summaryrefslogtreecommitdiff
path: root/systems/tex-extensions
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /systems/tex-extensions
Initial commit
Diffstat (limited to 'systems/tex-extensions')
-rw-r--r--systems/tex-extensions/clasen/INSTALL59
-rw-r--r--systems/tex-extensions/clasen/README103
-rw-r--r--systems/tex-extensions/clasen/etex.bib47
-rw-r--r--systems/tex-extensions/clasen/examples/example1/example1.dvibin0 -> 316 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example1/example1.log171
-rw-r--r--systems/tex-extensions/clasen/examples/example1/example1.ps141
-rw-r--r--systems/tex-extensions/clasen/examples/example1/example1.tex57
-rw-r--r--systems/tex-extensions/clasen/examples/example2/example2.dvibin0 -> 3184 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example2/example2.log40
-rw-r--r--systems/tex-extensions/clasen/examples/example2/example2.ps220
-rw-r--r--systems/tex-extensions/clasen/examples/example2/example2.tex72
-rw-r--r--systems/tex-extensions/clasen/examples/example3/example3.dvibin0 -> 4828 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example3/example3.log66
-rw-r--r--systems/tex-extensions/clasen/examples/example3/example3.ps652
-rw-r--r--systems/tex-extensions/clasen/examples/example3/example3.tex148
-rw-r--r--systems/tex-extensions/clasen/examples/example3/tf.mf322
-rw-r--r--systems/tex-extensions/clasen/examples/example3/tf10.mf83
-rw-r--r--systems/tex-extensions/clasen/examples/example3/tf5.mf83
-rw-r--r--systems/tex-extensions/clasen/examples/example3/tf7.mf83
-rw-r--r--systems/tex-extensions/clasen/examples/example4/Adiff1.gifbin0 -> 2615 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example4/Idiff1.gifbin0 -> 1797 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example4/Tdiff1.gifbin0 -> 2338 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example4/example4.dvibin0 -> 8348 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example4/example4.log332
-rw-r--r--systems/tex-extensions/clasen/examples/example4/example4.ps1026
-rw-r--r--systems/tex-extensions/clasen/examples/example4/example4.tex128
-rw-r--r--systems/tex-extensions/clasen/examples/example4/gdiff1.gifbin0 -> 2390 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz.mf7
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz1cmr10.mf79
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz2cmr10.mf78
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz3cmr10.mf78
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz4cmr10.mf78
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz5cmr10.mf78
-rw-r--r--systems/tex-extensions/clasen/examples/example4/hz6cmr10.mf78
-rw-r--r--systems/tex-extensions/clasen/examples/example4/ocmr10.mf10
-rw-r--r--systems/tex-extensions/clasen/examples/example4/ocomlig.mf59
-rw-r--r--systems/tex-extensions/clasen/examples/example4/oroman.mf81
-rw-r--r--systems/tex-extensions/clasen/examples/example5/example5.dvibin0 -> 4264 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example5/example5.log68
-rw-r--r--systems/tex-extensions/clasen/examples/example5/example5.ps446
-rw-r--r--systems/tex-extensions/clasen/examples/example5/example5.tex61
-rw-r--r--systems/tex-extensions/clasen/examples/example5/ocmr10.mf15
-rw-r--r--systems/tex-extensions/clasen/examples/example5/ocomlig.mf62
-rw-r--r--systems/tex-extensions/clasen/examples/example5/oligs.mf6
-rw-r--r--systems/tex-extensions/clasen/examples/example5/oroman.mf71
-rw-r--r--systems/tex-extensions/clasen/examples/example6/README15
-rw-r--r--systems/tex-extensions/clasen/examples/example6/example6.dvibin0 -> 4760 bytes
-rw-r--r--systems/tex-extensions/clasen/examples/example6/example6.log235
-rw-r--r--systems/tex-extensions/clasen/examples/example6/example6.ps856
-rw-r--r--systems/tex-extensions/clasen/examples/example6/example6.tex68
-rwxr-xr-xsystems/tex-extensions/clasen/examples/example6/mktexmf133
-rwxr-xr-xsystems/tex-extensions/clasen/examples/example6/mktexpk208
-rwxr-xr-xsystems/tex-extensions/clasen/examples/example6/mktextfm124
-rw-r--r--systems/tex-extensions/clasen/examples/example6/stretch.mf18
-rw-r--r--systems/tex-extensions/clasen/examples/example6/stretch.sty59
-rw-r--r--systems/tex-extensions/clasen/examples/example6/t1stretch.mf262
l---------systems/tex-extensions/clasen/glue/etex.bib1
-rw-r--r--systems/tex-extensions/clasen/glue/glue-post-web2c.ch40
-rw-r--r--systems/tex-extensions/clasen/glue/glue.ch677
-rw-r--r--systems/tex-extensions/clasen/glue/glue.tex75
-rw-r--r--systems/tex-extensions/clasen/glue/glueratio.patch15
-rw-r--r--systems/tex-extensions/clasen/hyphenation/classes.ch679
-rw-r--r--systems/tex-extensions/clasen/hyphenation/count.ch240
l---------systems/tex-extensions/clasen/hyphenation/etex.bib1
-rw-r--r--systems/tex-extensions/clasen/hyphenation/hyphenation.ch883
-rw-r--r--systems/tex-extensions/clasen/hyphenation/hyphenation.tex249
-rw-r--r--systems/tex-extensions/clasen/hyphenation/patgen-hyf.ch460
l---------systems/tex-extensions/clasen/hz/etex.bib1
-rw-r--r--systems/tex-extensions/clasen/hz/hz-glue.ch26
-rw-r--r--systems/tex-extensions/clasen/hz/hz-post-web2c.ch76
-rw-r--r--systems/tex-extensions/clasen/hz/hz.ch465
-rw-r--r--systems/tex-extensions/clasen/hz/hz.tex104
l---------systems/tex-extensions/clasen/margin/etex.bib1
-rw-r--r--systems/tex-extensions/clasen/margin/margin-post-web2c.ch45
-rw-r--r--systems/tex-extensions/clasen/margin/margin.ch341
-rw-r--r--systems/tex-extensions/clasen/margin/margin.tex97
-rw-r--r--systems/tex-extensions/clasen/math/accent.ch251
-rw-r--r--systems/tex-extensions/clasen/math/cramp.ch48
-rw-r--r--systems/tex-extensions/clasen/math/fraction.ch355
-rw-r--r--systems/tex-extensions/clasen/math/math.ch683
-rw-r--r--systems/tex-extensions/clasen/math/math.tex130
-rw-r--r--systems/tex-extensions/clasen/math/radical.ch99
-rw-r--r--systems/tex-extensions/clasen/post-web2c.ch4
-rw-r--r--systems/tex-extensions/clasen/pre-web2c.ch9
-rw-r--r--systems/tex-extensions/clasen/pre.ch41
-rw-r--r--systems/tex-extensions/clasen/tight2.patch1461
-rw-r--r--systems/tex-extensions/clasen/vftovp.patch119
87 files changed, 14842 insertions, 0 deletions
diff --git a/systems/tex-extensions/clasen/INSTALL b/systems/tex-extensions/clasen/INSTALL
new file mode 100644
index 0000000000..359c5079c1
--- /dev/null
+++ b/systems/tex-extensions/clasen/INSTALL
@@ -0,0 +1,59 @@
+Last updated: Sun Aug 9 18:02:12 CEST 1998
+
+A) Create the binary
+
+A1) Put all change and patch files in the web2c directory (or substitute
+ the full path to them in the tie commands in steps 3 and 4).
+
+A2) Move the web2c change file somewhere else:
+
+ mv tex.ch web2c.ch
+
+A3) Create a new change file:
+
+ tie -c tmp.ch tex.web pre.ch hyphenation.ch math.ch glue.ch \
+ hz.ch hz-glue.ch margin.ch pre-web2c.ch
+ tie -c tex.ch tex.web tmp.ch web2c.ch post-web2c.ch \
+ glue-post-web2c.ch hz-post-web2c.ch \
+ margin-post-web2c.ch
+ rm tmp.ch
+
+A4) Apply the patch to texmfmp.h:
+
+ patch <glueratio.patch
+
+A5) Create the binary. Note that for me, -O2 breaks
+ the math changes, therefore I had to compile with -O.
+
+ export XCFLAGS=-DHAVE_GLUERATIO_TYPE
+ make tex
+
+B) Create the environment for experiments. You should *not*
+ do `make install' for this binary since it is strictly
+ experimental.
+
+B1) Put the example files in a new directory and cd to it.
+
+B1) Create a shortcut to the new binary (substitute your path here)
+ and make it find its pool:
+
+ export TEXPOOL=/usr/src/teTeX-0.9/texk/web2c
+ TEX=$TEXPOOL/tex
+
+B2) Make $TEX and mf find the example fonts:
+
+ export MFINPUTS=.:
+ export TFMFONTS=.:
+ export GFFONTS=.:
+ export PKFONTS=.:
+
+B4) Create a latex format:
+
+ $TEX -ini latex.ltx
+
+B5) Now you can process the example files:
+
+ $TEX -ini example1
+ for i in 2 3 4 5; do $TEX \&./latex example${i}; done
+
+If all goes well, this should also create the needed example fonts.
diff --git a/systems/tex-extensions/clasen/README b/systems/tex-extensions/clasen/README
new file mode 100644
index 0000000000..9048148e4c
--- /dev/null
+++ b/systems/tex-extensions/clasen/README
@@ -0,0 +1,103 @@
+Last updated: Fri Feb 7 11:00:13 CET 2003
+
+
+This directory contains some proposals for extensions to TeX
+which I have implemented in a series of change files. These
+have only been tested with web2c 7.2 as contained on the
+TeX live III CD.
+
+glue/glue.ch and glue/glue-post-web2c.ch:
+ Adapt Knuth's glue.web to replace all cases of floating-point
+ arithmetic in TeX by fixed-point counterparts. To make this
+ change file work, you must also apply the patch glue/glueratio.patch
+ and compile with XCFLAGS=-DHAVE_GLUERATIO_TYPE.
+
+hyphenation/classes.ch:
+ Implements hyphen classes. There is a corresponding change file
+ patgen-hyf.ch which enables patgen to produce patterns for multiple
+ hyphen classes.
+
+hyphenation/count.ch:
+ Implements demerits for more than 2 consecutive hyphens.
+
+ (The changes in classes.ch and count.ch are described in more detail
+ in hyphenation/hyphenation.tex. There is a combined change file
+ hyphenation/hyphenation.ch.)
+
+math/accent.ch:
+ Implements nestable and under math accents.
+
+math/cramp.ch:
+ Implements primitives to switch to cramped styles.
+
+math/radical.ch:
+ Implements generalized radicals with a left and right delimiter.
+
+math/fraction.ch:
+ Implements \mathstyle and \fraction.
+
+ (There is a combined change file math/math.ch.)
+
+hz/hz.ch and hz/hz-post-web2c.ch:
+ Implement the hz-algorithm, ie using variants of a font to achieve
+ better justification.
+
+hz/hz-glue.ch;
+ Removes the floating-point operations reintroduced by hz.ch.
+ This can only be used in conjunction with glue.ch.
+
+margin/margin.ch and margin/margin-post-web2c.ch:
+ Implement \marginchar for hanging punctuation and hyphenation and
+ optical margin correction. This can currently only be used *after*
+ hz.ch.
+
+These change files can all be used together with the three change files
+in this directory in the following order (assuming web2c.ch is the
+tex.ch change file coming with web2c):
+
+pre.ch classes.ch count.ch accent.ch cramp.ch radical.ch fraction.ch
+glue.ch hz.ch hz-glue.ch margin.ch pre-web2c.ch web2c.ch post-web2c.ch
+glue-post-web2c.ch hz-post-web2c.ch margin-post-web2c.ch
+
+Since this list is rather long, you will need more than one
+run of tie/webmerge to create a single change file. Alternatively,
+it should be possible to use only a subset of the above list.
+
+There are also some example files. All example files are
+present with tex, dvi and log files. To avoid messing with the
+fonts, you can also use the ps versions (generated with
+dvips -D600 -mode ljfive).
+
+examples/example1/*:
+ Multiple hyphen classes. This file must be processed
+ with initex, since it uses \patterns. For this example, the
+ log file is more interesting than the dvi file.
+
+examples/example2/*:
+ Demerits for more than 2 consecutive hyphens. LaTeX file.
+
+examples/example3/*:
+ The various math features. This LaTeX file uses the fonts
+ tf5, tf7, and tf10 whose source can be found in the same
+ directory.
+
+examples/example4/*:
+ The hz-algorithm. This LaTeX file uses the fonts
+ hz1cmr10,...,hz6cmr10 whose source can be found in the same
+ directory.
+ There are also some gifs which compare glyphs at different
+ extension factors.
+
+examples/example5/*:
+ Hanging punctuation/hyphenation. The LaTeX file uses the font
+ ocmr10, whose source can be found in the same directory.
+
+examples/example6/*:
+ Another example showing the hz-Algorithm. This time demonstrating
+ a prototype for a LaTeX-interface integrated with NFSS.
+
+I'd be glad to hear comments on the ideas and their implementation!
+
+
+
+Matthias Clasen maclas@gmx.de
diff --git a/systems/tex-extensions/clasen/etex.bib b/systems/tex-extensions/clasen/etex.bib
new file mode 100644
index 0000000000..2a3dd36b0d
--- /dev/null
+++ b/systems/tex-extensions/clasen/etex.bib
@@ -0,0 +1,47 @@
+@InProceedings{MR:92,
+ author = {Frank Mittelbach and Chris Rowley},
+ title = {The pursuit of quality---How can automated typesetting achieve the highest standards of craft typography?},
+ booktitle = {Proceedings of the International Conference on Electronic Publishing, Document Manipulation \& Typography},
+ editor = {C. Vanoirbeek and G. Coray},
+ year = 1992,
+ publisher = {Cambridge University Press},
+ address = {New York},
+ pages = {261-273}
+}
+
+@Article{Mittelbach:90,
+ author = {Frank Mittelbach},
+ title = {{E-\TeX}: Guidelines for future {\TeX{}} extensions},
+ journal = {{TUGboat}},
+ year = 1990,
+ volume = 11,
+ number = 3,
+ pages = {337-345}
+}
+
+@TechReport{Knuth:91,
+ author = {Donald E. Knuth},
+ title = {Fixed-point glue setting},
+ institution = {\url{CTAN:/systems/knuth/glue.web}},
+ year = 1991
+}
+
+@Article{Knuth:82,
+ author = {Donald E. Knuth},
+ title = {Fixed-point arithmetic for {\TeX{}}},
+ journal = {\TUB},
+ year = {1982},
+ OPTvolume = {1},
+ OPTnumber = {3},
+ OPTpages = {10--27},
+ OPTmonth = {March},
+}
+
+@Book{Knuth:86,
+ ALTauthor = {Donald E. Knuth},
+ title = {The {\TeX{}}book},
+ publisher = {Addison-Wesley},
+ year = 1986,
+ OPTnumber = {A},
+ OPTseries = {Computers \& Typesetting},
+}
diff --git a/systems/tex-extensions/clasen/examples/example1/example1.dvi b/systems/tex-extensions/clasen/examples/example1/example1.dvi
new file mode 100644
index 0000000000..1f2dfb2781
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example1/example1.dvi
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example1/example1.log b/systems/tex-extensions/clasen/examples/example1/example1.log
new file mode 100644
index 0000000000..049e9316bf
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example1/example1.log
@@ -0,0 +1,171 @@
+This is TeX, Version 3.14159 (with experimental extensions) (Web2C 7.2) (INITEX) 23 JUL 1998 19:14
+**example1.tex
+(example1.tex
+Underfull \hbox (badness 10000) in paragraph at lines 33--33
+[] \tenrm aa-aa bb-2bb cc-3cc abra-2kad-a-5bra client-0server bart-wal bimm-ba
+mm schiff-6fahrt
+
+\hbox(6.94444+0.0)x16383.99998, glue set 1070.8125 []
+
+@firstpass
+@secondpass
+[]\tenrm aaaaa
+@ via @@0 b=* p=0 d=*
+@@1: line 1.3 t=0 -> @@0
+bb-2
+@\discretionary via @@1 b=* p=800 d=*
+@@2: line 2.3-(1) t=0 -> @@1
+b-2
+@\discretionary via @@2 b=10000 p=800 d=100640000
+@@3: line 3.0-(2) t=100640000 -> @@2
+bb
+@ via @@3 b=10000 p=0 d=100000000
+@@4: line 4.0 t=200640000 -> @@3
+cc-3
+@\discretionary via @@4 b=10000 p=700 d=100490000
+@@5: line 5.0-(1) t=301130000 -> @@4
+c-3
+@\discretionary via @@5 b=10000 p=700 d=100490000
+@@6: line 6.0-(2) t=401620000 -> @@5
+cc
+@ via @@5 b=10000 p=0 d=100000000
+@ via @@6 b=10000 p=0 d=100000000
+@@7: line 6.0 t=401130000 -> @@5
+abra-2
+@\discretionary via @@7 b=* p=800 d=*
+@@8: line 7.3-(1) t=401130000 -> @@7
+kad-
+@\discretionary via @@8 b=* p=900 d=*
+@@9: line 8.3-(2) t=401130000 -> @@8
+a-5
+@\discretionary via @@9 b=10000 p=500 d=100250000
+@@10: line 9.0-(3) t=501380000 -> @@9
+bra
+@ via @@10 b=* p=0 d=*
+@@11: line 10.3 t=501380000 -> @@10
+client-0server
+@ via @@11 b=* p=0 d=*
+@@12: line 11.3 t=501380000 -> @@11
+bart-
+@\discretionary via @@12 b=* p=900 d=*
+@@13: line 12.3-(1) t=501380000 -> @@12
+wal
+@ via @@13 b=* p=0 d=*
+@@14: line 13.3 t=501380000 -> @@13
+bimm-
+@\discretionary via @@14 b=* p=900 d=*
+@@15: line 14.3-(1) t=501380000 -> @@14
+bamm
+@ via @@15 b=* p=0 d=*
+@@16: line 15.3 t=501380000 -> @@15
+schiff-3f
+@\discretionary via @@16 b=* p=700 d=*
+@@17: line 16.3-(1) t=501380000 -> @@16
+ahrt
+@\par via @@17 b=* p=-10000 d=*
+@@18: line 17.3-(2) t=501380000 -> @@17
+
+
+Overfull \hbox (10.77371pt too wide) in paragraph at lines 50--56
+[]\tenrm aaaaa
+
+\hbox(4.30554+0.0)x14.22636 []
+
+
+Overfull \hbox (0.21811pt too wide) in paragraph at lines 50--56
+\tenrm bb-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 50--56
+\tenrm b-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 50--56
+\tenrm bb
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 50--56
+\tenrm cc-
+
+\hbox(4.30554+0.0)x14.22636 []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 50--56
+\tenrm c-3cc
+
+\hbox(4.30554+0.0)x14.22636 []
+
+
+Overfull \hbox (8.57924pt too wide) in paragraph at lines 50--56
+\tenrm abra-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (4.3848pt too wide) in paragraph at lines 50--56
+\tenrm kad-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 50--56
+\tenrm a-
+
+\hbox(4.30554+0.0)x14.22636 []
+
+
+Overfull \hbox (0.2459pt too wide) in paragraph at lines 50--56
+\tenrm bra
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (38.3848pt too wide) in paragraph at lines 50--56
+\tenrm client-0server
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (7.46812pt too wide) in paragraph at lines 50--56
+\tenrm bart-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (0.49588pt too wide) in paragraph at lines 50--56
+\tenrm wal
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (14.10704pt too wide) in paragraph at lines 50--56
+\tenrm bimm-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (12.99594pt too wide) in paragraph at lines 50--56
+\tenrm bamm
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (11.38478pt too wide) in paragraph at lines 50--56
+\tenrm schiff-
+
+\hbox(6.94444+0.0)x14.22636 []
+
+
+Overfull \hbox (7.19037pt too wide) in paragraph at lines 50--56
+\tenrm fahrt
+
+\hbox(6.94444+0.0)x14.22636 []
+
+[0] )
+Output written on example1.dvi (1 page, 316 bytes).
diff --git a/systems/tex-extensions/clasen/examples/example1/example1.ps b/systems/tex-extensions/clasen/examples/example1/example1.ps
new file mode 100644
index 0000000000..fa0cc14dd5
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example1/example1.ps
@@ -0,0 +1,141 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.76a Copyright 1997 Radical Eye Software (www.radicaleye.com)
+%%Title: example1.dvi
+%%Pages: 1
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSCommandLine: dvips -a -D600 -mode ljfive example1.dvi -o
+%+ example1.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource: TeX output 1998.07.23:1914
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N
+/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id
+gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp
+add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add
+/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{
+dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1
+adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2
+idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string
+putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval
+adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg}
+{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{
+adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2
+chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{]
+}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{dup length product length le{dup length product
+exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}
+ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}
+imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false
+RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round
+exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto
+rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup
+/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{
+-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}
+B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B
+/bos{/SS save N}B /eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (example1.dvi)
+@start
+%DVIPSBitmapFont: Fa cmr10 10 19
+/Fa 19 120 df<DA07FC13FC91393FFF07FF49B5009F1380903B03FC07FF8FC0903B0FE0
+03FE0FE0903A1FC007FC1F90383F800FD97F0013F8017EED0FC001FE903907F007804992
+C7FC1201ACB812F8A32801FC0007F0C7FCB3AB486C497E267FFFE0B512F0A3333B7FBA30
+>11 D<B512FCA616067F941C>45 D<EB3FE0EBFFFC000313FF3907C03F80390F800FC048
+6C6C7E01E07F6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7FF13801FF01EA07
+F8EA0FF0EA1FE0EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC01C7E383A
+1FF0787FF83A0FFFF03FF0000301E013E03A007F000F8026277DA52A>97
+D<EA03F812FFA3120F1203B0EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC090
+39FE0007E049EB03F0A249EB01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F8
+6D14F0ED07E06DEB0FC09039E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0
+283B7EB92E>I<EB03FC90381FFF80017F13E09038FE01F03901F800F83903F001FC3807
+E003EA0FC0121F90388001F8003FEB00F01560007F140090C8FCA25AA97EA27FA2003F14
+0E7F001F141C6C7E000714386C7ED801FC13F03900FF03E090387FFFC0011F1300EB07F8
+1F277DA525>I<ED1FC0EC07FFA3EC007F151FB0EB07F8EB1FFE90387FFF9F9038FE07DF
+3901F800FF4848137F4848133F4848131F121F485AA2127F90C7FCA35AA97EA27F123FA2
+121F6C6C133F157F6C6C13FF3A03F001DFF03A01FC079FFF39007FFF1FEB3FFED907F013
+C0283B7DB92E>I<EB07F8EB1FFF017F13809038FC0FC03901F003E03903E001F0000714
+F8390FC000FC121F4913FE003F147EA248C7127FA35A90B6FCA390C8FCA57EA27F123F15
+076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F090383FFFC06D1380903803
+FC0020277EA525>I<147E903803FF80010F13C090381FC7E090383F07F0EB7E0F13FE13
+FC0001EB07E09038F803C0000390C7FCADB512FCA3D803F8C7FCB3AB487EB512F8A31C3B
+7FBA19>I<EA03F812FFA3120F1203B0EC07F0EC1FFCEC7FFF9138F07F809038F9C01FD9
+FB807F9038FF000F49805BA35BB3A4486C497EB500E1B51280A3293A7EB92E>104
+D<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512
+E0A313387EB718>I<EA03F812FFA3120F1203B1913803FFFCA36E13C0913800FE005D15
+F04A5A4A5A4A5A4AC7FC141E5C5C14FCEBF9FE13FBEBFF7F496C7EEBFC1F01F87F6E7E6E
+7EA26E7E6E7EA26E7E157FA2ED3F8016C0486CEB7FF0B500E1B5FCA3283A7EB92C>107
+D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<2703F807F8EB0FF000
+FFD91FFEEB3FFCDA7FFFEBFFFE913AF03F81E07F3D0FF9C00FC3801F802603FB80D9E700
+7F020013E601FED907FC6D7EA2495CA2495CB3A4486C496C497EB500E1B500C3B51280A3
+41257EA446>I<3903F807F000FFEB1FFCEC7FFF9138F07F80390FF9C01F2603FB807F90
+38FF000F49805BA35BB3A4486C497EB500E1B51280A329257EA42E>I<3803F03F00FFEB
+7F809038F1FFE014C7390FF38FF03803F70F13F69038FE07E09038FC03C0EC018091C7FC
+A25BB3A3487EB512F8A31C257EA421>114 D<EBFF83000313E7000F13FFEA1F80383E00
+3F487F00787FA200F87FA37E6C90C7FC6C7EEA7FF8EBFF806C13E06C13F86C7F6C7F0001
+7F6C7E01031380EB003F0060EB1FC000E0130FA26C1307A37E15806C130F1500B4131EEB
+C07C38F3FFF800E15B38C07F801A277DA521>I<131CA5133CA3137CA213FC1201120312
+07121FB6FCA3D801FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB03F0
+1A347FB220>I<B538C07FFEA33A0FFC001FF0D803F8EB07C016807F00011500A26D5B00
+00140EA2017F5BA2EC803C013F1338A26D6C5AA214E0010F5BA214F101075BA2903803FB
+80A214FF6D90C7FCA36D5AA2147CA3143827257EA32C>118 D<B53A8FFFF07FFEA3260F
+F8009038800FF8000791397F0007E0EF03C000031780816DEC80070001027F1400A26D6E
+5A000002FF130E15EF6DECE01ED97F01141C15C70281EBF03CD93F8314381583D91FC36D
+5AECC701A2D90FE76D5AECEE00A2D907FEEBFFC04A137FA201035D4A133FA2010192C7FC
+4A7FA20100141E4A130E37257EA33C>I E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 0 1
+0 0 bop 0 36 a Fa(aaaaa)0 93 y(bb-)0 151 y(b-)0 209 y(bb)0
+244 y(cc-)0 280 y(ccc)0 338 y(abra-)0 396 y(k)-5 b(ad-)0
+431 y(a-)0 489 y(bra)0 547 y(clien)n(t-serv)n(er)0 604
+y(bart-)0 662 y(w)n(al)0 720 y(bimm-)0 777 y(bamm)0 835
+y(sc)n(hi\013-)0 892 y(fahrt)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/systems/tex-extensions/clasen/examples/example1/example1.tex b/systems/tex-extensions/clasen/examples/example1/example1.tex
new file mode 100644
index 0000000000..331d19858f
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example1/example1.tex
@@ -0,0 +1,57 @@
+%
+% This file must be processed with initex, since it uses \patterns.
+%
+\catcode`\{=1 % left brace is begin-group character
+\catcode`\}=2 % right brace is end-group character
+\catcode`\$=3 % dollar sign is math shift
+\catcode`\&=4 % ampersand is alignment tab
+\catcode`\#=6 % hash mark is macro parameter character
+\catcode`\^=7 \catcode`\^^K=7 % circumflex and uparrow are for superscripts
+\catcode`\_=8 \catcode`\^^A=8 % underline and downarrow are for subscripts
+\catcode`\^^I=10 % ascii tab is a blank space
+\chardef\active=13 \catcode`\~=\active % tilde is active
+\catcode`\^^L=\active \outer\def^^L{\par} % ascii form-feed is "\outer\par"
+\defaulthyphenchar=`\-
+\font\tenrm=cmr10
+
+\hyphenclassesstate=1
+\lefthyphenmin=2 \righthyphenmin=2
+\hyphenclasses=4 \exhyphenclass=0
+
+\patterns{a1a b10b c63c}
+\hyphenation{abra-2kad-a-5bra}
+\def\showhyphens#1{\setbox0=\vbox{\parfillskip0pt \hsize16383.99999pt \tenrm
+ \pretolerance=-1 \tolerance=-1 \hbadness=0 \showboxdepth=0 \ #1}}
+
+\showhyphens{
+aaaa bbbb cccc
+abrakadabra
+client-server
+bart\discretionary{-}{}{}wal
+bimm\-bamm
+schi\gendiscretionary6{ff-}{f}{ff}ahrt
+}
+
+\hyphenpenalties1=900
+\hyphenpenalties2=800
+\hyphenpenalties3=700
+\hyphenpenalties4=600
+\hyphenpenalties5=500
+\hyphenpenalties6=400
+\hyphenpenalties7=300
+\hyphenpenalties8=100
+\hyphenpenalties9=0
+
+\hsize=0.5cm
+\vsize=30cm
+\tenrm
+\tracingparagraphs=1
+
+aaaaa bbbbb ccccc
+abrakadabra
+client-server
+bart\discretionary{-}{}{}wal
+bimm\-bamm
+schi\gendiscretionary3{ff-}{f}{ff}ahrt
+
+\end
diff --git a/systems/tex-extensions/clasen/examples/example2/example2.dvi b/systems/tex-extensions/clasen/examples/example2/example2.dvi
new file mode 100644
index 0000000000..17e67a1268
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example2/example2.dvi
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example2/example2.log b/systems/tex-extensions/clasen/examples/example2/example2.log
new file mode 100644
index 0000000000..db755f264f
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example2/example2.log
@@ -0,0 +1,40 @@
+This is TeX, Version 3.14159 (with experimental extensions) (Web2C 7.2) (format=latex 1998.7.23) 23 JUL 1998 19:20
+**&latex example2
+(example2.tex
+LaTeX2e <1997/12/01> patch level 1
+Babel <v3.6h> and hyphenation patterns for american, german, loaded.
+(/usr/local/share/texmf/tex/latex/base/minimal.cls
+Document Class: minimal 1996/05/20 Standard LaTeX minimal class
+) (/usr/local/share/texmf/tex/generic/misc/german.sty
+Package `german', Version 2.5d of 97/05/01.
+Package: german 1997/05/01 v2.5d Support for writing german texts (br)
+\grmnU@D=\dimen102
+german -- \language number for Austrian undefined, default 1 used.
+german -- \language number for French undefined, default 255 used.
+)
+No file example2.aux.
+\openout1 = `example2.aux'.
+
+LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 17.
+LaTeX Font Info: ... okay on input line 17.
+LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 17.
+LaTeX Font Info: ... okay on input line 17.
+LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 17.
+LaTeX Font Info: ... okay on input line 17.
+LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 17.
+LaTeX Font Info: ... okay on input line 17.
+LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 17.
+LaTeX Font Info: ... okay on input line 17.
+LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 17.
+LaTeX Font Info: ... okay on input line 17.
+[1] [2] (example2.aux) )
+Here is how much of TeX's memory you used:
+ 205 strings out of 10889
+ 2248 string characters out of 147219
+ 49288 words of memory out of 263001
+ 3203 multiletter control sequences out of 10000+0
+ 3808 words of font info for 15 fonts, out of 200000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 15i,4n,10p,125b,149s stack positions out of 300i,100n,500p,30000b,4000s
+
+Output written on example2.dvi (2 pages, 3184 bytes).
diff --git a/systems/tex-extensions/clasen/examples/example2/example2.ps b/systems/tex-extensions/clasen/examples/example2/example2.ps
new file mode 100644
index 0000000000..1925446d48
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example2/example2.ps
@@ -0,0 +1,220 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.76a Copyright 1997 Radical Eye Software (www.radicaleye.com)
+%%Title: example2.dvi
+%%Pages: 2
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSCommandLine: dvips -a -D600 -mode ljfive example2.dvi -o
+%+ example2.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource: TeX output 1998.07.23:1920
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N
+/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id
+gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp
+add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add
+/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{
+dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1
+adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2
+idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string
+putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval
+adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg}
+{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{
+adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2
+chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{]
+}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{dup length product length le{dup length product
+exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}
+ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}
+imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false
+RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round
+exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto
+rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup
+/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{
+-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}
+B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B
+/bos{/SS save N}B /eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (example2.dvi)
+@start
+%DVIPSBitmapFont: Fa cmr10 10 4
+/Fa 4 109 df<B512FCA616067F941C>45 D<EB3FE0EBFFFC000313FF3907C03F80390F
+800FC0486C6C7E01E07F6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7FF13801
+FF01EA07F8EA0FF0EA1FE0EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC0
+1C7E383A1FF0787FF83A0FFFF03FF0000301E013E03A007F000F8026277DA52A>97
+D<EA03F812FFA3120F1203B0EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC090
+39FE0007E049EB03F0A249EB01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F8
+6D14F0ED07E06DEB0FC09039E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0
+283B7EB92E>I<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>108
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fb cmtt10 10 21
+/Fb 21 122 df<EB01FC90380FFF80497F017F13F090B57E488048EB07FEEBFC0148486C
+7E4848EB7F8049133F4848EB1FC0A24848EB0FE0A348C7EA07F0A400FEEC03F8AC6C1407
+6C15F0A36D130F003F15E0A26D131F001F15C06D133F000F15806D137F6C6CEBFF006C6C
+485AEBFF076CEBFFFC6C5C6D5B011F13C06D5BD901FCC7FC25357DB32C>48
+D<EB0380497E130FA2131FA2133F137F13FF1203127FB5FCA213DF139FEA7E1F1200B3AC
+003FB512E04814F0B612F8A26C14F06C14E01D3478B32C>I<007FB612F0A2B712F8A26C
+15F06C15E0CAFCA8003FB612E04815F0B712F8A26C15F0A225147DA22C>61
+D<1278A212FCA27E127E127F7E7F121F7F120F7F1207A27F12037F12017F12007F137E13
+7F7F80131FA280130F801307801303801301801300A280147E147F8081141F81140F8114
+07811403A281140181140081157E157F811680151FA2ED0F008121417BB92C>92
+D<3801FFF0000713FE486D7E48804880819038C01FF8391F8007FC380F0001000680C8FC
+A2140FEB07FF137F48B5FC12075A4813F8383FFC00EA7FE0EAFF8090C7FC5AA36C1301A2
+387F8007383FE03F90B612FC6C15FE7E6C143F0001EBFC1F3A007FC00FFC27247CA32C>
+97 D<903803FFF0011F13FC017F7F90B6FC4815805A48EB007FD80FF8EB3F00D81FE013
+1E4848130C4990C7FC127F90C9FCA25A5AA67E7EA26DEB0F806C6CEB1FC07F6C6C133FD8
+0FFCEB7F803907FF81FF6C90B512006C5C6C5C6D5B011F13E0010390C7FC22247BA32C>
+99 D<EC07FF4A13805CA28080EC003FA9EB0FF8EB3FFE90B512BF4814FF5A5A380FFC0F
+381FF00349C6FC4848137F485A153F90C7FC5A5AA87E6C147FA26D13FF6C7E5C381FF007
+380FFC1F6CB612FC6C15FE6CECBFFF6C143FD97FFC13FE90390FF01FFC28337DB22C>I<
+EB03FE90381FFFC0017F13F090B57E488048803907FE03FF260FF8001380D81FE0137F48
+48EB3FC049131F127F90C713E0150FB7FCA516C048C9FC7E7E7FED07C06C6CEB0FE07F6C
+6C131FD80FFCEB3FC03907FF80FF6C90B512806C15006C5C013F13F8010F5B0101138023
+247CA32C>I<EC07F8EC3FFCECFFFE497F4914805B90380FF87F9138E03F00011F131E4A
+C7FCA6003FB512FE4880B7FCA36C5C26001FC0C7FCB3A6007FB512F0B67EA46C5C21337D
+B22C>I<EA3FF8487E12FFA2127F123F1201A9EC07F8EC3FFE91B5FC01FD8090B67E82EC
+F81F9138C00FF0EC800714005BA35BB13B3FFFE03FFF80486D4813C0B56CB512E0A26C49
+6C13C06C496C13802B3380B22C>104 D<EB0380497E497E497EA36D5A6D5A6D5A90C8FC
+A7383FFFE0487FB5FCA27E7EEA0007B3A6007FB512FCB612FE15FFA215FE6C14FC20347A
+B32C>I<3A3FC1F803F03A7FE7FC0FF8B538FE3FFC6E487E6C91B5FC7E3B07FE1FFC3F80
+01FC13F89039F80FF01F01F013E0A301E013C0B2D83FFC01F813F03B7FFE1FFC3FF8B539
+3FFE7FFCA23B7FFE1FFC3FF83B3FFC0FF81FF02E2481A32C>109
+D<393FF807F8397FFC3FFE00FF90B5FC01FD806CB67E6C810001EBF81F9138C00FF0EC80
+0714005BA35BB13B3FFFE03FFF80486D4813C0B56CB512E0A26C496C13C06C496C13802B
+2480A32C>I<EB07FCEB1FFF017F13C048B512F048804880390FFC07FE391FF001FF497E
+4848EB7F8049133F48C7EA1FC0A300FEEC0FE0A76C141F6C15C0A26D133F003F15806D13
+7F6C6CEBFF00EBF803390FFE0FFE6CB55A6C5C6C5C6C6C13C0011F90C7FCEB07FC23247C
+A32C>I<393FF80FF0397FFC7FFED8FFFDB5FC90B612806C15C06C15E000019038F03FF0
+9138C00FF891380003FC5BED01FE491300A216FF167FA816FF6D14FE15017FED03FC9138
+8007F8ECC00F9138F03FF091B512E016C001FD148001FC1400EC7FFCEC0FF091C8FCAC38
+3FFFE0487FB57EA26C5B6C5B283680A32C>I<D83FFFEB3FC048903881FFE0B5008713F0
+028F13F86C019F13FC6C13BF39003FFFE3ED01F89138FC00F04A13604A1300A25CA25CA3
+5CAD003FB512F04880B6FCA27E6C5C26247EA32C>114 D<90383FF8700003B512F85A5A
+5A5A387FC01F38FF000700FC1303A36CEB01F06C6CC7FCEA7FFC383FFFF06C13FF6C14C0
+6C14E0C614F0010F13F89038007FFCEC03FE003CEB00FF007E143F12FE7EA26D137F6D13
+FEEBF00790B512FC15F815F015E000F8148039701FFC0020247AA32C>I<130F497E133F
+A8003FB6FC481580B7FCA36C150026003F80C7FCAFED0380ED07C0ED0FE0A3151F02C013
+C0011F133F9138F07F806DB5FC16006D5B6D13F801005BEC3FC0232E7EAD2C>I<D83FF8
+EBFFE0486C487F00FF5BA2007F7F003F7F00011407B3A2150FA2153F01FF13FF6C90B612
+8017C06D15E07F6D01E713C00103010313802B2480A32C>I<3A7FFF01FFFCB5008313FE
+14C7A214836C010113FC3A03F0001F806D133F00011500A26D5B0000147EA26D13FE017E
+5BA36D485AA31483011F5BA214C7010F5BA3903807EFC0A214FF6D5BA36D90C7FCA26D5A
+27247EA32C>I<3A3FFF01FFFC48018313FEB512C7A26C13836C010113FC3A03F8001F80
+0001143F6D140012005D6D137E137EA2017F5B7FA2EC81F8131FA2EB0FC1ECC3F0A2EB07
+E35D14E71303ECF7C0130114FF5D7FA292C7FC80A2147EA314FE5CA21301000C5BEA3F03
+387F87F0138F495AEBFFC0A26C5B6C48C8FC6C5AEA07F027367EA32C>121
+D E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 0 83 a Fb(\\hyphencountstat)o(e=0)0 211 y Fa(blabla)34
+b(blablabla)f(blabla)i(blabla)f(blabla)h(blabla)f(blabla)g
+(blablablabla)0 310 y(blablablabla)21 b(blablabla)i(blabla)h(blabla)f
+(blabla)h(blabla)g(blabla)g(blablab-)0 410 y(labla)18
+b(blablablabla)e(blablabla)h(blabla)h(blabla)g(blabla)g(blabla)h
+(blabla)f(bla-)0 509 y(blablabla)29 b(blablablabla)f(blablabla)h
+(blabla)i(blabla)f(blabla)g(blabla)h(bla-)0 609 y(bla)h(blablablabla)c
+(blablablabla)f(blablabla)j(blabla)g(blabla)g(blabla)h(bla-)0
+709 y(bla)h(blabla)e(blablablabla)e(blablablabla)g(blablabla)h(blabla)h
+(blabla)h(bla-)0 808 y(bla)h(blabla)e(blabla)h(blablablabla)c
+(blablablabla)h(blablabla)h(blabla)i(bla-)0 908 y(bla)20
+b(blabla)e(blabla)h(blabla)g(blablablabla)d(blablablabla)g(blablabla)h
+(blabla)0 1008 y(blabla)25 b(blabla)g(blabla)g(blabla)g(blablablabla)e
+(blablablabla)0 1214 y Fb(\\hyphencountstat)o(e=1)0 1314
+y(\\threehyphendeme)o(rit)o(s=)o(10)o(00)0 1414 y(\\fourhyphendemer)o
+(its)o(=1)o(00)o(00)0 1513 y(\\fivehyphendemer)o(its)o(=1)o(00)o(000)0
+1641 y Fa(blabla)34 b(blablabla)f(blabla)i(blabla)f(blabla)h(blabla)f
+(blabla)g(blablablabla)0 1740 y(blablablabla)21 b(blablabla)i(blabla)h
+(blabla)f(blabla)h(blabla)g(blabla)g(blablab-)0 1840
+y(labla)18 b(blablablabla)e(blablabla)h(blabla)h(blabla)g(blabla)g
+(blabla)h(blabla)f(bla-)0 1940 y(blablabla)29 b(blablablabla)f
+(blablabla)h(blabla)i(blabla)f(blabla)g(blabla)h(bla-)0
+2039 y(bla)h(blablablabla)c(blablablabla)f(blablabla)j(blabla)g(blabla)
+g(blabla)h(bla-)0 2139 y(bla)20 b(blabla)e(blablablabla)e(blablablabla)
+g(blablabla)i(blabla)g(blabla)h(blabla)0 2239 y(blabla)41
+b(blabla)f(blablablabla)e(blablablabla)g(blablabla)h(blabla)i(blabla)0
+2338 y(blabla)g(blabla)f(blabla)h(blablablabla)d(blablablabla)g
+(blablabla)h(blabla)0 2438 y(blabla)25 b(blabla)g(blabla)g(blabla)g
+(blablablabla)e(blablablabla)0 2645 y Fb(\\hyphencountstat)o(e=1)0
+2744 y(\\threehyphendeme)o(rit)o(s=)o(10)o(000)0 2844
+y(\\fourhyphendemer)o(its)o(=1)o(00)o(000)0 2943 y(\\fivehyphendemer)o
+(its)o(=1)o(00)o(000)o(0)0 3071 y Fa(blabla)34 b(blablabla)f(blabla)i
+(blabla)f(blabla)h(blabla)f(blabla)g(blablablabla)0 3171
+y(blablablabla)21 b(blablabla)i(blabla)h(blabla)f(blabla)h(blabla)g
+(blabla)g(blablab-)0 3270 y(labla)18 b(blablablabla)e(blablabla)h
+(blabla)h(blabla)g(blabla)g(blabla)h(blabla)f(bla-)0
+3370 y(blablabla)29 b(blablablabla)f(blablabla)h(blabla)i(blabla)f
+(blabla)g(blabla)h(bla-)0 3469 y(bla)20 b(blablablabla)c(blablablabla)g
+(blablabla)h(blabla)i(blabla)f(blabla)h(blabla)0 3569
+y(blabla)41 b(blablablabla)d(blablablabla)f(blablabla)j(blabla)g
+(blabla)h(blabla)0 3669 y(blabla)g(blabla)f(blablablabla)e
+(blablablabla)g(blablabla)h(blabla)i(blabla)0 3768 y(blabla)g(blabla)f
+(blabla)h(blablablabla)d(blablablabla)g(blablabla)h(blabla)0
+3868 y(blabla)25 b(blabla)g(blabla)g(blabla)g(blablablabla)e
+(blablablabla)0 4075 y Fb(\\hyphencountstat)o(e=1)0 4174
+y(\\threehyphendeme)o(rit)o(s=)o(10)o(000)o(0)0 4274
+y(\\fourhyphendemer)o(its)o(=1)o(00)o(000)o(0)0 4374
+y(\\fivehyphendemer)o(its)o(=1)o(00)o(000)o(00)0 4501
+y Fa(blabla)34 b(blablabla)f(blabla)i(blabla)f(blabla)h(blabla)f
+(blabla)g(blablablabla)0 4601 y(blablablabla)28 b(blablabla)h(blabla)h
+(blabla)h(blabla)f(blabla)h(blabla)f(blabla-)0 4700 y(blabla)k
+(blablablabla)e(blablabla)h(blabla)i(blabla)f(blabla)g(blabla)h(blabla)
+0 4800 y(blablablabla)j(blablablabla)g(blablabla)h(blabla)i(blabla)f
+(blabla)h(blabla)p eop
+%%Page: 2 2
+2 1 bop 0 83 a Fa(blabla)41 b(blablablabla)d(blablablabla)f(blablabla)j
+(blabla)g(blabla)h(blabla)0 183 y(blabla)g(blabla)f(blablablabla)e
+(blablablabla)g(blablabla)h(blabla)i(blabla)0 282 y(blabla)g(blabla)f
+(blabla)h(blablablabla)d(blablablabla)g(blablabla)h(blabla)0
+382 y(blabla)i(blabla)f(blabla)h(blabla)f(blablablabla)e(blablablabla)g
+(blablabla)0 482 y(blabla)25 b(blabla)g(blabla)g(blabla)g(blabla)g
+(blablablabla)e(blablablabla)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/systems/tex-extensions/clasen/examples/example2/example2.tex b/systems/tex-extensions/clasen/examples/example2/example2.tex
new file mode 100644
index 0000000000..1a58d2afdc
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example2/example2.tex
@@ -0,0 +1,72 @@
+\documentclass[a4paper]{minimal}
+\usepackage{german}
+\tolerance=2000
+\setlength{\textwidth}{10cm}
+\def\testpar{\noindent
+blabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+blablabla blabla blabla blabla blabla blabla blablablabla blablablabla
+}
+
+\begin{document}
+\begin{verbatim}
+\hyphencountstate=0
+\end{verbatim}
+
+\smallskip
+\testpar
+
+\bigskip
+\begin{verbatim}
+\hyphencountstate=1
+\threehyphendemerits=1000
+\fourhyphendemerits=10000
+\fivehyphendemerits=100000
+\end{verbatim}
+
+\smallskip
+\hyphencountstate=1
+\threehyphendemerits=1000
+\fourhyphendemerits=10000
+\fivehyphendemerits=100000
+\testpar
+
+\bigskip
+\begin{verbatim}
+\hyphencountstate=1
+\threehyphendemerits=10000
+\fourhyphendemerits=100000
+\fivehyphendemerits=1000000
+\end{verbatim}
+
+\smallskip
+\threehyphendemerits=10000
+\fourhyphendemerits=100000
+\fivehyphendemerits=1000000
+\testpar
+
+\bigskip
+\begin{verbatim}
+\hyphencountstate=1
+\threehyphendemerits=100000
+\fourhyphendemerits=1000000
+\fivehyphendemerits=10000000
+\end{verbatim}
+
+\smallskip
+\threehyphendemerits=100000
+\fourhyphendemerits=1000000
+\fivehyphendemerits=10000000
+\testpar
+
+\end{document}
+
+
+
+
diff --git a/systems/tex-extensions/clasen/examples/example3/example3.dvi b/systems/tex-extensions/clasen/examples/example3/example3.dvi
new file mode 100644
index 0000000000..08c7416545
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/example3.dvi
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example3/example3.log b/systems/tex-extensions/clasen/examples/example3/example3.log
new file mode 100644
index 0000000000..1001432304
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/example3.log
@@ -0,0 +1,66 @@
+This is TeX, Version 3.14159 (with experimental extensions) (Web2C 7.2) (format=latex 1998.7.23) 23 JUL 1998 19:38
+**&../latex example3
+(example3.tex
+LaTeX2e <1997/12/01> patch level 1
+Babel <v3.6h> and hyphenation patterns for american, german, loaded.
+(/usr/local/share/texmf/tex/latex/base/article.cls
+Document Class: article 1997/10/10 v1.3x Standard LaTeX document class
+(/usr/local/share/texmf/tex/latex/base/size10.clo
+File: size10.clo 1997/10/10 v1.3x Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+)
+(/usr/local/share/texmf/tex/latex/base/shortvrb.sty
+Package: shortvrb 1997/02/05 v1.9z Standard LaTeX documentation package (FMi)
+)
+Package shortvrb Info: Made | a short reference for \verb on input line 3.
+\symnewsym=\mathgroup4
+ (example3.aux)
+\openout1 = `example3.aux'.
+
+LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 10.
+LaTeX Font Info: ... okay on input line 10.
+LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 10.
+LaTeX Font Info: ... okay on input line 10.
+LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 10.
+LaTeX Font Info: ... okay on input line 10.
+LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 10.
+LaTeX Font Info: ... okay on input line 10.
+LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 10.
+LaTeX Font Info: ... okay on input line 10.
+LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 10.
+LaTeX Font Info: ... okay on input line 10.
+LaTeX Font Info: External font `cmex10' loaded for size
+(Font) <7> on input line 19.
+LaTeX Font Info: External font `cmex10' loaded for size
+(Font) <5> on input line 19.
+
+Overfull \hbox (5.38829pt too wide) in paragraph at lines 64--67
+[]\OT1/cmr/m/n/10 And here is the list of all math styles, ac-ti-vated via []\O
+T1/cmtt/m/n/10 \displaystyle\OT1/cmr/m/n/10 , []\OT1/cmtt/m/n/10 \cramped\OT1/c
+mr/m/n/10 -
+ []
+
+[1
+
+] (example3.aux) )
+Here is how much of TeX's memory you used:
+ 248 strings out of 10889
+ 2357 string characters out of 147219
+ 49955 words of memory out of 263001
+ 3239 multiletter control sequences out of 10000+0
+ 4929 words of font info for 20 fonts, out of 200000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 23i,13n,18p,143b,160s stack positions out of 300i,100n,500p,30000b,4000s
+
+Output written on example3.dvi (1 page, 4828 bytes).
diff --git a/systems/tex-extensions/clasen/examples/example3/example3.ps b/systems/tex-extensions/clasen/examples/example3/example3.ps
new file mode 100644
index 0000000000..e5a442aa60
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/example3.ps
@@ -0,0 +1,652 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.76a Copyright 1997 Radical Eye Software (www.radicaleye.com)
+%%Title: example3.dvi
+%%Pages: 1
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSCommandLine: dvips -a -D600 -mode ljfive example3.dvi -o
+%+ example3.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource: TeX output 1998.07.23:1938
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N
+/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id
+gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp
+add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add
+/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{
+dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1
+adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2
+idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string
+putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval
+adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg}
+{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{
+adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2
+chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{]
+}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{dup length product length le{dup length product
+exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}
+ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}
+imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false
+RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round
+exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto
+rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup
+/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{
+-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}
+B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B
+/bos{/SS save N}B /eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (example3.dvi)
+@start
+%DVIPSBitmapFont: Fa cmex10 10 6
+/Fa 6 68 df<177CA217F8EE01F01603EE07E017C0EE0F80161FEE3F00A2167E5EA24B5A
+15035E4B5A150F5E151F5E153F93C7FC5D15FEA24A5AA24A5AA214075D140F5D141FA25D
+143F5D147FA292C8FC5CA2495AA3495AA3495AA3495AA3131F5CA2133FA25CA2137FA25C
+13FFA44890C9FCA5485AA512075BA4120FA25BA5121FA35BA5123FA65BA3127FAD5BA212
+FFB3A62E95688149>48 D<127812F8127C7E123F6C7E120F6C7E7F6C7EA26C7E6C7EA213
+7E137F7F6D7E80130F801307801303806D7EA26D7EA2147FA281143F81141F81A2140F81
+140781A2140381A26E7EA36E7EA36F7EA36F7EA382151FA282A2150FA282A2150782A46F
+7EA56F7EA5178081A417C0A2167FA517E0A3163FA517F0A6161FA317F8AD160FA217FCB3
+A62E957E8149>I<EAFFC0B3A6127FA27FAD123FA37FA6121FA57FA3120FA57FA21207A4
+7F1203A56C7EA56C7FA4137F80A2133FA280A2131FA280130FA36D7EA36D7EA36D7EA36D
+7EA28081A2143F81141F81A2140F811407811403A26E7EA26E7EA2157F8182151F82150F
+8215076F7E8215016F7EA2167E82A2EE1F80160FEE07C017E0EE03F01601EE00F8177CA2
+2E95688349>64 D<EE0FFCB3A617F8A2161FAD17F0A3163FA617E0A5167FA317C0A516FF
+A21780A45D1700A54B5AA54B5AA45E150FA25EA2151FA25EA2153F5EA34B5AA34BC7FCA3
+4A5AA34A5AA25D1407A25D140F5D141FA25D143F5D147F92C8FCA214FEA2495AA2495A5C
+13075C130F5C131F5C49C9FC5B137E5BA2485A485AA2485A5B485A121F48CAFC123E5A5A
+12782E957E8349>I<EAFFC0B3B3B00A34688049>I<EAFFC0B3B3B00A345A8049>I
+E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fb cmsy5 5 1
+/Fb 1 49 df<EA0780EA0FC0A4EA1F80A21300A25A123EA2123CA2127C1278A2127012F0
+A25A0A157D9612>48 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fc cmsy7 7 3
+/Fc 3 50 df<B712FEA327037A8F34>0 D<13E0EA01F0EA03F8A3EA07F0A313E0A2120F
+13C0A3EA1F80A21300A25A123EA35AA3127812F8A25A12100D1E7D9F13>48
+D<D97F80147F2601FFE0903803FFC0000701F8010F13F04801FE90381F8038261F01FF90
+383E001C281C007F8078130C486D6C487F4890261FE1E07F006090380FF3C06EB45A486D
+90C7EA0180806E5A157F6F7E4B7E8200604A6CEB0300913801E7F8912603C3FC5B6C9026
+0781FE130E6C49C66C5B001C013E90387FC07C6C01FC6DB45A6CB448010F5B000101E001
+0313C06C6CC890C7FC391B7C9942>I E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fd cmmi5 5 5
+/Fd 5 102 df<903807F02090381FFC6090387FFEE09038F80FC03801E00338038001A2
+D807001380A291C7FC7F7FEA03FC3801FFC06C13F0EB3FF8EB01FCEB003E141E140EA212
+30A200705B143C00785B387E01F0B55A00C71380D881FEC7FC1B1E7B9C24>83
+D<EB7C603803FEF0EA0787EA0F01001E13E0123C127CA238F803C0A314C2EB0786A2EA78
+0F383C3F8C381FF3F83807C0F017127C9120>97 D<EA7F80A3000FC7FCA4121EA4EA3C7C
+EA3DFF383F8780383E03C0127C1278A3EAF007A31480130F1400EA701EEA387CEA1FF0EA
+0FC0121D7C9C1A>I<EB01FEA3EB003CA41478A4EB7CF0EA03FEEA0787EA0F01001E13E0
+123C127CA238F803C0A314C2EB0786A2EA780F383C3F8C381FF3F83807C0F0171D7C9C1F
+>100 D<137F3803FF803807C1C0EA0F00121E5A387C0780387FFF00EAFFF800F8C7FCA3
+12781440003813E0383E03C0380FFF00EA07F813127C911C>I E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fe cmmi7 7 2
+/Fe 2 98 df<91381FE0189138FFFC380103EBFE78903907E03FF090380F000F011E1303
+5B49EB01E0137013F0A2000115C0A292C7FC7F7F6CB47E14F86DB47E6D13F06D7F01077F
+01007F1407EC00FF153F81A281121CA2003C141EA2151C153C007C5C007E5C397F8003E0
+9038F00FC000F3B5C7FC00E05B38C01FF0252A7CA829>83 D<EB0FC0EB3FE09038F87380
+3801E03F3807C01F1380EA0F0048130F48EB1F00123E127EA248133EA4485B1538A3ECF8
+70EA78011303393C0778E0381E1E7C390FFC3FC03903E00F001D1B7D9924>97
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Ff cmti10 10 10
+/Ff 10 120 df<14F8EB07FE90380FFF1C90383F07BE90387C03FEEBF801EA01F000035C
+EBE0001207485A4A5AEA1F80123FA249485A5AA300FE495AA448495AEDC1C0A391381F83
+80A2143F127C91387F8700007E13FF393E03CF8E381F0F8F390FFF07FC3907FC03F83901
+F000F0222677A42A>97 D<147F903803FFC04913E090381FC1F090383F0078017C133849
+13F83801F00100031303EA07E0D80FC013F0EC01E04848C7FCA2123F90C8FC5AA312FEA5
+5AA315101538007C147015F0007EEB01E0003EEB07C06CEB1F00380F80FE3807FFF86C13
+E0C690C7FC1D2677A426>99 D<147F903803FFC0010F13E090381F81F0EB7E0049137848
+5A485A485AA2485A001F14F090388001E0003FEB07C0EC3F8048B5120014FC14E090C8FC
+12FEA65AA2007C14101538007E147015F0003EEB01E06CEB07C0EC1F00380F80FE3807FF
+F86C13E0C690C7FC1D2677A426>101 D<EB03F013FF5A7EEB07E0A4495AA4495AA449C8
+FCA4137EEC07F0EC1FFCEC7FFE9038FCF83F9039FDE01F80EBFF80EC000F485A16C05B49
+EB1F8012035BA34848EB3F00A3157E485AA35D485A913801F81CA33A3F0003F038A3EDE0
+70127E16E0A2EDE3C048903801FF80007C6D13000038143C263B7BB92A>104
+D<EB03F013FF5A7EEB07E0A4495AA4495AA449C8FCA4137EED0F80ED3FC0ED7FE09038FC
+01F0913803C1F0EC0703EC0E073A01F80C0FE0141891383007C09138700380484848C7FC
+EBF1C0EBF38001FFC8FC485A6D7E14E014F8380FC3FCEBC0FE143FA248486C7EED81C0A3
+3A3F003F0380A3ED0700127EA2EC1F0E5D48EB0FFC007C6D5A0038EB01E0243B7BB926>
+107 D<D801E013FE3A07F803FF80260FFC0F7F3A1E3E1F07E0001C90383C03F038383F70
+ECE00114C000708114804A485A485A137EA2120049495AA34B5A485AA34B5A485A92383F
+0380A3484890387E0700A3ED7C0E485A5EA25E4848EB3FF0000F6E5A6CC7EA0780292679
+A42F>110 D<3903C003F03907F00FFC390FF83FFE391C7C7C1FECF00F3A387FC01F8015
+3F00709038807F001400153E017E131C484890C7FCA31200485AA4485AA4485AA4485AA4
+485AA448C9FC7E120E212679A423>114 D<14FE903807FF804913C090381F03E090383C
+00F049137001F813F0EBF00100011303A215E00003EB01C06DC7FC7F3801FFC014F8806C
+7F6D7E6D1380130F010013C0141F140FA2123C127E00FE1480A2481400485B00E0131E00
+705B0078137C383E03F06CB45A6C5BD801FEC7FC1C267AA422>I<1307EB0F80131FA4EB
+3F00A4137EA45BA2B512FC14FE14FC3801F800A3485AA4485AA4485AA4485AA448C7FC14
+38A21470127E14E0A2EB01C0A2EB0380383E0700131EEA1FFC6C5AEA03E0173578B31C>
+I<01F01507D803FC903903800F80486C903807C01FD80E1F010FEB3FC0121C171F003816
+0FED1F8048481507A21880D8E07E90383F0003A3C6481507037E1400485AA3484849130E
+A4484848485BA35FA25FA202035C1203D9F007495A000190390EFC03803A00FC1E7E0F90
+277FFC3FFFC7FC90393FF00FFC90390FE003F0322679A437>119
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fg cmsy10 10 4
+/Fg 4 113 df<007FB81280B912C0A26C17803204799641>0 D<14C0EB01E0A2EB03C0A3
+EB0780A3EB0F00A2131EA35BA25BA35BA2485AA3485AA3485AA248C7FCA3121EA25AA35A
+A35AA21278A37EA37EA27EA36C7EA26C7EA36C7EA36C7EA21378A37FA27FA37FA2EB0780
+A3EB03C0A3EB01E0A2EB00C0135278BD20>104 D<126012F0A21278A37EA37EA27EA36C
+7EA26C7EA36C7EA26C7EA31378A37FA27FA37FA2EB0780A3EB03C0A3EB01E0A2EB03C0A3
+EB0780A3EB0F00A2131EA35BA25BA35BA3485AA2485AA3485AA248C7FCA3121EA25AA35A
+A35AA2126013527CBD20>I<F10180F103C0A2F10780A2F10F00A2191EA261A261A261A2
+4E5AA24E5AA24E5AA24EC7FCA3181EA260A260A260A24D5AA24D5AA24D5AA24DC8FCA217
+1E132001F05D1201486C5D120F486C5D123D00794B5AEAE0FE00404B5AEA007F4C5A6D7E
+4CC9FC6D7E161EA26D6C5BA26D6C5BA26D7E5E6D7E4B5AEB00FE4B5AA291387F0780A2DA
+3F8FCAFCA2EC1FDEA2EC0FFCA26E5AA25D14035D14015D42547B8345>112
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fh cmmi10 10 19
+/Fh 19 121 df<0103B7FC18E018F8903B0007FC0007FE4BEB01FF9438007F80F03FC04A
+48141FF00FE019F018074A5AF003F8A34A4815FCA44A5AA44AC81207A4494816F8180FA3
+494816F0181FA219E04948153F19C0A2F07F80495AF0FF0060170149484A5A604D5A4D5A
+49484A5A4D5A4DC7FCEE01FE4948495AEE0FF001FFECFFC0007F90B6C8FCB712FC16C03E
+397DB845>68 D<48B812FE5A5A903AFC003FE00301E09138C0007ED80F80163C90C7FC00
+0E4A5A121E121CA2484AC7FC18385AA24A5A5AA2481730C748481400A44A5AA44A5AA44A
+5AA44A5AA44A5AA44AC9FCA4495AA4495AA2EB0FFE003FB67EA337397EB831>84
+D<147E903803FF80010FEBC38090391F81E7C090383E00FF49137F5B4848EB3F80485A12
+074848131FED3F00485AA2123F90C7127E5AA300FE5CA44A5A48151CA3913803F038A200
+7C1307140F007E011F1370003E133B6C01F113E0380F83E13A07FFC0FFC06C9038807F80
+3A00FC001F0026267DA42C>97 D<133FEA0FFF5AA2EA007EA45BA4485AA4485AA4485A14
+FCEBE3FF01E713C0390FDF07E09038FC01F013F801F013F8381FE0004913FC5BA248C7FC
+A4007E1301A448EB03F8A315F014074814E0A2EC0FC0A2EC1F801500007C133E147E003C
+5B383E01F0381F07E06CB45A6C90C7FCEA01FC1E3B7CB924>I<EC3FC0903801FFF00107
+13FC90380FE03E90383F800E90387E001F49133F4848137F484813FF485A15FE4848137C
+001F1438491300123F90C8FC5AA312FEA55AA31502007C1407007E140E151C003E14386C
+14F0390F8003E09038E03FC00003B512006C13FC38003FC020267DA424>I<163FED0FFF
+5DA2ED007EA416FCA4ED01F8A4ED03F0A4ED07E0147E903803FF87010F13C790391F81EF
+C090383E00FF49137F5B4848EB3F80485A12074848131FED3F00485AA2123F90C7127E5A
+A300FE5CA44A5A48151CA3913803F038A2007C1307140F007E011F1370003E133B6C01F1
+13E0380F83E13A07FFC0FFC06C9038807F803A00FC001F00283B7DB92B>I<EC3F809038
+01FFF0010713F890381FE07C90383F003C017C131E5B485A1203485A485A001F143C4913
+78003FEB01F0EC07E048B512C0150014F890C8FC127E12FEA6127E15021507150E003E14
+1C003F14386C14F0390F8003E03907E03FC06CB512006C13FC38003FC020267DA427>I<
+16F8ED03FE4B7E92380F0F80ED1E1FED3E3FED7C7FA203FC1300163E161C4A48C7FCA54A
+5AA54A5AA20103B512F05B5E9026000FC0C7FCA54A5AA64AC8FCA5147EA55CA5495AA549
+5AA45C1307A25C121E003F5BEA7F8FA2D8FF0FC9FC131E127EEA7C3CEA3FF86C5AEA07C0
+294C7CBA29>I<EC07E0EC1FF891387FFC389138FC1E7C903903F007FCEB07E090380FC0
+03D91F8013F81400491301137EED03F05B1201A249EB07E01203A34848EB0FC0A4ED1F80
+5BA3ED3F0000035CA26D5B0001495A3800F80790387C1F7EEB3FFE90381FF8FCEB07E090
+C7FCA24A5AA4001E495A123F486C485AA24848485A4A5A007E017FC7FC387C01FE383FFF
+F86C13E0000390C8FC26367FA428>I<EB03F013FF5AA2380007E0A4495AA4495AA449C9
+FCA4137EEC03F8EC1FFE4A6C7E9039FCFC0FC09038FDE007D9FFC07F148048EB00035B5B
+49130712035BA34848495AA34B5A485AA24BC7FCA2485A92387E0380A348C738FC0700A3
+EDF80E127E5E5EED787848EC7FF0007C6E5A0038EC0F80293B7CB930>I<14E0EB01F0EB
+03F81307A214F0EB03E0EB01C090C7FCAB13F8EA01FEEA07FF130F000E1380121C1238A2
+EA701FA338E03F00A3EA007EA25BA3485AA3485AA23807E038A3380FC070A3EB80E0A2EB
+81C0EB83803807870013FFEA03FCC65A15397EB71D>I<150E151FED3F80157FA2160015
+3E151C92C7FCABEC0F80EC3FE04A7EECF0F8EB01C049487EEB0700A2130E5BA24A5A1338
+A213004A5AA44A5AA44A5AA44A5AA44AC7FCA4147EA45CA4381E01F8123F387F83F05CEA
+FF07495A48485AD87C3FC8FCEA3FFC6C5AEA0FC0214981B722>I<EB03F013FF5AA23800
+07E0A4495AA4495AA449C8FCA4137EED07C0ED1FE0ED3FF049EBF838913801E0F8EC0381
+EC07033901F80E07141C143891387003F03A03F0E001C0D9F1C0C7FCEBF38001FFC8FC48
+5A6D7E14F014FC380FC1FEEBC07FEC1F80A248486C7E1670A33A3F001F80E0A3ED81C012
+7E020F1380158391380787004814FE007C6D5A0038EB00F8253B7CB92B>I<EB0FC0EA03
+FF5A7E38001F80A4EB3F00A4137EA45BA4485AA4485AA4485AA4485AA4485AA448C7FCA4
+127E1307A3EAFC0EA35BA3EA7C381378EA3FF06C5AEA0780123B7DB919>I<D803E0017F
+14FE3D07F803FFC007FF80486C48D9F00F13E03D1C3E1F81F83F03F0DA3C00EB78012638
+3F78D9FCF07F4AEBFDE000704990387DC0004AEB7F804A91C7FC91C700FE1301485A017E
+5CA21200494948495AA34E5A4848495AA24E5AA24848495A95381F80E0A3484849489038
+3F01C0A395383E03804848495AF10700190EF01E1E484849C7EA1FFC000F6E6E5A6CC700
+0EEC03E043267EA449>I<D803E0137F3A07F803FFC0486C4813F03A1C3E1F81F8EC3C00
+26383F787F5C007049137C5C5C91C712FC485A137EA2120049495AA34B5A485AA24B5AA2
+485A92380FC070A3484890381F80E0A3EE01C0485AEE0380EE07006F5A484814FE000FEC
+07F86CC7EA01F02C267EA432>I<EC1FC0ECFFF801077F90380FE07E90383F801F90397E
+000F8049EB07C0484814E0485A485AED03F0485A121F5B003F140790C7FC5AA300FEEC0F
+E0A316C0151F481580153F1600157E127E5D4A5A003E495A6C495A390F801FC02607E07F
+C7FC3803FFFE6C13F038003F8024267DA428>I<90390F8003F090391FE01FFC496C487E
+903970F87C1F9238F00F80903AE0FDC007C0DAFF8013E04848EB00035C4A14F0A2380381
+F8A3D800011407495AA44948EB0FE0A317C04948131F1780A2EE3F00495A6E137E167C5E
+496C485A4B5A6E485A9138781F8090267E3FFFC7FCEC1FFCEC07E091C9FC5BA4485AA448
+5AA3387FFFC0B5FC7E2C3583A42A>I<90390FC007E090393FF00FF890397FF83FFC9039
+F07C783C3A01C03EF03E3A03801FE07ED80700EBC0FE000E14C115815AED80FC4890383F
+00701600A2C7FC147EA45CA4495A1638A2121C267E03F0137012FF16E0130700FEEC01C0
+D8FC0FEB03803AF81EF8070039783C7C1E397FF83FFC393FE01FF8390FC007E027267DA4
+2F>120 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fi tf10 10 22
+/Fi 22 101 df<1906190FA2191EA2193CA21978A219F0A2F001E0A2F003C0A2F00780A2
+F00F00A2181EA260A360A260A24D5AA24D5AA24D5AA24DC7FCA2171EA25FA25FA201105D
+133001F84A5A120100034B5A487E001F4B5A487E007D4BC8FC12F1D8E0FF141E1240C66C
+6C5BA26D6C5BA25E6D7E4B5AEB0FF0A24B5AEB07F84B5AEB03FC4BC9FCEB01FE151EA26D
+6C5AA2EC7FF8A25D143F5D141F5D140F5DA26ECAFC4054798345>0
+D<1B301B78A31BF0A4F201E0A4F203C0A5F20780A4F20F00A41A1EA462A462A462A54F5A
+A44F5AA44F5AA44FC7FCA4191EA461A561A461A44E5AA44E5AA44E5AA44EC8FCA5181EA4
+60A401085EA21318133860137C13FCA200014C5A487EA21207A2000F4C5AEA1EFF121C5A
+00784C5A127038F07F80126000004CC9FCA26D7EA2171EA36D7E5FA46D6C5CA46D7E5FA4
+6D6C495AA44C5A6D7EA34C5A6D7EA34CCAFCA2EC7F80A2161EA2EC3FC0A35EA2EC1FE0A2
+5EA3EC0FF05EA3EC07F8EDF9E0A46EB45AA45E80A46E90CBFCA45D157EA3157CA2153C15
+384DC8788353>3 D<007FB512FEB7FCA215FE00F0C8FCB3B3AB12602034468358>7
+D<126012F0A21278A27EA27EA27EA26C7EA36C7EA26C7EA26C7EA21378A27FA27FA27FA2
+6D7EA26D7EA36D7EA26D7EA21478A280A28018106E1538183C6E6C143EF07F806E6C15C0
+F0FFE06E6C15F019786E6C903801FE3E191F943803FC0E03781500A26F495AA26F495AA2
+814D5AED07804D5AED03C04D5AED01E0A26F6C48C7FCA2EE79FEA3EE3FFCA2705AA2160F
+5F16075F1603A2705A4054828345>I<126012F0A21278A27EA27EA27EA26C7EA26C7EA3
+6C7EA26C7EA21378A27FA27FA27FA26D7EA26D7EA26D7EA26D7EA21478A380A280A280A2
+6E7EA26E7EA26E7E616E6C4B7E86037882F107F86F824F7E6FEEFF8096381FE7C06FEEE3
+E0F2E0F06F6C91383FC0601B004F5A6F7E4FC7FC6F7EA26F6C495AA20478495AA2824E5A
+824E5A824E5AEE0780A2706C485AA2706C485AA2EE00F04EC8FCA2EF79FEA2EF3FFCA217
+1F60170F601707601703A2715A4C64828353>I<126012F0A31278A37EA37EA37EA36C7E
+A36C7EA46C7EA36C7EA31378A37FA37FA47FA36D7EA36D7EA36D7EA36D7EA31478A480A3
+80A380A36E7EA36E7EA36E7EA3616E6C4B7E868603784B7EA2866F824F7E866FEEF7801A
+F396381FE3C06FEEE1E0F2E0F096383FC0606F6C1600A34F5A6F7EA24FC7FC6F7EA36F6C
+495AA30478495AA3824E5AA3824E5AA2824E5AA2EE0780A24E5AEE03C0A24E5AEE01E0A3
+706C48C8FCA3EFF1FE1779A3EF3FFCA3171F60A2170F60A21707A2601703A26017014C96
+828353>I<126012F0A31278A47EA57EA47EA46C7EA46C7EA56C7EA46C7EA41378A47FA5
+7FA47FA46D7EA56D7EA46D7EA46D7EA41478A580A480A480A46E7EA56E7EA46E7EA3616E
+6C4B7EA286A20378824F7EA28686814F7EA21AF76F17801AF396381FE3C0F2E1E06F16E0
+1BF096383FC0601B006F7EA34F5AA26F7EA34FC7FC6F7EA46F6C495AA40478495AA57049
+5AA4824E5AA382A24E5AA3EE0780A24E5AA2EE03C0A24E5AA2EE01E0A34EC8FC707EA4EF
+F1FE1779A4EF3FFCA4715AA4170F60A4170760A31703A26017014CC8828353>I<007FB5
+12FCB612FEA27EC8121EB3B3AB150C1F34828358>15 D<ED01E0A26F7EA21678167C007F
+B7FCB81280A26C1600C9127C16785EA24B5AA229107EBA2E>I<1878A284183E84F00F80
+007FB912E0BA12F0A26C18E0CBEA0F80F01F00183E183C60A23C107EBA41>I<387FFFF0
+B512F8A26C13F0150482B412>20 D<1D78A2891D3E89F50F80007FBE12E0BF12F0A26C1D
+E0D0EA0F80F51F001D3E1D3C65A2641082BA65>I<EA03C0A2485AA248CAFC5A007FB7FC
+B81280A26C1600001FCAFC7E6C7EA26C7EA229107EBA2E>24 D<EA01E0A2485A1207485A
+48CCFC007FB912E0BA12F0A26C18E0001FCCFC6C7E6C7E12036C7EA23C107EBA41>I<EA
+01E0A2485A1207485A48D0FC007FBD12FEBFFCA26C1CFE001FD0FC6C7E6C7E12036C7EA2
+60107EBA65>27 D<177F933803FFC04C13F093381FC0F893383F0038047E137C9338FC01
+FCDB01F813FE923803F0031507A292390FE001FCA2031FEB00704C1300153FA34B5AA415
+FFB3B3B3B3B3A293C8FCA35CA25DA34A5AA2001C5C007F13075DD8FF805B140F4A5A0100
+5B6C49C9FC007C137E383801FC383E07F8381FFFE000071380D801FCCAFC378A7C7F2E>
+33 D<147F903803FFC0010F13E090383FC0F090387F003801FE131C484813FC3903F801
+FE3807F003120F13E0121F393FC001FCEC00F81520007F14005BA212FFB3A96CC8FC1F2E
+647F2E>I<157FEDFF80B3A916005CA25DA2001C1303007F5CA2486C485A5D4A5A49485A
+6C495A007C49C7FC003813FE383E07FC381FFFF0000713C0D801FCC8FC212F7C802E>I<
+127FEAFF80B3B3AAEA7F00093064802E>I<13101338137C13FE487E3803EF803807C7C0
+380F83E0381F01F0383E00F848137C00F0131E0060130C170D77B92A>40
+D<007FBA12E0BB12F0A300F0CB1207191F193F197E19F8F001F0F003E0F007C0F00F80F0
+1F00183E18FC4D5A4D5AEF07C04D5A4DC7FC173E5F5F4C5AEE07E04C5A4C5A043EC8FC5E
+5E4B5A4B5A4B5AED1F804BC9FC157E15F84A5A4A5A4A5A4A5A4ACAFC143E14FC495A495A
+EB07C0495A49CBFC133E5B5BEAF1F0EAF7E0B45A5B48CCFCBBFCA36C19E0443E82BB41>
+I<FC000101808058>100 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fj cmtt10 10 30
+/Fj 30 126 df<1478A214FCAE007FB612F0A2B712F8A26C15F0A2C700FCC7FCAE1478A2
+25267DAB2C>43 D<007FB6FCA2B71280A26C1500A221067B9B2C>45
+D<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>I<007FB612F0A2B7
+12F8A26C15F06C15E0CAFCA8003FB612E04815F0B712F8A26C15F0A225147DA22C>61
+D<1278A212FCA27E127E127F7E7F121F7F120F7F1207A27F12037F12017F12007F137E13
+7F7F80131FA280130F801307801303801301801300A280147E147F8081141F81140F8114
+07811403A281140181140081157E157F811680151FA2ED0F008121417BB92C>92
+D<130EEB3F80EBFFE0000313F8000F13FE003FEBFF804814C0D8FFF113E0EBC07FEB803F
+38FE000F0078EB03C00020EB00801B0D78B22C>94 D<007FB6FCA2B71280A26C1500A221
+067B7D2C>I<3801FFF0000713FE486D7E48804880819038C01FF8391F8007FC380F0001
+000680C8FCA2140FEB07FF137F48B5FC12075A4813F8383FFC00EA7FE0EAFF8090C7FC5A
+A36C1301A2387F8007383FE03F90B612FC6C15FE7E6C143F0001EBFC1F3A007FC00FFC27
+247CA32C>97 D<EA3FF8487E12FFA2127F123F1201A9EC0FF0EC7FFE01FDB5FC90B61280
+16C016E09138F03FF09138C00FF891380003FC5BED01FE491300A216FF167FA816FF6D14
+FE15017FED03FC91388007F8ECC00F9138F03FF091B512E016C001FD148001FC14000000
+EB7FFC9038780FF0283380B22C>I<903803FFF0011F13FC017F7F90B6FC4815805A48EB
+007FD80FF8EB3F00D81FE0131E4848130C4990C7FC127F90C9FCA25A5AA67E7EA26DEB0F
+806C6CEB1FC07F6C6C133FD80FFCEB7F803907FF81FF6C90B512006C5C6C5C6D5B011F13
+E0010390C7FC22247BA32C>I<EC07FF4A13805CA28080EC003FA9EB0FF8EB3FFE90B512
+BF4814FF5A5A380FFC0F381FF00349C6FC4848137F485A153F90C7FC5A5AA87E6C147FA2
+6D13FF6C7E5C381FF007380FFC1F6CB612FC6C15FE6CECBFFF6C143FD97FFC13FE90390F
+F01FFC28337DB22C>I<EB03FE90381FFFC0017F13F090B57E488048803907FE03FF260F
+F8001380D81FE0137F4848EB3FC049131F127F90C713E0150FB7FCA516C048C9FC7E7E7F
+ED07C06C6CEB0FE07F6C6C131FD80FFCEB3FC03907FF80FF6C90B512806C15006C5C013F
+13F8010F5B0101138023247CA32C>I<EC07F8EC3FFCECFFFE497F4914805B90380FF87F
+9138E03F00011F131E4AC7FCA6003FB512FE4880B7FCA36C5C26001FC0C7FCB3A6007FB5
+12F0B67EA46C5C21337DB22C>I<ED03F0903907F81FFC90391FFE3FFE017FB5FC90B7FC
+5A48ECFE7F3A07FE1FF87ED9F003133C000FECFC00EBE001001F80EBC000A5EBE001000F
+5CEBF00300075CEBFE1F90B55A5D485C5DD9DFFEC7FCEBC7F801C0C8FCA27F6CB512E015
+FE6CECFF80000F15C04815E04815F09039C0003FF848C7EA03FC007E140000FE15FE4815
+7EA46C15FE007E15FCD87F801303D83FE0EB0FF8D81FFEEBFFF06CB612E06C15C06C1580
+C6ECFE00013F13F80103138028387EA42C>I<EA3FF8487E12FFA2127F123F1201A9EC07
+F8EC3FFE91B5FC01FD8090B67E82ECF81F9138C00FF0EC800714005BA35BB13B3FFFE03F
+FF80486D4813C0B56CB512E0A26C496C13C06C496C13802B3380B22C>I<EB0380497E49
+7E497EA36D5A6D5A6D5A90C8FCA7383FFFE0487FB5FCA27E7EEA0007B3A6007FB512FCB6
+12FE15FFA215FE6C14FC20347AB32C>I<383FFFF0487FB5FCA27E7EEA0003B3B3A3003F
+B612804815C0B712E0A26C15C06C158023337CB22C>108 D<3A3FC1F803F03A7FE7FC0F
+F8B538FE3FFC6E487E6C91B5FC7E3B07FE1FFC3F8001FC13F89039F80FF01F01F013E0A3
+01E013C0B2D83FFC01F813F03B7FFE1FFC3FF8B5393FFE7FFCA23B7FFE1FFC3FF83B3FFC
+0FF81FF02E2481A32C>I<393FF807F8397FFC3FFE00FF90B5FC01FD806CB67E6C810001
+EBF81F9138C00FF0EC800714005BA35BB13B3FFFE03FFF80486D4813C0B56CB512E0A26C
+496C13C06C496C13802B2480A32C>I<EB07FCEB1FFF017F13C048B512F048804880390F
+FC07FE391FF001FF497E4848EB7F8049133F48C7EA1FC0A300FEEC0FE0A76C141F6C15C0
+A26D133F003F15806D137F6C6CEBFF00EBF803390FFE0FFE6CB55A6C5C6C5C6C6C13C001
+1F90C7FCEB07FC23247CA32C>I<393FF80FF0397FFC7FFED8FFFDB5FC90B612806C15C0
+6C15E000019038F03FF09138C00FF891380003FC5BED01FE491300A216FF167FA816FF6D
+14FE15017FED03FC91388007F8ECC00F9138F03FF091B512E016C001FD148001FC1400EC
+7FFCEC0FF091C8FCAC383FFFE0487FB57EA26C5B6C5B283680A32C>I<D83FFFEB3FC048
+903881FFE0B5008713F0028F13F86C019F13FC6C13BF39003FFFE3ED01F89138FC00F04A
+13604A1300A25CA25CA35CAD003FB512F04880B6FCA27E6C5C26247EA32C>114
+D<90383FF8700003B512F85A5A5A5A387FC01F38FF000700FC1303A36CEB01F06C6CC7FC
+EA7FFC383FFFF06C13FF6C14C06C14E0C614F0010F13F89038007FFCEC03FE003CEB00FF
+007E143F12FE7EA26D137F6D13FEEBF00790B512FC15F815F015E000F8148039701FFC00
+20247AA32C>I<130F497E133FA8003FB6FC481580B7FCA36C150026003F80C7FCAFED03
+80ED07C0ED0FE0A3151F02C013C0011F133F9138F07F806DB5FC16006D5B6D13F801005B
+EC3FC0232E7EAD2C>I<D83FF8EBFFE0486C487F00FF5BA2007F7F003F7F00011407B3A2
+150FA2153F01FF13FF6C90B6128017C06D15E07F6D01E713C00103010313802B2480A32C
+>I<3A7FFF01FFFCB5008313FE14C7A214836C010113FC3A03F0001F806D133F00011500
+A26D5B0000147EA26D13FE017E5BA36D485AA31483011F5BA214C7010F5BA3903807EFC0
+A214FF6D5BA36D90C7FCA26D5A27247EA32C>I<3A3FFF03FFF048018713F802C713FCA2
+028713F86C010313F03A00FE01FC0090387F03F8EB3F83EC87F090381FCFE090380FEFC0
+EB07FF5D6D90C7FC7F6D5A5C80497E5B497FECEFC090380FCFE0EB1FC7EC83F090383F03
+F8496C7EEBFE00497F3A3FFF03FFF848018713FCB500C713FEA26C018713FC6C010313F8
+27247EA32C>120 D<3A3FFF01FFFC48018313FEB512C7A26C13836C010113FC3A03F800
+1F800001143F6D140012005D6D137E137EA2017F5B7FA2EC81F8131FA2EB0FC1ECC3F0A2
+EB07E35D14E71303ECF7C0130114FF5D7FA292C7FC80A2147EA314FE5CA21301000C5BEA
+3F03387F87F0138F495AEBFFC0A26C5B6C48C8FC6C5AEA07F027367EA32C>I<EDFFC002
+0713E0141F147F91B5FC4914C0EDC000D903FCC7FC5CB31307EB3FF0383FFFE0485BB55A
+91C8FC806C7F6C7F38003FF0EB07F81303B380903801FFC0EDFFC06D14E080141F140702
+0013C023417CB92C>123 D<EA3FE0EA7FFCB5FC14C0806C7FEA007FEB07F81303B3806D
+B47E6DEBFF806E13C06E13E0805C4A13C091B5128049EB8000D903FCC7FC5CB31307EB7F
+F0EA7FFFB55A5C91C8FCEA7FFCEA3FE023417CB92C>125 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fk cmr10 10 42
+/Fk 42 123 df<EC07F8EC3FFE49B57E903903FC07C090390FE001E090381FC003494848
+7E90387F000F137E13FE496D5A00016E5A6F5A92C8FCA9ED07F0B7FCA33901FC001F1507
+B3AA486C497E267FFFE0B512C0A32A3B7FBA2E>12 D<EC07FC91387FFF7049B512F09038
+03FC0790380FE00FEB1FC0EB3F005B017E130713FE5B1201ACB7FCA33901FC0007B3AB48
+6C497E267FFFF1B512C0A32A3B7FBA2E>I<14E01301EB03C0EB0780EB0F00131EA25B5B
+13F85B12015B12035B1207A2485AA2121F90C7FCA25AA2123EA2127EA5127C12FCB2127C
+127EA5123EA2123FA27EA27F120FA26C7EA212037F12017F12007F13787F7FA27FEB0780
+EB03C0EB01E01300135278BD20>40 D<126012F012787E7E7EA26C7E6C7E7F12017F1200
+7F1378137CA27FA2133F7FA21480A2130FA214C0A5130714E0B214C0130FA51480A2131F
+A21400A25B133EA25BA2137813F85B12015B12035B485A48C7FCA2121E5A5A5A12601352
+7CBD20>I<15301578B3A6007FB812F8B912FCA26C17F8C80078C8FCB3A6153036367BAF
+41>43 D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA
+0700A2120E5A123C123812100B1A7A8917>I<B512FCA616067F941C>I<121E123FEA7F80
+EAFFC0A4EA7F80EA3F00121E0A0A7A8917>I<EB01C013031307131F13FFB5FCA2131F12
+00B3B3A8497E007FB512F0A31C3879B72A>49 D<007FB812F8B912FCA26C17F8CCFCAE00
+7FB812F8B912FCA26C17F836167B9F41>61 D<1538157CA315FEA34A7EA34A7FA34A7F15
+3FA2020F7FEC0E1FA2021E7FEC1C0FA2023C7FEC3807A202787FEC7003A202F07FECE001
+A20101804A7EA20103814A137FA201078191C7123F91B6FC4981A2010EC7121F011E8101
+1C140FA2013C8101381407A201788101701403A201F08116011201486C81D80FFE020713
+80B500C090B512FEA3373C7DBB3E>65 D<B712E016FC16FF0001903980007FC06C90C7EA
+1FE0707E707E707EA2707EA283A65FA216035F4C5A160FEE1FE0EE7FC04B485A91B548C7
+FCA2707E91C7EA3FE0EE0FF0707E707E707E707EA21880177F18C0A7188017FFA24C1300
+5F16034C5AEE1FF8486DEB7FF0B812C094C7FC16F832397DB83B>I<B812FCA300019038
+80001F6C90C71201707E177E173E171EA2170EA4170F83ED01C0A394C7FCA31503A21507
+151F91B5FCA3EC001F15071503A21501A218E0A3170192C713C0A41703A3EF0780A2170F
+A2171F173F17FF486D010F1300B9FCA333397DB839>69 D<DBFF8013C0020FEBF001023F
+13FC9139FF803E03903A03FC000F87D907F0EB03CFD91FC0EB01EF4948EB007F49C8FC01
+FE153F4848151FA24848150F485A000F16075B001F1603A2485AA21701127FA25B94C7FC
+12FFAA93B6FC127FA26D9138007FE0EF3FC0123FA36C7EA26C7EA212076C7E6C7EA26C7E
+017F157F6D7ED91FE014EFD907F0EB01C7D903FCEB0783903A00FFC03F0191393FFFFE00
+020F01F8130002001380383D7CBA41>71 D<B612C0A3C6EBC0006D5AB3B3AD497EB612C0
+A31A397EB81E>73 D<B591380FFFFE80A2C66D010013E06EEC3F80EF1F00D9EFF0140E80
+13E7EBE3FC8013E1EBE0FF81147F81143F6E7E81140F6E7E8114036E7E8180ED7F8016C0
+153FED1FE016F0150FED07F816FC1503ED01FE16FF81EE7F8E17CE163FEE1FEE17FE160F
+A216071603A216011600A2486C157E486C153EEA0FFEB500E0141E170EA237397DB83E>
+78 D<003FB812E0A3D9E003EB003F90260001FE1307007EEE03F0007C160100781600A3
+00701770A400F01778481738A4C71600B3B0913807FF80011FB612E0A335397DB83C>84
+D<007FB590387FFFFCA3C601F8010F1380D97FE0D903FCC7FC013FEC01F06D6C5C5F6D6C
+13036D6C495A94C8FC6D6C5B161E6D6C131C6DEB803C5E91387FC07091383FE0F0EDE1E0
+91381FF1C0EC0FF3EDFB806EB4C9FCA26E5A6E7EA26E7F6F7E15FF825C913803DFF0ED8F
+F8140791380F07FC91380E03FE141E91381C01FF4A7E02788002706D7E14F049486D7E4A
+6D7E130349486D7E91C76C7E5B011E6E7E1601013E8101FF8200076D01077FB500F0013F
+EBFF80A339397EB83E>88 D<EB3FE0EBFFFC000313FF3907C03F80390F800FC0486C6C7E
+01E07F6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7FF13801FF01EA07F8EA0F
+F0EA1FE0EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC01C7E383A1FF078
+7FF83A0FFFF03FF0000301E013E03A007F000F8026277DA52A>97
+D<EA03F812FFA3120F1203B0EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC090
+39FE0007E049EB03F0A249EB01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F8
+6D14F0ED07E06DEB0FC09039E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0
+283B7EB92E>I<EB03FC90381FFF80017F13E09038FE01F03901F800F83903F001FC3807
+E003EA0FC0121F90388001F8003FEB00F01560007F140090C8FCA25AA97EA27FA2003F14
+0E7F001F141C6C7E000714386C7ED801FC13F03900FF03E090387FFFC0011F1300EB07F8
+1F277DA525>I<ED1FC0EC07FFA3EC007F151FB0EB07F8EB1FFE90387FFF9F9038FE07DF
+3901F800FF4848137F4848133F4848131F121F485AA2127F90C7FCA35AA97EA27F123FA2
+121F6C6C133F157F6C6C13FF3A03F001DFF03A01FC079FFF39007FFF1FEB3FFED907F013
+C0283B7DB92E>I<EB07F8EB1FFF017F13809038FC0FC03901F003E03903E001F0000714
+F8390FC000FC121F4913FE003F147EA248C7127FA35A90B6FCA390C8FCA57EA27F123F15
+076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F090383FFFC06D1380903803
+FC0020277EA525>I<147E903803FF80010F13C090381FC7E090383F07F0EB7E0F13FE13
+FC0001EB07E09038F803C0000390C7FCADB512FCA3D803F8C7FCB3AB487EB512F8A31C3B
+7FBA19>I<ED03E090390FF00FF090393FFC1FF890B5EA3C7C3A01F81FF0FC3A03E007C0
+7C3A07C003E038000FECF000001F80EB8001003F80A7001F5CEBC003000F5C00075C6C6C
+485A9038F81F800006B5C7FCEB3FFC380E0FF090C9FC121EA3121F6C7E90B512C015F86C
+14FE6CECFF8016C04815E0391F80007F48C7EA0FF0007E140316F8481401A5007EEC03F0
+A26CEC07E06C6CEB0FC0D80FE0EB3F803A07FC01FF000001B512FC6C6C13F0010790C7FC
+26387EA52A>I<EA03F812FFA3120F1203B0EC07F0EC1FFCEC7FFF9138F07F809038F9C0
+1FD9FB807F9038FF000F49805BA35BB3A4486C497EB500E1B51280A3293A7EB92E>I<EA
+03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A3
+13387EB718>I<EA03F812FFA3120F1203B1913803FFFCA36E13C0913800FE005D15F04A
+5A4A5A4A5A4AC7FC141E5C5C14FCEBF9FE13FBEBFF7F496C7EEBFC1F01F87F6E7E6E7EA2
+6E7E6E7EA26E7E157FA2ED3F8016C0486CEB7FF0B500E1B5FCA3283A7EB92C>107
+D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<2703F807F8EB0FF000
+FFD91FFEEB3FFCDA7FFFEBFFFE913AF03F81E07F3D0FF9C00FC3801F802603FB80D9E700
+7F020013E601FED907FC6D7EA2495CA2495CB3A4486C496C497EB500E1B500C3B51280A3
+41257EA446>I<3903F807F000FFEB1FFCEC7FFF9138F07F80390FF9C01F2603FB807F90
+38FF000F49805BA35BB3A4486C497EB500E1B51280A329257EA42E>I<EB03FE90380FFF
+80013F13E09038FE03F83901F800FC4848137E48487F4848EB1F80001F15C049130F003F
+15E0A248C7EA07F0A44815F8A96C15F0A26D130F003F15E0A26C6CEB1FC0000F15806D13
+3F6C6CEB7F006C6C13FE3900FE03F890387FFFF0011F13C0D903FEC7FC25277EA52A>I<
+3903F80FE000FFEB7FFC9038F9FFFE9039FBE07F803A07FF801FC03A03FE000FE049EB07
+F0A249EB03F816FC150116FEA3ED00FFA916FE1501A316FC150316F86DEB07F0ED0FE06D
+14C09039FF803F809039FBE07F009038F9FFFE9038F87FF8EC1FC091C8FCAB487EB512E0
+A328357EA42E>I<3803F03F00FFEB7F809038F1FFE014C7390FF38FF03803F70F13F690
+38FE07E09038FC03C0EC018091C7FCA25BB3A3487EB512F8A31C257EA421>114
+D<EBFF83000313E7000F13FFEA1F80383E003F487F00787FA200F87FA37E6C90C7FC6C7E
+EA7FF8EBFF806C13E06C13F86C7F6C7F00017F6C7E01031380EB003F0060EB1FC000E013
+0FA26C1307A37E15806C130F1500B4131EEBC07C38F3FFF800E15B38C07F801A277DA521
+>I<131CA5133CA3137CA213FC120112031207121FB6FCA3D801FCC7FCB2EC01C0A93900
+FE0380A2017E13006D5AEB1FFE6D5AEB03F01A347FB220>I<D803F8EB0FE000FFEB03FF
+A3000FEB003F0003140FB3A5151FA2153F1201156F6C6CEBEFF8903A7E03CFFF8090383F
+FF8F6D130FD903FCEBE00029267EA42E>I<B538C07FFEA33A0FFC001FF0D803F8EB07C0
+16807F00011500A26D5B0000140EA2017F5BA2EC803C013F1338A26D6C5AA214E0010F5B
+A214F101075BA2903803FB80A214FF6D90C7FCA36D5AA2147CA3143827257EA32C>I<B5
+3A8FFFF07FFEA3260FF8009038800FF8000791397F0007E0EF03C000031780816DEC8007
+0001027F1400A26D6E5A000002FF130E15EF6DECE01ED97F01141C15C70281EBF03CD93F
+8314381583D91FC36D5AECC701A2D90FE76D5AECEE00A2D907FEEBFFC04A137FA201035D
+4A133FA2010192C7FC4A7FA20100141E4A130E37257EA33C>I<B500C0B5FCA300039038
+007FF06C48EB3F806C6C013EC7FC6D133CEB3F806E5A011F5B6D6C5A14F1903807FBC06D
+B45A6D90C8FCA26D5A147F818114FF497FECCFF0EB03C790380783F890380F03FCEB0E01
+90381E00FE497F496D7E01F8133F000181D80FFC497EB548B51280A329247FA32C>I<B5
+38C07FFEA33A07FC001FF06C48EB07C016807F00011500A26C6C130EA26D131E6D131CA2
+6D6C5AA2ECC078011F1370A2ECE0F0010F5B14F0903807F1C0A214FB01035BA26DB4C7FC
+A36D5AA2147CA31438A214781470A25CA21301007C5BEAFE035C130749C8FCEAFC1EEA78
+3CEA3FF86C5AEA0FC027357EA32C>I<003FB512FCA39038C007F8D83E0013F0003C130F
+EC1FE0003814C00078EB3F80147F0070EBFF005C1301495A5CEA0007495A5C495A133F90
+387F800E14005B485A5B0003141E485A5B4848131C001F143C4848137C4913FC007F1303
+B6FCA31F247EA325>I E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fl cmbx10 10 20
+/Fl 20 122 df<ED03E04B7EA24B7EA34B7EA24B7EA34B7EA292B57EA34A8015F7020380
+15E715E302078015C1020F801580A2021F80ED007F4A80023E133FA2027E80027C7F02FC
+814A7FA20101824A7F49B77EA34982A290270FC000017F4A7FA2011F8291C8127F498201
+3E153FA2017E82017C81B500F8010FB61280A5413A7DB948>65 D<B912F0A528007FFC00
+0113F8EE003F170F17071703A21701A21700A2163E18FC187CA4047E1300A216FE150391
+B5FCA5ECFC031500167E181F163EA2183EA493C7127EA2187C18FCA21701A21703EF07F8
+170F173FEE03FFB9FCA218F0A338397DB83F>69 D<B500FC0407B512F06E5E6E5EA3C66C
+6D4BEBE000A2017D6D157DA2017C6D15F9A36E6CEC01F1A26E6CEC03E1A26E6CEC07C1A3
+6E6CEC0F81A26E6CEC1F01A26E6D133EA36E6D137CA26E6D13F8A292397FF001F0A39239
+3FF803E0A292391FFC07C0A292390FFE0F80A3923907FF1F00A26F13BEA26F13FCA36F5B
+A2705AA2705AB500FE0303B612F0A2EE1FC0A2EE0F8054397DB85B>77
+D<B712FCEEFFE017FC17FF18C028007FFC000F7F04017F706C7E717EA2717EA284A76017
+3F604D5A4D5A4C5B040F5B91B7C8FC17FC5F17FE913AFC003FFF80040F7F707F82707FA2
+707FAB1AE0F101F0A2EF7FFC1AE0B600FE90383FFE0394381FFF0771EBFFC00503148005
+001400CBEA0FFC443A7DB848>82 D<EB3FFE0003B512E04814F84880391FF007FE393FF8
+01FF6E7F82157F6C4880A26C5AEA0380C8FCA291B5FC130F90B6FC0003EBF87F48138038
+1FFC00485A5B485A485AA515FF6C6C5A6C6C487F903AFC0FBFFFC06CB5123F0007497E6C
+EBF80F39007FC0032A257DA42E>97 D<13FFB5FCA512077EAEEDFF80020F13F8023F7F91
+B6FCDAFE031380DAF00013C002C0EB3FE04A14F091C7121F17F8A2EE0FFCA317FEA917FC
+A3EE1FF8A217F06EEB3FE06E137F02F0EBFFC09026FDFC07138001F8B5EAFE00023F5BD9
+F00F13F0D9E00190C7FC2F3A7EB935>I<903801FFC0010F13FC017F7F90B6FC48018013
+802607FE0113C0EA0FFC13F8EA1FF0003F6D1380A24848EB7F00151C92C7FC12FFA9127F
+7FA2123F6DEB03E0121F6C6CEB07C07F6C6CEB0F8000019038E03F006CEBFFFE6D5B010F
+13F00101138023257DA42A>I<EE7F80ED7FFFA5150381AEEB03FF011F13F1017F13FD48
+B7FC48EBC07F3907FE000F48487F484813015B123FA2485AA312FFA9127FA36C7EA2121F
+6D5B000F140FD807FE4913C06C6C6CB512FE6CEBFFFD6C6C13F9011F13C1903803FE012F
+3A7DB935>I<49B47E011F13F0017F13FC90B57E0003903881FF803907FE007F4848EB3F
+C04848EB1FE05B003FEC0FF0A2485A16F8150712FF90B6FCA401E0C8FCA4127FA27F123F
+16F86C7E6C6C13016DEB03F06C6CEB07E00001EBE01F6C90B51280013F1400010F13FC01
+0013C025257DA42C>I<13FFB5FCA512077EAEED7FC0913803FFF84A7F021F7F91383F03
+FFDA7801138014F04A6C13C05C5CA391C7FCB3A2B5D8FC3F13FFA5303A7DB935>104
+D<13F0EA03FC487E487EA2481380A46C1300A26C5A6C5AEA00F090C7FCA813FF127FA512
+077EB3A7B512F8A5153B7DBA1B>I<13FFB5FCA512077EB3B3AAB512FCA5163A7DB91B>
+108 D<01FEEB7FC000FF903803FFF84A7F021F7F91383F03FFDA78011380000713F06C6C
+486C13C05C5CA391C7FCB3A2B5D8FC3F13FFA530257DA435>110
+D<903801FFC0010F13F8017F13FF90B67E0003018013E03A07FE003FF0D80FF8EB0FF800
+1F81491307003F81491303007F81A300FF1680A9007F1600A36C6C495AA2001F5D6D130F
+6C6C495A6C6C495A6C6C6CB45A6C90B55A6C6C91C7FC011F13FC010113C029257DA430>
+I<01FFEBFF80B5000F13F8023F7F91B6FCDAFE071380DAF00113C000039039C0007FE04A
+14F091C7123F17F8161F17FCA2160F17FEA917FC161FA217F8163F17F06EEB7FE06E13FF
+DAF00113C0DAFC07138091B5EAFE00023F5B020F13F0020190C7FC91C9FCABB512FCA52F
+357EA435>I<9038FE07F000FFEB1FFC4A7E4A7E02F8138002E113C0EA07FF6C13C1A202
+801380A2ED7F00151C91C8FCB3B512FEA522257EA427>114 D<90383FF0383903FFFEF8
+4813FF121F383FC00FEB0003007E1301140012FEA27E6D130013F8EBFFE06C13FC14FF6C
+14C06C14E06C14F0000314F8C614FC131F9038007FFE14070078130112F814007EA26C14
+FC6C1301018013F89038F00FF090B512E000FD14C000F0140038E01FF81F257DA426>I<
+131FA55BA45BA25BA25A5A5A001FEBFFE0B6FCA4000390C7FCB115F8A86CEB01F014816C
+EBC3E090387FFFC06D13806D1300EB03FC1D357EB425>I<B539F01FFFF0A500019039C0
+07F0006C5D6D6C485A6D6C485AECF83F6D6C48C7FC010F13FE6DB45A6D5B5D6D5B7F147F
+6E7E814A7E14FF497F903803FBFFD907F37F02E17FEB0FC049486C7E013F6D7ED97F007F
+01FE6D7E49130FB539803FFFF8A52D257EA432>120 D<B539F003FFF8A5000390C7EA3E
+006E137E6C157C6E13FC6C5DECE001017F5CA2ECF003013F5CECF807011F5CECFC0F010F
+5C151FD907FE90C7FCA26E5A6D133E15FE6D5BA26D5BA36E5AA26E5AA26E5AA26E5AA214
+1F92C8FC5C003F133E387F807E38FFC07C14FC5CEAF80138FC07F0387E1FE0387FFFC06C
+90C9FC6C5AEA07F02D357EA432>I E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 440 531 a Fl(Accen)m(ts)84 b Fk(This)39 b(demonstrates)e(the)j
+(extended)g(seman)n(tics)d(of)i Fj(\\mathaccent)p Fk(.)68
+b(The)440 631 y(\014rst)24 b(ro)n(w)f(uses)h(an)g(accen)n(t)f(whose)h
+Fj(charlist)d Fk(ends)j(with)g(an)g Fj(extensible)39
+b(recipe)p Fk(,)23 b(the)440 731 y(second)k(uses)g(a)g(traditional)d
+Fj(charlist)p Fk(.)1518 878 y Fi(\020)-45 b Fh(a)1598
+856 y Fi(\021)1591 878 y Fh(ab)1696 856 y Fi(\024\025)1698
+878 y Fh(abc)1833 856 y Fi(\024\024)q(\024\024)q(\025)1841
+878 y Fh(abcd)2020 856 y Fi(\024)q(\024\024)q(\024\024\024)q(\025)2028
+878 y Fh(abcde)1518 1025 y Fi(\030)g Fh(a)1598 1003 y
+Fi(\031)1591 1025 y Fh(ab)1705 1003 y Fi(\033)1698 1025
+y Fh(abc)1870 1003 y Fi(\033)1841 1025 y Fh(abcd)2076
+1003 y Fi(\033)2028 1025 y Fh(abcde)565 1153 y Fk(Nested)28
+b(accen)n(ts)f(and)h(under)f(accen)n(ts)h(with)f Fj(\\nestingmathacce)o
+(nt)p Fk(,)22 b Fj(\\mathunder)p Fk(-)440 1252 y Fj(accent)32
+b Fk(and)i Fj(\\nestingmathunder)o(ac)o(cen)o(t)p Fk(.)51
+b(The)34 b(p)r(ositioning)d(information)g(for)j(the)440
+1352 y(under)25 b(accen)n(ts)f(is)g(tak)n(en)g(from)g(the)h
+Fg(h)p Ff(skewchar)p Fg(i)p Fk(-)p Fg(h)p Ff(ac)l(c)l(ente)l(e)p
+Fg(i)i Fk(k)n(erning)c(and)i(the)g Fg(h)p Ff(ac)l(c)l(ent)p
+Fg(i)p Fk(-)440 1452 y Fg(h)p Ff(ac)l(c)l(ent)p Fg(i)j
+Fk(k)n(erning.)1519 1630 y Fi(\()1475 1651 y(\))g(\))1547
+1718 y(\()1704 1608 y(\()1704 1630 y(\()1660 1651 y(\))f(\))1731
+1718 y(\()1731 1740 y(\()1888 1608 y(\()1888 1630 y(\()1844
+1651 y(\))1824 1718 y(\()1824 1740 y(\()2004 1586 y(\()2004
+1608 y(\()2036 1630 y(\()1992 1651 y(\))2096 1586 y(\()2128
+1608 y(\()2128 1630 y(\()2084 1651 y(\))2188 1608 y(\()2220
+1630 y(\()2177 1651 y(\))2156 1718 y(\()2156 1740 y(\()440
+1871 y Fl(Radicals)83 b Fk(Generalized)24 b(radicals)h(with)i
+Fj(\\genradical)p Fk(.)1204 1962 y Fi(\000)p 1273 1962
+192 4 v 75 x Fh(a)1317 2013 y Fe(a)1353 1996 y Fd(a)1393
+2037 y Fh(bc)1503 1962 y Fi(\000)p 1572 1962 V 75 x Fh(a)1616
+2013 y Fe(a)1652 1996 y Fd(a)1692 2037 y Fh(bc)1764 1962
+y Fi(\017)1764 2011 y(d)p 1889 1966 V 1889 2037 a Fh(a)1933
+2013 y Fe(a)1969 1996 y Fd(a)2009 2037 y Fh(bc)2081 1966
+y Fi(\010)2178 1953 y(\007)2178 2003 y(d)p 2265 1953
+V 2265 2037 a Fh(a)2309 2013 y Fe(a)2345 1996 y Fd(a)2386
+2037 y Fh(bc)2457 1953 y Fi(\011)1681 2120 y(\003)p 1764
+2120 217 4 v 1774 2155 124 4 v 1774 2173 a(\000)p 1843
+2173 44 4 v 64 x Fh(a)1897 2155 y Fi(\012)1980 2120 y(\013)440
+2492 y Fl(Math)d(st)m(yle)83 b Fk(This)20 b(sample)f(sho)n(ws)g(that)j
+Fj(\\mathstyle)17 b Fk(k)n(eeps)j(trac)n(k)f(of)i(the)h(math)e(st)n
+(yle)440 2592 y(while)26 b(scanning)g(the)i(form)n(ula.)1218
+2776 y Fh(D)1311 2720 y(T)p 1299 2757 84 4 v 1299 2833
+a(T)1360 2809 y Fc(0)1392 2776 y Fh(D)p 1463 2710 95
+4 v 2 w(D)1534 2752 y Fc(0)1558 2776 y Fh(D)p 1558 2789
+72 4 v 1629 2702 a Fg(p)p 1698 2702 95 4 v 74 x Fh(D)1769
+2752 y Fc(0)1792 2776 y Fh(D)1863 2742 y Fe(S)1907 2717
+y Fd(S)r(S)1863 2797 y Fe(S)1907 2780 y Fb(0)1930 2812
+y Fd(S)r(S)2006 2800 y Fb(0)2062 2755 y Fi(\()2036 2776
+y Fh(D)2107 2752 y Fc(0)2130 2776 y Fh(D)85 b(T)12 b
+Fk(X)p Fh(T)e(T)565 2947 y Fk(And)19 b(here)e(is)h(the)g(list)f(of)h
+(all)e(math)i(st)n(yles,)h(activ)-5 b(ated)17 b(via)g
+Fj(\\displaystyle)p Fk(,)e Fj(\\cramped)p Fk(-)440 3046
+y Fj(displaystyle)p Fk(,)23 b(.)14 b(.)g(.)f(,)28 b Fj
+(\\scriptscriptstyl)o(e)p Fk(,)22 b Fj(\\crampedscripts)o(cr)o(ipt)o
+(st)o(yle)o Fk(.)1532 3212 y Fh(D)16 b(D)1688 3188 y
+Fc(0)1725 3212 y Fh(T)25 b(T)1860 3188 y Fc(0)1896 3212
+y Fe(S)14 b(S)1995 3195 y Fb(0)2029 3212 y Fd(S)r(S)e(S)r(S)2191
+3200 y Fb(0)565 3359 y Fk(The)31 b(follo)n(wing)d(displa)n(y)h(sho)n
+(ws)h(that)i Fj(\\fraction)c Fk(has)j(no)g(in\015uence)g(on)g(the)h(t)n
+(yp)r(e-)440 3459 y(setting.)1044 3622 y Fj(\\fraction{a+b\\ov)o(er)37
+b(c-d}={a+b\\over)h(c-d})1626 3789 y Fh(a)18 b Fk(+)g
+Fh(b)p 1626 3826 181 4 v 1626 3903 a(c)g Fg(\000)g Fh(d)1840
+3846 y Fk(=)1937 3789 y Fh(a)h Fk(+)f Fh(b)p 1937 3826
+V 1937 3903 a(c)h Fg(\000)f Fh(d)440 4085 y Fl(Extensible)41
+b(op)s(erators)83 b Fk(These)36 b(ha)n(v)n(e)g(not)g(b)r(een)i
+(implemen)n(ted)33 b(in)j(T)2859 4103 y(E)2905 4085 y(X)h(the)g(pro-)
+440 4185 y(gram,)26 b(since)g(this)i(turned)g(out)f(to)h(b)r(e)g(a)g
+(bit)f(complicated)e(\(the)j(limits)d(of)i(a)h Fj(mathop)d
+Fk(are)440 4285 y(p)r(ositioned)h(in)i(the)g(\014rst)h(pass)e(o)n(v)n
+(er)g(the)h Fj(mlist)p Fk(,)f(but)i(the)g(size)e(of)h(big)f(delimiters)
+d(is)j(not)440 4384 y(determined)35 b(un)n(til)g(the)j(second)e
+(pass\).)64 b(But)37 b(I)g(ha)n(v)n(e)f(done)h(some)e(macro)g(hac)n(k)n
+(ery)f(to)440 4484 y(sho)n(w)c(ho)n(w)g(this)g(w)n(ould)f(lo)r(ok)h
+(lik)n(e.)44 b(The)30 b(input)h(for)f(the)h(middle)e(in)n(tegral)e(w)n
+(as)j(\(after)h(a)440 4584 y(suitable)26 b(rede\014nition)f(of)i
+Fj(\\left)p Fk(\))848 4731 y Fj(\\left\\int\\limits)o(^{)o(\\in)o(ft)o
+(y}_)o({-)o(\\i)o(nft)o(y})o(...)o(\\r)o(ig)o(ht.)o(dx)886
+5016 y Fc(1)877 5032 y Fi(!)841 5220 y Fc(\0001)982 5122
+y Fh(abc)1098 5088 y Fe(a)1134 5063 y Fd(b)1160 5046
+y(d)1191 5029 y(e)1236 5122 y Fh(dx)1394 4885 y Fc(1)1389
+4917 y Fi(")1389 4963 y($)1389 5009 y($)1389 5055 y($)1389
+5101 y($)1389 5147 y($)1389 5194 y($)1389 5240 y(#)1368
+5350 y Fc(\0001)1500 4905 y Fa(0)1500 5052 y(B)1500 5101
+y(B)1500 5154 y(@)1614 4972 y Fh(a)112 b(b)97 b(c)92
+b(d)1614 5071 y(e)117 b(f)92 b(g)c(h)1614 5171 y(i)127
+b(j)99 b(k)85 b(l)1614 5271 y(m)e(n)g(o)88 b(p)2121 4905
+y Fa(1)2121 5052 y(C)2121 5101 y(C)2121 5154 y(A)2207
+5122 y Fh(dx)2339 5009 y Fi(")2339 5055 y($)2339 5101
+y($)2339 5147 y(#)2414 5030 y Fc(1)2414 5198 y(\0001)2550
+5122 y Fh(abc)2666 5088 y Fe(a)2702 5063 y Fd(b)2728
+5046 y(d)2759 5029 y(e)2803 5122 y Fh(dx)1851 5662 y
+Fk(1)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/systems/tex-extensions/clasen/examples/example3/example3.tex b/systems/tex-extensions/clasen/examples/example3/example3.tex
new file mode 100644
index 0000000000..f3f0cf68d6
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/example3.tex
@@ -0,0 +1,148 @@
+\documentclass[a4paper]{article}
+\usepackage{shortvrb}
+\MakeShortVerb{\|}
+\def\meta#1{$\langle${\normalfont\itshape#1}$\rangle$}
+
+\DeclareFontFamily{U}{tf}{\skewchar\font=42}
+\DeclareFontShape{U}{tf}{m}{n}{<5> tf5 <7> tf7 <10> tf10}{}
+\DeclareSymbolFont{newsym}{U}{tf}{m}{n}
+
+\begin{document}
+
+\paragraph*{Accents} This demonstrates the extended semantics of
+|\mathaccent|. The first row uses an accent whose |charlist| ends with
+an |extensible recipe|, the second uses a traditional |charlist|.
+
+\def\acca{\mathaccent"410 }
+\def\accb{\mathaccent"418 }
+
+\[\acca{a}\ \acca{ab}\ \acca{abc}\ \acca{abcd}\ \acca{abcde}\]
+\[\accb{a}\ \accb{ab}\ \accb{abc}\ \accb{abcd}\ \accb{abcde}\]
+
+Nested accents and under accents with |\nesting|\-|math|\-|accent|,
+|\math|\-|under|\-|accent| and |\nesting|\-|math|\-|under|\-|accent|. The
+positioning information for the under accents is taken from the
+\meta{skewchar}-\meta{accentee} kerning and the \meta{accent}-\meta{accent}
+kerning.
+
+\def\hat{\mathaccent"0428 }
+\def\uhat{\mathunderaccent"0428 }
+\def\Hat{\nestingmathaccent"0428 }
+\def\uHat{\nestingmathunderaccent"0428 }
+\mathcode`A="0429
+
+\[
+\hat A\ \uhat A\ \Hat{\Hat A}\ \uHat{\uHat A}\ \Hat{\uHat{\Hat{\uHat A}}}
+\quad
+\Hat{\hat {\Hat A}}\ \hat{\Hat {\Hat A}}\ \uHat{\hat{\uHat{\hat A}}}\
+\]
+
+\paragraph*{Radicals} Generalized radicals with |\genradical|.
+\def\radl{\genradical"400401 "4FF4FF }
+\def\radlx{\genradical"400401 "40F40F }
+\def\radr{\genradical"4FF4FF "408409 }
+\def\radrx{\genradical"407407 "408409 }
+\def\radlr{\genradical"400401 "408409 }
+
+\[\radl{a^{a^a}bc}\ \radlx{a^{a^a}bc}\ \radr{a^{a^a}bc}\ \radrx{a^{a^a}bc}\]
+\[\radlr{\radr{\radl{a}}}\]
+
+\paragraph*{Math style} This sample shows that |\mathstyle| keeps track of the
+math style while scanning the formula.
+
+\def\sh{%
+ \ifnum\the\mathstyle<0 X\else
+ \ifcase\the\mathstyle D\or D'\or T\or T'\or S\or S'\or SS\or SS'
+ \else !!\the\mathstyle!!\fi
+ \fi}
+
+\[
+\sh\fraction{\sh\over\sh}\sh\overline{\sh}\underline{\sh}\sqrt{\sh}\sh
+{}^{{\sh}^{\sh}}_{{\sh}_{\sh}}\hat{\sh}\sh\quad\textstyle\sh\hbox{\sh$\sh$}\sh
+\]
+
+And here is the list of all math styles, activated via
+|\displaystyle|, |\cramped|\-|display|\-|style|, \dots,
+|\script|\-|script|\-|style|, |\cramped|\-|script|\-|script|\-|style|.
+
+\[
+\displaystyle\sh\,
+\crampeddisplaystyle\sh\,
+\textstyle\sh\,
+\crampedtextstyle\sh\,
+\scriptstyle\sh\,
+\crampedscriptstyle\sh\,
+\scriptscriptstyle\sh\,
+\crampedscriptscriptstyle\sh
+\]
+
+The following display shows that |\fraction| has no influence on the
+typesetting.
+
+\[\hbox{|\fraction{a+b\over c-d}={a+b\over c-d}|}\]
+
+\[\fraction{a+b\over c-d}={a+b\over c-d}\]
+
+
+\paragraph*{Extensible operators} These have not been implemented in \TeX{}
+the program, since this turned out to be a bit complicated (the limits of a
+|mathop| are positioned in the first pass over the |mlist|, but the size of
+big delimiters is not determined until the second pass). But I have done some
+macro hackery to show how this would look like. The input for the middle
+integral was (after a suitable redefinition of |\left|)
+\[\hbox{|\left\int\limits^{\infty}_{-\infty}...\right.dx|}\]
+
+\def\int{\mathchar"1420 }
+\let\ooleft\left
+\def\left{\futurelet\next\oint}
+\def\oint{%
+ \ifx\next\int
+ \let\next\ooint
+ \else
+ \let\next\ooleft
+ \fi
+ \next}
+\def\ooint\int{\def\isb{}\def\isp{}\let\li\limits\futurelet\next\oooint}
+\def\oooint{%
+ \ifx_\next
+ \let\next\getsb
+ \else
+ \ifx^\next
+ \let\next\getsp
+ \else
+ \ifx\next\limits
+ \let\next\eatlimits
+ \else
+ \ifx\next\nolimits
+ \let\next\eatlimits
+ \else
+ \let\next\ooooint
+ \fi
+ \fi
+ \fi
+ \fi
+ \next}
+\def\getsb_#1{\def\isb{#1}\futurelet\next\oooint}
+\def\getsp^#1{\def\isp{#1}\futurelet\next\oooint}
+\def\eatlimits#1{\let\li#1\futurelet\next\oooint}
+\def\ooooint#1\right.{%
+ \mathop{\nulldelimiterspace=0pt\ooleft\delimiter"4420420\vphantom{#1}\right.}%
+ \li_{\isb}^{\isp}#1}
+
+\[
+\int_{-\infty}^{\infty}abc^{a^{b^{d^e}}}dx\
+\left\int^{\infty}_{-\infty}
+\left(\begin{array}{llll}
+a&b&c&d\\
+e&f&g&h\\
+i&j&k&l\\
+m&n&o&p\\\end{array}\right)\right.dx\
+\left\int\nolimits_{-\infty}^{\infty}abc^{a^{b^{d^e}}}\right.dx
+\]
+
+\end{document}
+
+
+
+
+
diff --git a/systems/tex-extensions/clasen/examples/example3/tf.mf b/systems/tex-extensions/clasen/examples/example3/tf.mf
new file mode 100644
index 0000000000..831432b8af
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/tf.mf
@@ -0,0 +1,322 @@
+
+font_coding_scheme:="None";
+mode_setup; font_setup;
+
+
+def big_sqrt_refl =
+ adjust_fit(-letter_fit#,0); pickup rule.nib;
+ x1=good.x 5/9w; x2=good.x(-.5); bot y1=-d; bot y2=0;
+ draw z1--z2; % diagonal
+ pickup crisp.nib; pos3(max(curve,rule_thickness),0);
+ x3r=1.5[x2,x1]; y3=.5[y1,y2];
+ pos4(rule_thickness,0); x4=x1; bot y4=-d;
+ pos5(vair,45); x5r=good.x(x3r+u); z5r=whatever[z3l,z2];
+ z6=z5l+whatever*(z2-z3l)=whatever[z3r,z4r];
+ z7=whatever[z1,z2]=z3l+whatever*(z4r-z3r);
+ filldraw reverse z5l--z6--z4r--z4--z7--z3l--z5r--cycle; % left diagonal and serif
+ penlabels(1,2,3,4,5,6,7); enddef;
+
+numeric mikro; mikro=1.2(asc_height#-x_height#);
+
+def bar_or_vector(expr lh, rh, sol, sor) =
+italcorr .7[x_height#,asc_height#]*slant;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround if sol: -.5u else: .5u fi;
+rt x2=hround if sor: (w+.5u) else: (w-.5u) fi;
+y1=y2=good.y .7[x_height,asc_height];
+draw z1--z2; % bar
+if rh:
+rt x3=rt x4=hround(x2-u);
+y3=y2+.3(asc_height-x_height); y4=y2-.3(asc_height-x_height);
+draw z3{x2-x3,2(y2-y3)}...{2(x2-x3),y2-y3}z2; % upper point
+draw z4{x2-x4,2(y2-y4)}...{2(x2-x4),y2-y4}z2; % lower point
+fi;
+if lh:
+lft x5=lft x6=hround(x1+u);
+y5=y1+.3(asc_height-x_height); y6=y1-.3(asc_height-x_height);
+draw z5{x1-x5,2(y1-y5)}...{2(x1-x5),y1-y5}z1; % upper point
+draw z6{x1-x6,2(y1-y6)}...{2(x1-x6),y1-y6}z1; % lower point
+fi;
+labels(1,2,3,4);
+enddef;
+
+def big_bar = bar_or_vector(false,false,false,false); enddef;
+def big_vector = bar_or_vector(false,true,false,false); enddef;
+def big_backvector = bar_or_vector(true,false,false,false); enddef;
+
+
+charlist 1: 2: 3: 4: 5;
+charlist 9: 10: 11: 12: 13;
+extensible 5: 7, 0, 5, 6;
+extensible 7: 7, 0, 0, 100;
+extensible 13: 15, 0, 13, 14;
+extensible 15: 15, 0, 0, 100;
+charlist 16: 17: 18: 19: 21;
+charlist 24: 25: 26: 27;
+extensible 21: 0, 0, 21, 20;
+charlist 32: 33: 34;
+extensible 34: 34, 0, 35, 36;
+
+cmchar "\textsize radical sign";
+beginchar(0,15u#,rule_thickness#,10/6dh#-rule_thickness#);
+big_sqrt; endchar;
+
+cmchar "\big radical sign";
+beginchar(1,18u#,rule_thickness#,2dh#-rule_thickness#);
+big_sqrt; endchar;
+
+cmchar "\Big radical sign";
+beginchar(2,18u#,rule_thickness#,3dh#-rule_thickness#);
+big_sqrt; endchar;
+
+cmchar "\bigg radical sign";
+beginchar(3,18u#,rule_thickness#,4dh#-rule_thickness#);
+big_sqrt; endchar;
+
+cmchar "\Bigg radical sign";
+beginchar(4,18u#,rule_thickness#,5dh#-rule_thickness#);
+big_sqrt; endchar;
+
+cmchar "Extensible radical sign---bottom";
+beginchar(5,19u#,0,3dh#);
+adjust_fit(0,-letter_fit#); pickup rule.nib;
+x1=x2=good.x(w-6u); bot y1=1-d; y2=h+eps;
+draw z1--z2; % diagonal
+pickup crisp.nib; pos3(max(curve,rule_thickness),0);
+x3l=good.x 3u; y3=.9[y1,y2];
+pos4(rule_thickness,0); x4=x1; bot y4=-d;
+pos5(vair,-45); x5l=good.x(x3l-u); z5l=whatever[z3r,(x2,body_height)];
+z6=z5r+whatever*((x2,body_height)-z3r)=whatever[z3l,z4l];
+z7=whatever[z1,z2]=z3r+whatever*(z4l-z3l);
+filldraw z5r--z6--z4l--z4--z7--z3r--z5l--cycle; % left diagonal and serif
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Extensible radical sign---extension module";
+beginchar(6,19u#,0,dh#);
+adjust_fit(0,-letter_fit#); pickup rule.nib;
+x1=x2=good.x(w-6u); y1=-d-eps; y2=h+eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+cmchar "Extensible radical sign---top";
+beginchar(7,19u#,rule_thickness#,dh#-rule_thickness#);
+adjust_fit(0,-letter_fit#); pickup rule.nib;
+x1=x2=good.x(w-6u); x3=good.x(w+.5); y1=-d-eps; bot y2=bot y3=0;
+draw z1--z2--z3; % stem and link
+labels(1,2,3); endchar;
+
+cmchar "\textsize reflected radical sign";
+beginchar(8,15u#,rule_thickness#,10/6dh#-rule_thickness#);
+big_sqrt_refl; endchar;
+
+cmchar "\big reflected radical sign";
+beginchar(9,18u#,rule_thickness#,2dh#-rule_thickness#);
+big_sqrt_refl; endchar;
+
+cmchar "\Big reflected radical sign";
+beginchar(10,18u#,rule_thickness#,3dh#-rule_thickness#);
+big_sqrt_refl; endchar;
+
+cmchar "\bigg reflected radical sign";
+beginchar(11,18u#,rule_thickness#,4dh#-rule_thickness#);
+big_sqrt_refl; endchar;
+
+cmchar "\Bigg reflected radical sign";
+beginchar(12,18u#,rule_thickness#,5dh#-rule_thickness#);
+big_sqrt_refl; endchar;
+
+cmchar "Extensible reflected radical sign---bottom";
+beginchar(13,19u#,0,3dh#);
+adjust_fit(-letter_fit#,0); pickup rule.nib;
+x1=x2=good.x(6u); bot y1=1-d; y2=h+eps;
+draw z1--z2; % diagonal
+pickup crisp.nib; pos3(max(curve,rule_thickness),0);
+x3l=good.x (w-3u); y3=.9[y1,y2];
+pos4(rule_thickness,0); x4=x1; bot y4=-d;
+pos5(vair,45); x5r=good.x(x3r+u); z5r=whatever[z3l,(x2,body_height)];
+z6=z5l+whatever*((x2,body_height)-z3l)=whatever[z3r,z4r];
+z7=whatever[z1,z2]=z3l+whatever*(z4r-z3r);
+filldraw z5l--z6--z4r--z4--z7--z3l--z5r--cycle; % left diagonal and serif
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Extensible reflected radical sign---extension module";
+beginchar(14,19u#,0,dh#);
+adjust_fit(-letter_fit#,0); pickup rule.nib;
+x1=x2=good.x(6u); y1=-d-eps; y2=h+eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+cmchar "Extensible reflected radical sign---top";
+beginchar(15,19u#,rule_thickness#,dh#-rule_thickness#);
+adjust_fit(-letter_fit#,0); pickup rule.nib;
+x1=x2=good.x(6u); x3=good.x(-.5); y1=-d-eps; bot y2=bot y3=0;
+draw z1--z2--z3; % stem and link
+labels(1,2,3); endchar;
+
+
+cmchar "Wide vector accent 1";
+beginchar(16,10u#,body_height#,0);
+big_vector; endchar;
+
+cmchar "Wide vector accent 2";
+beginchar(17,14u#,body_height#,0);
+big_vector; endchar;
+
+cmchar "Wide vector accent 3";
+beginchar(18,18u#,body_height#,0);
+big_vector; endchar;
+
+cmchar "Wide vector accent 4";
+beginchar(19,22u#,body_height#+.05(mikro),0);
+big_vector; endchar;
+
+cmchar "Extensible wide vector accent -- middle piece";
+beginchar(20,4u#,body_height#+.05(mikro),0);
+bar_or_vector(false,false,true,true); endchar;
+
+cmchar "Extensible wide vector accent -- right piece";
+beginchar(21,22u#,body_height#+.05(mikro),0);
+bar_or_vector(false,true,true,false); endchar;
+
+cmchar "Wide reverse vector accent 1";
+beginchar(24,10u#,body_height#,0);
+big_backvector; endchar;
+
+cmchar "Wide reverse vector accent 2";
+beginchar(25,14u#,body_height#,0);
+big_backvector; endchar;
+
+cmchar "Wide reverse vector accent 3";
+beginchar(26,18u#,body_height#,0);
+big_backvector; endchar;
+
+cmchar "Wide reverse vector accent 4";
+beginchar(27,22u#,body_height#+.05(mikro),0);
+big_backvector; endchar;
+
+cmchar "Extensible radical sign -- empty repeater";
+beginchar(100,19u#,rule_thickness#,dh#-rule_thickness#);
+adjust_fit(0,-letter_fit#); endchar;
+
+cmchar "\textstyle integral sign";
+beginchar(32,11u#,0,100/54dh#);
+italcorr 3.5u#; % \TeX\ kerning between upper limit and lower limit
+adjust_fit(0,-ic#); pickup fine.nib;
+pos1(curve,0); pos2(hair,0); pos3(vair,90); pos4(curve,180);
+pos5(curve,180); pos5'(curve,0); z5'=z5; pos6(curve,0);
+pos7(vair,-90); pos8(hair,-180); pos9(curve,-180);
+rt x1r=hround(w-u); x9=w-x1; x7=w-x3=3u;
+x5=x4=x6; lft x5r=hround(.5w-.5curve);
+top y3r=0; bot y7r=-d; y9-.5curve=vround(top y7l+.25curve);
+y3-y1=y9-y7; y5=.5[y3,y7]=.5[y4,y6]; y4-y6=.6(y3-y7);
+bulb(3,2,1); bulb(7,8,9); % bulbs
+filldraw stroke z3e{left}...z4e{(z5e-z4e)xscaled 1.1}
+ ..tension atleast 1 and atleast .8..{z5-z4}z5e; % upper curve
+filldraw stroke z5'e{z6-z5}..tension atleast.8 and atleast 1
+ ..{(z6e-z5'e)xscaled 1.1}z6e...{left}z7e; % lower curve
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "\displaystyle integral sign";
+beginchar(33,14u#,0,150/54dh#);
+italcorr 4u#; % \TeX\ kerning between upper limit and lower limit
+adjust_fit(0,-ic#); pickup fine.nib;
+numeric bulb_size, max_size;
+bulb_size=hround(bold+dw); max_size=bold+dw;
+pos1(bulb_size,0); pos2(hair,0); pos3(vair,90); pos4(max_size,180);
+pos5(max_size,180); pos5'(max_size,0); z5'=z5; pos6(max_size,0);
+pos7(vair,-90); pos8(hair,-180); pos9(bulb_size,-180);
+rt x1r=hround(w-u); x9=w-x1; x7=w-x3=3u;
+x5=x4=x6; lft x5r=hround(.5w-.5curve);
+top y3r=0; bot y7r=-d;
+y9-.5bulb_size=vround(top y7l+.25bulb_size); y3-y1=y9-y7;
+y5=.5[y3,y7]=.5[y4,y6]; y4-y6=.6(y3-y7);
+bulb(3,2,1); bulb(7,8,9); % bulbs
+filldraw stroke z3e{left}...z4e{(z5e-z4e)xscaled 1.1}
+ ..tension atleast 1 and atleast .8..{z5-z4}z5e; % upper curve
+filldraw stroke z5'e{z6-z5}..tension atleast.8 and atleast 1
+ ..{(z6e-z5'e)xscaled 1.1}z6e...{left}z7e; % lower curve
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Extensible integral sign - top";
+beginchar(34,14u#,0,50/54dh#);
+italcorr 4u#; % \TeX\ kerning between upper limit and lower limit
+adjust_fit(0,-ic#); pickup fine.nib;
+numeric bulb_size, max_size;
+bulb_size=hround(bold+dw); max_size=bold+dw;
+pos1(bulb_size,0); pos2(hair,0); pos3(vair,90); pos4(max_size,180);
+pos5(max_size,180); pos5'(max_size,0); z5'=z5;
+pos7(vair,-90); pos8(hair,-180); pos9(bulb_size,-180);
+rt x1r=hround(w-u); w-x3=3u;
+x5=x4; lft x5r=hround(.5w-.5curve);
+top y3r=0; bot y5=-d; bot y7=-d;
+y9-.5bulb_size=vround(top y7l+.25bulb_size); y3-y1=y9-y7;
+y4=-.5d; bulb(3,2,1);
+filldraw stroke z3e{left}...z4e{(z5e-z4e)xscaled 1.1}
+ ..tension atleast 1 and atleast .8..{z5-z4}z5e; % upper curve
+penlabels(1,2,3,4,5); endchar;
+
+cmchar "Extensible integral sign - bot";
+beginchar(35,14u#,0,50/54dh#);
+italcorr 4u#; % \TeX\ kerning between upper limit and lower limit
+adjust_fit(0,-ic#); pickup fine.nib;
+numeric bulb_size, max_size;
+bulb_size=hround(bold+dw); max_size=bold+dw;
+pos1(bulb_size,0); pos2(hair,0); pos3(vair,90); pos4(max_size,180);
+pos5(max_size,180); pos5'(max_size,0); z5'=z5; pos6(max_size,0);
+pos7(vair,-90); pos8(hair,-180); pos9(bulb_size,-180);
+rt x1r=hround(w-u); x9=w-x1; x7=w-x3=3u;
+x5=x4=x6; lft x5r=hround(.5w-.5curve);
+top y3r=0; bot y7r=-d;
+y9-.5bulb_size=vround(top y7l+.25bulb_size); y3-y1=y9-y7;
+y6=-0.5d; y4=y5=0; bulb(7,8,9); % bulbs
+filldraw stroke z5'e{z6-z5}..tension atleast.8 and atleast 1
+ ..{(z6e-z5'e)xscaled 1.1}z6e...{left}z7e; % lower curve
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Extensible integral sign - rep";
+beginchar(36,14u#,0,50/54dh#);
+italcorr 4u#; % \TeX\ kerning between upper limit and lower limit
+adjust_fit(0,-ic#); pickup fine.nib;
+numeric max_size; max_size=bold+dw;
+pos4(max_size,0); pos6(max_size,0);
+x4=x6; lft x4l=hround(.5w-.5curve);
+y4=0; y6=-d;
+filldraw stroke z4e...z6e;
+penlabels(4,6);
+endchar;
+
+cmchar "Circumflex (hat) accent";
+beginchar(40,9u#,min(asc_height#,2x_height#),0);
+ adjust_fit(0,0);
+ pickup crisp.nib; pos2(.5[vair,curve],90); top y2r=h; x2=.5w;
+ x1=w-x3=good.x 2.25u; y1=y3=.5[x_height,y2];
+ pos1(hair,angle(z2-z1)+90); pos3(hair,angle(z3-z2)+90);
+ filldraw stroke z1e--z2e--z3e; % diagonals
+penlabels(0,1,2,3,4); endchar;
+
+cmchar "Example char";
+beginchar(41,14u#,asc_height#,0);
+ adjust_fit(0,0);
+ pickup rule.nib;
+ draw (0,0)--(w,h)--(0,h)--(0,0)--(w,0)--(w,h);
+endchar;
+
+cmchar "Example char";
+beginchar(42,14u#,asc_height#,0);
+ adjust_fit(0,0);
+ pickup rule.nib;
+ draw (0,0)--(w,h);
+endchar;
+
+
+
+
+
+font_x_height x_height#;
+font_quad 18u#+4letter_fit#;
+% (The calling file should give the other math extension font parameters.)
+
+ligtable 40: 40 kern 2u#;
+ligtable 41: 42 kern 7u#;
+ligtable 42: 41 kern 7u#;
+bye.
diff --git a/systems/tex-extensions/clasen/examples/example3/tf10.mf b/systems/tex-extensions/clasen/examples/example3/tf10.mf
new file mode 100644
index 0000000000..f017218994
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/tf10.mf
@@ -0,0 +1,83 @@
+if unknown cmbase: input cmbase fi
+
+font_identifier:="TF"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+% the following font parameters are explained in {\sl The \TeX book}, Appendix G
+fontdimen 8: % parameters $\xi_8$ through $\xi_{13}$ will now be listed
+ rule_thickness#, % default\_rule\_thickness
+ 40/36pt#, % big\_op\_spacing1
+ 60/36pt#, % big\_op\_spacing2
+ 72/36pt#, % big\_op\_spacing3
+ 216/36pt#, % big\_op\_spacing4
+ 36/36pt#; % big\_op\_spacing5
+
+generate tf % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example3/tf5.mf b/systems/tex-extensions/clasen/examples/example3/tf5.mf
new file mode 100644
index 0000000000..d7876198e2
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/tf5.mf
@@ -0,0 +1,83 @@
+if unknown cmbase: input cmbase fi
+
+font_identifier:="TF"; font_size 5pt#;
+
+u#:=12.5/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=2/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=10/36pt#; % extra space added to all sidebars
+
+body_height#:=135/36pt#; % height of tallest characters
+asc_height#:=125/36pt#; % height of lowercase ascenders
+cap_height#:=123/36pt#; % height of caps
+fig_height#:=116/36pt#; % height of numerals
+x_height#:=77.5/36pt#; % height of lowercase without ascenders
+math_axis#:=45/36pt#; % axis of symmetry for math symbols
+bar_height#:=43.5/36pt#; % height of crossbar in lowercase e
+comma_depth#:=35/36pt#; % depth of comma below baseline
+desc_depth#:=35/36pt#; % depth of lowercase descenders
+
+crisp#:=0/36pt#; % diameter of serif corners
+tiny#:=6/36pt#; % diameter of rounded corners
+fine#:=5/36pt#; % diameter of sharply rounded corners
+thin_join#:=5/36pt#; % width of extrafine details
+hair#:=7.5/36pt#; % lowercase hairline breadth
+stem#:=16/36pt#; % lowercase stem breadth
+curve#:=18/36pt#; % lowercase curve breadth
+ess#:=12/36pt#; % breadth in middle of lowercase s
+flare#:=19/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=22/36pt#; % diameter of dots
+cap_hair#:=8/36pt#; % uppercase hairline breadth
+cap_stem#:=20/36pt#; % uppercase stem breadth
+cap_curve#:=22/36pt#; % uppercase curve breadth
+cap_ess#:=15/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.28pt#; % thickness of lines in math symbols
+
+dish#:=.7/36pt#; % amount erased at top or bottom of serifs
+bracket#:=10/36pt#; % vertical distance from serif base to tangent
+jut#:=15.5/36pt#; % protrusion of lowercase serifs
+cap_jut#:=20/36pt#; % protrusion of uppercase serifs
+beak_jut#:=6/36pt#; % horizontal protrusion of beak serifs
+beak#:=35/36pt#; % vertical protrusion of beak serifs
+vair#:=6/36pt#; % vertical diameter of hairlines
+notch_cut#:=5pt#; % maximum breadth above or below notches
+bar#:=8/36pt#; % lowercase bar thickness
+slab#:=8/36pt#; % serif and arm thickness
+cap_bar#:=8/36pt#; % uppercase bar thickness
+cap_band#:=8/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=5pt#; % max breadth above/below uppercase notches
+serif_drop#:=2/36pt#; % vertical drop of sloped serifs
+stem_corr#:=.7/36pt#; % for small refinements of stem breadth
+vair_corr#:=.5/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=4/36pt#; % amount of overshoot for curves
+apex_o#:=4/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=1; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=1; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+%the following font parameters are explained in {\sl The \TeX book}, Appendix G
+fontdimen 8: % parameters $\xi_8$ through $\xi_{13}$ will now be listed
+rule_thickness#, % default \_rule\_thickness
+20/36pt#, % big\_op\_spacing1
+30/36pt#, % big\_op\_spacing2
+36/36pt#, % big\_op\_spacing3
+110/36pt#, % big\_op\_spacing4
+25.71/36pt#; % big\_op\_spacing5
+
+generate tf % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example3/tf7.mf b/systems/tex-extensions/clasen/examples/example3/tf7.mf
new file mode 100644
index 0000000000..0cdb4ec733
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example3/tf7.mf
@@ -0,0 +1,83 @@
+if unknown cmbase: input cmbase fi
+
+font_identifier:="TF"; font_size 7pt#;
+
+u#:=15.5/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=3.5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=4/36pt#; % extra space added to all sidebars
+
+body_height#:=189/36pt#; % height of tallest characters
+asc_height#:=175/36pt#; % height of lowercase ascenders
+cap_height#:=172.2/36pt#; % height of caps
+fig_height#:=162.4/36pt#; % height of numerals
+x_height#:=108.5/36pt#; % height of lowercase without ascenders
+math_axis#:=63/36pt#; % axis of symmetry for math symbols
+bar_height#:=60.9/36pt#; % height of crossbar in lowercase e
+comma_depth#:=49/36pt#; % depth of comma below baseline
+desc_depth#:=49/36pt#; % depth of lowercase descenders
+
+crisp#:=0/36pt#; % diameter of serif corners
+tiny#:=7/36pt#; % diameter of rounded corners
+fine#:=6/36pt#; % diameter of sharply rounded corners
+thin_join#:=6/36pt#; % width of extrafine details
+hair#:=8.5/36pt#; % lowercase hairline breadth
+stem#:=20/36pt#; % lowercase stem breadth
+curve#:=23/36pt#; % lowercase curve breadth
+ess#:=21/36pt#; % breadth in middle of lowercase s
+flare#:=24/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=29/36pt#; % diameter of dots
+cap_hair#:=9/36pt#; % uppercase hairline breadth
+cap_stem#:=25/36pt#; % uppercase stem breadth
+cap_curve#:=28/36pt#; % uppercase curve breadth
+cap_ess#:=24/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.34pt#; % thickness of lines in math symbols
+
+dish#:=.9/36pt#; % amount erased at top or bottom of serifs
+bracket#:=14/36pt#; % vertical distance from serif base to tangent
+jut#:=19.5/36pt#; % protrusion of lowercase serifs
+cap_jut#:=26/36pt#; % protrusion of uppercase serifs
+beak_jut#:=7.6/36pt#; % horizontal protrusion of beak serifs
+beak#:=49/36pt#; % vertical protrusion of beak serifs
+vair#:=7/36pt#; % vertical diameter of hairlines
+notch_cut#:=7pt#; % maximum breadth above or below notches
+bar#:=9/36pt#; % lowercase bar thickness
+slab#:=9/36pt#; % serif and arm thickness
+cap_bar#:=9/36pt#; % uppercase bar thickness
+cap_band#:=9/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=7pt#; % max breadth above/below uppercase notches
+serif_drop#:=2.8/36pt#; % vertical drop of sloped serifs
+stem_corr#:=.9/36pt#; % for small refinements of stem breadth
+vair_corr#:=.9/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=5/36pt#; % amount of overshoot for curves
+apex_o#:=5/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=.6; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+%the following font parameters are explained in {\sl The \TeX book}, Appendix G
+fontdimen 8: % parameters $\xi_8$ through $\xi_{13}$ will now be listed
+rule_thickness#, % default \_rule\_thickness
+28/36pt#, % big\_op\_spacing1
+42/36pt#, % big\_op\_spacing2
+50.4/36pt#, % big\_op\_spacing3
+154/36pt#, % big\_op\_spacing4
+36/36pt#; % big\_op\_spacing5
+
+generate tf % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example4/Adiff1.gif b/systems/tex-extensions/clasen/examples/example4/Adiff1.gif
new file mode 100644
index 0000000000..7a138bc2a7
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/Adiff1.gif
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example4/Idiff1.gif b/systems/tex-extensions/clasen/examples/example4/Idiff1.gif
new file mode 100644
index 0000000000..485fe33ce8
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/Idiff1.gif
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example4/Tdiff1.gif b/systems/tex-extensions/clasen/examples/example4/Tdiff1.gif
new file mode 100644
index 0000000000..9d979ae35b
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/Tdiff1.gif
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example4/example4.dvi b/systems/tex-extensions/clasen/examples/example4/example4.dvi
new file mode 100644
index 0000000000..8edea08af3
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/example4.dvi
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example4/example4.log b/systems/tex-extensions/clasen/examples/example4/example4.log
new file mode 100644
index 0000000000..87202f1d9e
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/example4.log
@@ -0,0 +1,332 @@
+This is TeX, Version 3.14159 (with experimental extensions) (Web2C 7.2) (format=latex 1998.7.24) 24 JUL 1998 16:39
+**&../latex example4
+(example4.tex
+LaTeX2e <1997/12/01> patch level 1
+Babel <v3.6h> and hyphenation patterns for american, german, loaded.
+(/usr/local/share/texmf/tex/latex/base/article.cls
+Document Class: article 1997/10/10 v1.3x Standard LaTeX document class
+(/usr/local/share/texmf/tex/latex/base/size10.clo
+File: size10.clo 1997/10/10 v1.3x Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+) (example4.aux)
+\openout1 = `example4.aux'.
+
+LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 68.
+LaTeX Font Info: ... okay on input line 68.
+LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 68.
+LaTeX Font Info: ... okay on input line 68.
+LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 68.
+LaTeX Font Info: ... okay on input line 68.
+LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 68.
+LaTeX Font Info: ... okay on input line 68.
+LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 68.
+LaTeX Font Info: ... okay on input line 68.
+LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 68.
+LaTeX Font Info: ... okay on input line 68.
+47.71527 -!-> 221.0
+(adjust_excess: 4.63164 --> 00000000
+ got 0.0) Original173.13927 -!-> 193.77815
+(adjust_excess: 1.1192 --> 0000000000000000000000000000000000000
+ got 0.0)171.52823 -!-> 196.55559
+(adjust_excess: 1.1459 --> 000000000000000000000000000000000000000
+ got 0.0)190.36148 -!-> 208.50005
+(adjust_excess: 1.09529 --> 0000000000000000000000000000000000000000
+ got 0.0)
+Underfull \hbox (badness 1675) in paragraph at lines 72--72
+\OT1/cmr/m/n/10 go-rithm, nev-er-the-less im-prove-ments seem pos-
+ []
+
+135.77808 -!-> 196.83337
+(adjust_excess: 1.44968 --> 0000000000000000000000000000000
+ got 0.0)
+Underfull \hbox (badness 6204) in paragraph at lines 72--72
+\OT1/cmr/m/n/10 si-ble. As you will note, I stuffed this
+ []
+
+215.38943 -!-> 214.88892
+(adjust_excess: 0.99768 --> 000000000000000000000000000000000000000000
+ got 0.0)189.11159 -!-> 198.50006
+(adjust_excess: 1.04965 --> 000000000000000000000000000000000000000
+ got 0.0)210.50049 -!-> 211.83337
+(adjust_excess: 1.00633 --> 0000000000000000000000000000000000000000
+ got 0.0)195.36162 -!-> 199.05563
+(adjust_excess: 1.0189 --> 000000000000000000000000000000000000000
+ got 0.0)174.58379 -!-> 218.7778
+(adjust_excess: 1.25314 --> 000000000000000000000000000000000000
+ got 0.0)82.31111 -!-> 217.625
+(adjust_excess: 2.64394 --> 0000000000000
+ got 0.0) 3 variants(fontvariants of cmr10: cmr10, hz3cmr10)(fontvariants of cm
+r10: hz4cmr10, cmr10, hz3cmr10)173.13927 -!-> 193.77815
+(adjust_excess: 1.1192 --> 0000000000000000000000000000000000000
+ got 3.45796)171.52823 -!-> 196.55559
+(adjust_excess: 1.1459 --> 000000000000000000000000000000000000000
+ got 3.42564)190.36148 -!-> 208.50005
+(adjust_excess: 1.09529 --> 0000000000000000000000000000000000000000
+ got 3.80806)135.77808 -!-> 196.83337
+(adjust_excess: 1.44968 --> 0000000000000000000000000000000
+ got 2.70496)
+Underfull \hbox (badness 5417) in paragraph at lines 76--76
+\4 si\n -\4 ble. As you will note, I stu\n ff\4 ed this
+ []
+
+215.38943 -!-> 214.88892
+(adjust_excess: 0.99768 --> 111121111121111112111111112111111121111211
+ got -0.52235)189.11159 -!-> 198.50006
+(adjust_excess: 1.04965 --> 000000000000000000000000000000000000000
+ got 3.78302)210.50049 -!-> 211.83337
+(adjust_excess: 1.00633 --> 1011011011102110110110110101101100110110
+ got 1.33641)195.36162 -!-> 199.05563
+(adjust_excess: 1.0189 --> 000000001000000000000000010000000000000
+ got 3.7135)174.58379 -!-> 218.7778
+(adjust_excess: 1.25314 --> 000000000000000000000000000000000000
+ got 3.49234)73.10974 -!-> 218.0
+(adjust_excess: 2.98181 --> 000000000000
+ got 0.0) 5 variants(fontvariants of cmr10: hz4cmr10, cmr10, hz3cmr10, hz2cmr10
+)(fontvariants of cmr10: hz4cmr10, cmr10, hz3cmr10, hz2cmr10)(fontvariants of c
+mr10: hz4cmr10, cmr10, hz3cmr10, hz2cmr10)(fontvariants of cmr10: hz5cmr10, hz4
+cmr10, cmr10, hz3cmr10, hz2cmr10)173.13927 -!-> 193.77815
+(adjust_excess: 1.1192 --> 0000000000000000000000000000000000000
+ got 6.91344)171.52823 -!-> 196.55559
+(adjust_excess: 1.1459 --> 000000000000000000000000000000000000000
+ got 6.84897)197.08371 -!-> 208.50005
+(adjust_excess: 1.05792 --> 000000000000000000000000000000000000000000
+ got 7.88216)183.55598 -!-> 193.50005
+(adjust_excess: 1.05417 --> 000000000000000000000000000000000000000
+ got 7.31888)220.72278 -!-> 212.11116
+(adjust_excess: 0.96098 --> 44444444344444444444434444444444444434444444
+ got -8.63828)170.44489 -!-> 198.22227
+(adjust_excess: 1.16296 --> 00000000000000000000000000000000000
+ got 6.81673)204.63936 -!-> 215.72227
+(adjust_excess: 1.05415 --> 000000000000000000000000000000000000000
+ got 8.18428)160.05597 -!-> 198.50006
+(adjust_excess: 1.24019 --> 00000000000000000000000000000000
+ got 6.40118)
+Underfull \hbox (badness 2065) in paragraph at lines 80--80
+\5 ments that can be had by al\n -\5 low\n -\5 ing font\n ---
+ []
+
+174.58379 -!-> 218.7778
+(adjust_excess: 1.25314 --> 000000000000000000000000000000000000
+ got 6.98225)82.03334 -!-> 218.0
+(adjust_excess: 2.65746 --> 0000000000000
+ got 0.0) 7 variants(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3cmr10
+, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3cmr1
+0, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3cmr
+10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3cm
+r10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3c
+mr10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz6cmr10, hz5cmr10, hz4cmr10,
+cmr10, hz3cmr10, hz2cmr10, hz1cmr10)210.66714 -!-> 193.77815
+(adjust_excess: 0.91983 --> 666666666666666666666666666666666666666666666
+ got -12.62292)208.7783 -!-> 196.83337
+(adjust_excess: 0.94278 --> 66665666656666656666665666666566656665666656666
+ got -11.96954)202.63928 -!-> 194.05562
+(adjust_excess: 0.95764 --> 55556555565555555565555565555565555655555565
+ got -8.57765)223.00055 -!-> 214.88892
+(adjust_excess: 0.96362 --> 55545555455545555545555455554555455545555454
+ got -8.05693)202.13942 -!-> 198.50006
+(adjust_excess: 0.982 --> 444443444444444434444444444344444434444444
+ got -3.68808)210.19495 -!-> 212.11116
+(adjust_excess: 1.00911 --> 3223233232323232432323323232332323232232
+ got 1.98596)189.5838 -!-> 198.77785
+(adjust_excess: 1.0485 --> 10101011101011011010110101010110010201
+ got 9.19914)202.08386 -!-> 219.05559
+(adjust_excess: 1.08398 --> 00000000000000000000000000000000000000000
+ got 12.12448)124.34447 -!-> 213.5
+(adjust_excess: 1.71701 --> 00000000000000000000
+ got 0.0) 7* variants(fontvariants of hz6cmr10: hz6cmr10, hz1cmr10)(fontvariant
+s of hz6cmr10: hz6cmr10, hz2cmr10, hz1cmr10)(fontvariants of hz6cmr10: hz6cmr10
+, hz3cmr10, hz2cmr10, hz1cmr10)(fontvariants of hz6cmr10: hz6cmr10, cmr10, hz3c
+mr10, hz2cmr10, hz1cmr10)(fontvariants of hz6cmr10: hz6cmr10, hz4cmr10, cmr10,
+hz3cmr10, hz2cmr10, hz1cmr10)(fontvariants of hz6cmr10: hz6cmr10, hz5cmr10, hz4
+cmr10, cmr10, hz3cmr10, hz2cmr10, hz1cmr10)223.29002 -!-> 193.37817
+(adjust_excess: 0.86604 --> 666666666666666666666666666666666666666666666
+ got -25.2458)221.28767 -!-> 196.83337
+(adjust_excess: 0.8895 --> 66656666656666666665666656666666566665666566666
+ got -24.47389)214.76381 -!-> 194.05562
+(adjust_excess: 0.90358 --> 55556555556555555565555565555565555655555565
+ got -20.6855)236.38005 -!-> 214.88892
+(adjust_excess: 0.90909 --> 55545555455545555545555455554555455545555454
+ got -21.43643)214.26726 -!-> 198.50006
+(adjust_excess: 0.9264 --> 444443444444444434444444444344444434444444
+ got -15.81592)222.80621 -!-> 212.11116
+(adjust_excess: 0.952 --> 3223233232323232432323323232332323232232
+ got -10.6253)200.95839 -!-> 198.77785
+(adjust_excess: 0.98915 --> 10101011101011011010110101010110010201
+ got -2.17545)214.20834 -!-> 219.05559
+(adjust_excess: 1.02263 --> 00000000000000000000000000000000000000000
+ got 0.0)
+LaTeX Font Info: Try loading font information for OMS+cmtt on input line 91.
+
+LaTeX Font Info: No file OMScmtt.fd. on input line 91.
+
+
+LaTeX Font Warning: Font shape `OMS/cmtt/m/n' undefined
+(Font) using `OMS/cmsy/m/n' instead
+(Font) for symbol `textbackslash' on input line 91.
+
+178.76534 -!-> 212.0
+(adjust_excess: 1.18591 --> 00000000000000000000000000000
+ got 0.0) Original+es(fontvariants of cmr10: cmr10)223.29002 -!-> 193.37817
+(adjust_excess: 0.86604 --> 666666666666666666666666666666666666666666666
+ got -25.2458)221.28767 -!-> 196.83337
+(adjust_excess: 0.8895 --> 66656666656666666665666656666666566665666566666
+ got -24.47389)214.76381 -!-> 194.05562
+(adjust_excess: 0.90358 --> 55556555556555555565555565555565555655555565
+ got -20.6855)236.38005 -!-> 214.88892
+(adjust_excess: 0.90909 --> 55545555455545555545555455554555455545555454
+ got -21.43643)214.26726 -!-> 198.50006
+(adjust_excess: 0.9264 --> 444443444444444434444444444344444434444444
+ got -15.81592)222.80621 -!-> 212.11116
+(adjust_excess: 0.952 --> 3223233232323232432323323232332323232232
+ got -10.6253)200.95839 -!-> 198.77785
+(adjust_excess: 0.98915 --> 10101011101011011010110101010110010201
+ got -2.17545)214.20834 -!-> 219.05559
+(adjust_excess: 1.02263 --> 00000000000000000000000000000000000000000
+ got 0.0)213.36118 -!-> 208.625
+(adjust_excess: 0.9778 --> 0000000000000000000000000000000000
+ got 0.0) 3 variants+es(fontvariants of cmr10: cmr10, hz3cmr10)(fontvariants of
+ cmr10: hz4cmr10, cmr10, hz3cmr10)223.29002 -!-> 193.37817
+(adjust_excess: 0.86604 --> 666666666666666666666666666666666666666666666
+ got -25.2458)221.28767 -!-> 196.83337
+(adjust_excess: 0.8895 --> 66656666656666666665666656666666566665666566666
+ got -24.47389)214.76381 -!-> 194.05562
+(adjust_excess: 0.90358 --> 55556555556555555565555565555565555655555565
+ got -20.6855)236.38005 -!-> 214.88892
+(adjust_excess: 0.90909 --> 55545555455545555545555455554555455545555454
+ got -21.43643)214.26726 -!-> 198.50006
+(adjust_excess: 0.9264 --> 444443444444444434444444444344444434444444
+ got -15.81592)222.80621 -!-> 212.11116
+(adjust_excess: 0.952 --> 3223233232323232432323323232332323232232
+ got -10.6253)200.95839 -!-> 198.77785
+(adjust_excess: 0.98915 --> 10101011101011011010110101010110010201
+ got -2.17545)214.20834 -!-> 219.05559
+(adjust_excess: 1.02263 --> 00000000000000000000000000000000000000000
+ got 0.0)204.1598 -!-> 209.0
+(adjust_excess: 1.02371 --> 000000000000000000000000000000000
+ got 0.0) 5 variants+es(fontvariants of cmr10: hz4cmr10, cmr10, hz3cmr10, hz2cm
+r10)(fontvariants of cmr10: hz4cmr10, cmr10, hz3cmr10, hz2cmr10)(fontvariants o
+f cmr10: hz4cmr10, cmr10, hz3cmr10, hz2cmr10)(fontvariants of cmr10: hz5cmr10,
+hz4cmr10, cmr10, hz3cmr10, hz2cmr10)223.29002 -!-> 193.37817
+(adjust_excess: 0.86604 --> 666666666666666666666666666666666666666666666
+ got -25.2458)221.28767 -!-> 196.83337
+(adjust_excess: 0.8895 --> 66656666656666666665666656666666566665666566666
+ got -24.47389)214.76381 -!-> 194.05562
+(adjust_excess: 0.90358 --> 55556555556555555565555565555565555655555565
+ got -20.6855)236.38005 -!-> 214.88892
+(adjust_excess: 0.90909 --> 55545555455545555545555455554555455545555454
+ got -21.43643)214.26726 -!-> 198.50006
+(adjust_excess: 0.9264 --> 444443444444444434444444444344444434444444
+ got -15.81592)222.80621 -!-> 212.11116
+(adjust_excess: 0.952 --> 3223233232323232432323323232332323232232
+ got -10.6253)200.95839 -!-> 198.77785
+(adjust_excess: 0.98915 --> 10101011101011011010110101010110010201
+ got -2.17545)214.20834 -!-> 219.05559
+(adjust_excess: 1.02263 --> 00000000000000000000000000000000000000000
+ got 0.0)213.0834 -!-> 209.0
+(adjust_excess: 0.98083 --> 0000000000000000000000000000000000
+ got 0.0) 7 variants+es(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3cm
+r10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3c
+mr10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3
+cmr10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz
+3cmr10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz5cmr10, hz4cmr10, cmr10, h
+z3cmr10, hz2cmr10, hz1cmr10)(fontvariants of cmr10: hz6cmr10, hz5cmr10, hz4cmr1
+0, cmr10, hz3cmr10, hz2cmr10, hz1cmr10)223.29002 -!-> 193.37817
+(adjust_excess: 0.86604 --> 666666666666666666666666666666666666666666666
+ got -25.2458)221.28767 -!-> 196.83337
+(adjust_excess: 0.8895 --> 66656666656666666665666656666666566665666566666
+ got -24.47389)214.76381 -!-> 194.05562
+(adjust_excess: 0.90358 --> 55556555556555555565555565555565555655555565
+ got -20.6855)236.38005 -!-> 214.88892
+(adjust_excess: 0.90909 --> 55545555455545555545555455554555455545555454
+ got -21.43643)214.26726 -!-> 198.50006
+(adjust_excess: 0.9264 --> 444443444444444434444444444344444434444444
+ got -15.81592)222.80621 -!-> 212.11116
+(adjust_excess: 0.952 --> 3223233232323232432323323232332323232232
+ got -10.6253)200.95839 -!-> 198.77785
+(adjust_excess: 0.98915 --> 10101011101011011010110101010110010201
+ got -2.17545)214.20834 -!-> 219.05559
+(adjust_excess: 1.02263 --> 00000000000000000000000000000000000000000
+ got 0.0)97.12222 -!-> 213.125
+(adjust_excess: 2.1944 --> 000000000000000
+ got 0.0)(fontvariants of cmr10: cmr10)172.94298 -!-> 220.70009
+(adjust_excess: 1.27614 --> 0000000000000000000000000000000000000000
+ got 0.0)gw=0
+gw=0
+gw=0
+[1
+
+]176.6204 -!-> 220.80011
+(adjust_excess: 1.25014 --> 0000000000000000000000000000000000000000
+ got 0.0)180.29517 -!-> 220.90005
+(adjust_excess: 1.22522 --> 0000000000000000000000000000000000000000
+ got 0.0)183.9726 -!-> 221.00008
+(adjust_excess: 1.20126 --> 0000000000000000000000000000000000000000
+ got 0.0)187.65002 -!-> 221.1001
+(adjust_excess: 1.17825 --> 0000000000000000000000000000000000000000
+ got 0.0)191.32483 -!-> 221.20004
+(adjust_excess: 1.15614 --> 0000000000000000000000000000000000000000
+ got 0.0)195.00224 -!-> 221.30006
+(adjust_excess: 1.13486 --> 0000000000000000000000000000000000000000
+ got 0.0)142.26807 -!-> 207.875
+(adjust_excess: 1.46115 --> 00000000000000000000000
+ got 0.0)(fontvariants of cmr10: cmr10, hz1cmr10)(fontvariants of cmr10: cmr10,
+ hz2cmr10, hz1cmr10)(fontvariants of cmr10: cmr10, hz3cmr10, hz2cmr10, hz1cmr10
+)(fontvariants of cmr10: hz4cmr10, cmr10, hz3cmr10, hz2cmr10, hz1cmr10)(fontvar
+iants of cmr10: hz5cmr10, hz4cmr10, cmr10, hz3cmr10, hz2cmr10, hz1cmr10)(fontva
+riants of cmr10: hz6cmr10, hz5cmr10, hz4cmr10, cmr10, hz3cmr10, hz2cmr10, hz1cm
+r10)183.9726 -!-> 171.9726
+(adjust_excess: 0.93477 --> 6666666666666666666666666666666666666666
+ got -11.02962)183.9726 -!-> 175.9726
+(adjust_excess: 0.95651 --> 5655565555655565555655555655564655555655
+ got -7.98792)183.9726 -!-> 179.9726
+(adjust_excess: 0.97826 --> 4444544444444454444444544444445444444544
+ got -4.02394)183.9726 -!-> 180.9726
+(adjust_excess: 0.98369 --> 4344434444344434444344443444443444344443
+ got -2.9984)183.9726 -!-> 181.9726
+(adjust_excess: 0.98914 --> 4334343434343434343434334343434434343434
+ got -1.98593)183.9726 -!-> 182.9726
+(adjust_excess: 0.99457 --> 3433434334333424333433433433433343334333
+ got -0.98468)183.9726 -!-> 184.9726
+(adjust_excess: 1.00543 --> 3233232332333242333233233233233323332333
+ got 0.98463)183.9726 -!-> 185.9726
+(adjust_excess: 1.01086 --> 2332323232323232323232332323232232323232
+ got 1.986)183.9726 -!-> 186.9726
+(adjust_excess: 1.01631 --> 2322232222322232222322223222223222322223
+ got 2.99843)183.9726 -!-> 187.9726
+(adjust_excess: 1.02174 --> 2222122222222212222222122222221222222122
+ got 4.02391)183.9726 -!-> 191.9726
+(adjust_excess: 1.04349 --> 1011101111011101111011111011102011111011
+ got 7.98792)183.9726 -!-> 195.9726
+(adjust_excess: 1.06523 --> 0000000000000000000000000000000000000000
+ got 11.02965)gw=0
+gw=0
+gw=0
+gw=0
+[2
+
+] (example4.aux)
+
+LaTeX Font Warning: Some font shapes were not available, defaults substituted.
+
+ )
+Here is how much of TeX's memory you used:
+ 220 strings out of 10928
+ 2149 string characters out of 147947
+ 48995 words of memory out of 263001
+ 3188 multiletter control sequences out of 10000+0
+ 6477 words of font info for 24 fonts, out of 200000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 23i,5n,19p,139b,175s stack positions out of 300i,100n,500p,30000b,4000s
+
+Output written on example4.dvi (2 pages, 8348 bytes).
diff --git a/systems/tex-extensions/clasen/examples/example4/example4.ps b/systems/tex-extensions/clasen/examples/example4/example4.ps
new file mode 100644
index 0000000000..847aec9988
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/example4.ps
@@ -0,0 +1,1026 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.76a Copyright 1997 Radical Eye Software (www.radicaleye.com)
+%%Title: example4.dvi
+%%Pages: 2
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSCommandLine: dvips -a -D600 -mode ljfive example4.dvi -o
+%+ example4.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource: TeX output 1998.07.24:1639
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N
+/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id
+gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp
+add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add
+/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{
+dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1
+adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2
+idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string
+putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval
+adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg}
+{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{
+adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2
+chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{]
+}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{dup length product length le{dup length product
+exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}
+ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}
+imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false
+RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round
+exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto
+rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup
+/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{
+-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}
+B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B
+/bos{/SS save N}B /eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (example4.dvi)
+@start
+%DVIPSBitmapFont: Fa cmtt12 12 10
+/Fa 10 122 df<ECFFF0010713FE497F013F14804914C090B612E04815F048EBC01F3807
+FE00EA0FF849EB0FE04848EB07C04848EB038092C7FC5B127F90C9FCA25A5AA87EA27E7F
+A26C6CEB01F06DEB03F8121F01F813076C6C14F06CB4130F6C9038E03FE06C90B512C07E
+6D14806DEBFE006D5B010713F0010013C0252E79AC33>99 D<147F903803FFF0011F13FC
+497F90B6FC4815804815C0028013E03907FE003FD80FF8EB0FF04848EB07F85B4848EB03
+FC5B007F1401A290C713FE15005A90B6FCA516FCA248C9FC7E7EA27F123F6D147C6C7E6D
+14FE6C7E01FE13016C6CEB07FC6C9038E01FF86C90B5FC6C15F06D14E06D14C0010F1400
+010313FC9038003FC0272E7BAC33>101 D<D901FEEB3FC0903A0FFFC1FFF04901E713F8
+4990B512FC5B90B7FC5A480103EBE1F82607FC00EB80F049017F130048486D7E49131F00
+1F8149130FA76D131F000F5D6D133F6C6C495A6D13FF2603FF0390C7FCECFFFE485C5D48
+5C01DF5B01CF5BD9C1FEC8FC01C0C9FCA37FEA07F290B512FC6CECFFC016F04815FC4881
+4881273FE00007138001809038007FC048C8EA1FE0007E150F160700FE16F0481503A56C
+1507007E16E0D87F80141FD83FE0EC7FC0D81FF8903801FF809038FF801F6C90B612006C
+5D000115F86C5D013F14C0010F91C7FC010013F02E447DAB33>103
+D<EA3FFC127F487EA3127F123F1200AA4AB4FC020F13C04A7F027F7F91B57E90B67E82EC
+FE07ECF0014A6C7E5C4A7FA291C7FCA35BB3A33B3FFFF80FFFFC486D4813FEB56C4813FF
+A36C496C13FE6C496C13FC303D7FBC33>I<02FC137E3A7FC3FE01FF27FFCFFF077F90B5
+008F7F03DF7F92B57EA26C010F13873B07FC07FE03F801F813FC02031301A201F013F8A3
+01E013F0B3A43C7FFE0FFF07FF80B5028713C04A138FA36E1387D87FFE02071380322C80
+AB33>109 D<4AB4FC263FFC0F13C0007F497F26FFFE7F7F91B57E90B67E6C816CEBFE07
+C6EBF0014A6C7E5C4A7FA291C7FCA35BB3A33B3FFFF80FFFFC486D4813FEB56C4813FFA3
+6C496C13FE6C496C13FC302C7FAB33>I<ED03FE3B7FFF801FFF80B5017F13C002C1B512
+E002C314F014C714CF6C9038DFFE0F3B001FFFF007E09238C003C092C8FC5C5C5CA25CA2
+5CA45CB0007FB512FEB6FC81A35D7E2C2C7DAB33>114 D<90381FFE0790B5EA8F800003
+14FF5A5A5A5A387FF007EBC00048C7127FA248143FA4007FEC1F0001C090C7FCEA3FF838
+1FFFC06C13FE6CEBFFC06C14F0C614FC011F7F01017FD900071380020013C0ED3FE0003C
+140F007E15F000FE1407A27EA27F150F6DEB1FE001F0133F9039FC01FFC090B6FC168016
+0000FD5CD8FC7F13F8486C13E0D8700790C7FC242E79AC33>I<EB03C01307497EAA003F
+B612FC5AB77EA36C5DA226000FE0C8FCB3161FA2EE3F80A46E137F170001075C6E485AEC
+FE076DB55A5E6D5C6D5C6E1380021F90C7FCEC07F829387EB633>I<3B7FFF801FFFE0B5
+6C4813F06E4813F8A34A6C13F06C496C13E03B01F80001FC006D5CA2000014036D5C137E
+1507017F5C7FA26E485A131FA26D6C485AA214E0010749C7FCA214F01303157EEB01F8A2
+5D130014FC5D147C147DEC3FF0A36E5AA36E5AA2141F5DA2143F92C8FCA3147EA2001F13
+FE486C5AEA7FC1EBC3F81307EB1FF013FF6C5B5C6C5B91C9FCEA0FFCEA03F02D427DAA33
+>121 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fb cmsy10 12 1
+/Fb 1 111 df<126012F0A21278A37EA37EA37EA26C7EA36C7EA36C7EA36C7EA21378A3
+7FA37FA37FA26D7EA36D7EA36D7EA36D7EA21478A380A380A280A36E7EA36E7EA36E7EA2
+6E7EA31578A381A381A281A3ED0780A3ED03C0A3ED01E0A2ED00F0A31678A3163CA3161E
+A2160C27647BCA32>110 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fc hz6cmr10 10 27
+/Fc 27 128 df<DA03FFEB1F80021F9038E0FFE091B500F313F0903B03FE00FFF1F8D907
+F090387FC1FCD91FC0EBFF8349485AD97F001403017EED01F801FE903900FE00F0491600
+1201ACB9FCA3D801FCC748C7FCB3AB486C497E277FFFF03F13FEA3363B7FBA33>11
+D<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A798918>46
+D<B91280A3000190388000036C90C8127FEF1FC0170F17071703A31701A318E017001638
+A31800A31678A216F8150791B5FCA3EC000715001678A21638A2181CA3183C93C71238A4
+1878A318F0A21701A21703170F173F486D903801FFE0B9FCA336397DB83C>69
+D<B9FCA3000190388000076C90C8FCEF3F80171F170F1707A31703A318C01701A21670A2
+94C7FCA416F0A21501150791B5FCA3EC000715011500A21670A693C8FCAD4813C0B612C0
+A332397DB839>I<D907F8133090393FFF807090B512C03A01F807F0F03903E000F9D807
+80133D48C7120F481407123E1503481401A2150012FCA316707EA27E6C150013C07FEA3F
+FCEBFF806C13F86CEBFF806C14F06C14FC6C806C6C7F6D1480010314C0D9003F13E00203
+13F0EC007FED1FF81507A2ED03FC1501126012E01500A47E16F87E15016C15F016E06C14
+036C6CEB07C0D8FBC0EB0F80D8F9F0EB1F00D8F0FF137E39E03FFFFC010F13F048C61380
+263D7BBA31>83 D<EB3FF848B5FC000780390FC01FE0391F0007F0486C6C7E6D6C7E1400
+816C48137E6CC7127F1206C8FCA4EC7FFF010FB5FC90383FF87F3801FF803803FC00EA0F
+F0485A485A5B127F90C713075AA315FFA2397F8001BF14033A3FC0071F8E261FF01E13FE
+3A07FFFC0FFC6C01F013F83A007FC003E028277DA52C>97 D<EA03F812FFA3120F1203B0
+EC07F8EC3FFF91B512C09039F9F01FE09039FBC003F09039FF0001F8496D7E49147E4914
+7F821780A2EE1FC0A317E0A817C0A2163F1780A217006D5C16FE6D5C01F7495A9039E3C0
+07F09039C1F01FE001C0B512809026803FFEC7FCC7EA0FF02B3B7EB931>I<EB03FF010F
+13E0013F13F89038FE00FCD801F8133E4848137F48485B120F5B001F147E4848133C1518
+007F91C7FC90C9FCA25AA97E7FA2123FED03806C7EED07006C7E6C6C130E6C6C131E6C6C
+5B3900FF01F890387FFFE0011F1380D903FEC7FC21277DA527>I<ED03F815FFA3150F15
+03B0EB01FE90380FFF83013F13E39038FF01FB3901FC003FD803F0131F48481307120F48
+4813035B123FA2127F90C7FCA25AA87EA36C7EA2121F6D1307120F6C6C130F6C6C131F6C
+6CEB7BFE3B00FF03F3FFE090387FFFC3011F1383903A03FC03F8002B3B7DB931>I<EB03
+FC90381FFF804913E09038FE07F03901F801F848486C7E4848137E4848137F001F804914
+80003F141FA248C7FC16C0A25A90B6FCA390C9FCA57EA27F123FED01C06C7E000FEC0380
+7F6C6CEB07006C6C130E6C6C5B39007F80F86DB45A010F13C0D901FEC7FC22277EA527>
+I<EC3F80ECFFE0010313F090380FE1F890381F81FCEB3F03137F137E9038FE01F8EC00F0
+48481300ADB6FCA3D801FCC7FCB3AB487E387FFFFCA31E3B7FBA1B>I<16F8903907F803
+FC90393FFF07FE90B5EACF1F3A01FC0FFC3F3A03F003F01F3A07E001F80E3A0FC000FC00
+001F8049137E003F147FA7001F147E6D13FE000F5C6C6C485A6C6C485A9038FC0FE00006
+B55A013F90C7FC380E07F890C9FCA3121E7E7F90B512E06C14FEEDFF806C15C06C15E000
+0715F03A1F80001FF848C7EA03FC003E1401007EEC00FE48157EA5007E15FCA26CEC01F8
+D81FC0EB07F0D80FF0EB1FE0D803FEEBFF806CB61200D8003F13F80103138028387EA52C
+>I<EA03F812FFA3120F1203B0EC03FC91381FFF804A7F9138780FE09138E007F09039F9
+8003F8EBFB0001FE6D7EA25BA25BB3A4486C497EB539E07FFFF0A32C3A7EB931>I<EA03
+C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512C0A312
+387EB718>I<EA03F812FFA3120F1203B192B5FCA3ED7FF0ED3F80033EC7FC5D1578EC01
+E04A5A4A5A4AC8FC141E5C14FEEBF9FF13FB9038FFBF80EC1FC09038FC0FE013F86E7E6E
+7E6E7EA26E7E157F81826F7E826F7E486C497EB539E07FFFC0A32A3A7EB92E>107
+D<EA03F812FFA312071203B3B3AD487EB512E0A3133A7EB918>I<2703F803FCEB01FE00
+FF903B1FFF800FFFC04A6D487F913B780FE03C07F0000F903BE007F07003F83D03F98003
+F8C001FCD9FB00EBF98001FE6DB4C77EA2495CA2495CB3A4486C496C497EB528E07FFFF0
+3F13F8A345257EA44A>I<3903F803FC00FF90381FFF804A7F9138780FE0000F9038E007
+F03A03F98003F8EBFB0001FE6D7EA25BA25BB3A4486C497EB539E07FFFF0A32C257EA431
+>I<49B4FC010F13E0013F13F890387F01FC3901FC007FD803F0EB1F804848EB0FC04848
+EB07E0A24848EB03F0003F15F8A248C7EA01FCA44815FEA86C15FCA36C6CEB03F8A2001F
+15F06D1307000F15E06C6CEB0FC06C6CEB1F80D801FCEB7F003900FF01FE90383FFFF801
+0F13E0010190C7FC27277EA52C>I<3903F01F8000FFEB7FC0ECFFF0EBF1E3390FF387F8
+0003130713F79038F603F09038FE01E09038FC00C01500A25BB3A3487EB512F8A31D257E
+A422>114 D<90387FC0C03803FFF14813FF381F807F383E000F003C1307481303A200F8
+1301A37E7E6C6CC7FCEA7FFCEBFFC06C13F86C7F6C13FF000314806C14C0EA003F010113
+E0EB001F0060EB07F000E01303A26C1301A36C14E0A26C13036C14C06CEB07809038C03F
+0038F3FFFE00E013F838C03FE01C277DA523>I<131CA5133CA3137CA213FC1201120312
+07121FB612C0A3D801FCC7FCB21570A815606C6C13E0A290387F01C090383F838090381F
+FF006D5AEB01F81C347FB222>I<D803F8EB01FC00FF147FA3000F140700031401B3A415
+03A315070001140F6D130D0000EC39FF017F01F113F090383FFFE1010F13C1903A03FE01
+FC002C267EA431>I<B539C01FFF80A33B07FC0007FC006C48EB01F05E7F00015D6D1303
+00005DA26D13076D91C7FC6E5A013F130EA26D6C5AA2ECE03C010F1338A26D6C5AA2ECF8
+F001035B14FC903801FDC0A214FF6D5BA26EC8FCA3143EA2141C29257EA32E>I<B53BC7
+FFFC07FFE0A3290FFC003FE00113006C4890391FC0007E0003177C030F14386D16780001
+6F1370151F6D16F000004A6C5B153B017F6E485A157BEC8071013F6E485A15E002C01407
+011F02FE90C7FC9138C1C07E02E1EB7F0FD90FE3140EED803FD907F3149C14F79138FF00
+1F6D15F84A130FA201015D4A1307A201005D4A130302785C027013013B257EA340>I<BD
+12FEA35703809758>124 D<001EEB03C0393F800FE0397FC01FF0A200FF14F8A2007F14
+F0A2393F800FE0391E0003C01D0A79B72C>127 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fd hz1cmr10 10 33
+/Fd 33 128 df<91390FF003F091397FFC1FFC903A01FFFE7FFE903A07F80FFE3FD90FE0
+01F81380903A1F801FF07F90383F003F4914E001FEED3F0092381FC01E4992C7FC1201AC
+B812C0A32801FC001FC0C7FCB3AB486C497E267FFFC1B512C0A3313B7FBA2E>11
+D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA0700A2
+120E5A123C123812100B1A7AB916>39 D<121E123FEA7F80EAFFC0A213E0A2127F123F12
+1E1200A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A7A8916>44
+D<B512F0A614067F941A>I<B812C0A30001EB80006C90C7121FEE07E01603A21601A216
+00A417F01770A2151CA21700A4153CA2157C15FC14FFA31400157C153CA2151CA692C8FC
+AD4813C0B612C0A32C397DB833>70 D<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A
+397FB81C>73 D<90381FE00690387FF80E3801FFFE3903F01F1E3907C007BE390F8001FE
+48C7FC121E003E147E007E143E127CA200FC141EA3150EA27EA36C91C7FC6C7E7FEA3FF0
+13FF6C13E014FE6C6D7E6C14E06C806C806C6C7F010F7F1300EC0FFF14016E1380157F15
+3FED1FC0A2126000E0140FA57E1680A26C141F16007E6C143E6C143C6D137CD8FBE05B39
+F0FC03F039E07FFFC0011F5B26C003FEC7FC223D7CBA2B>83 D<003FB712FEA39039E00F
+FC01903A0007F8007E007E82007C82007882A2831270A400F01780481603A4C792C7FCB3
+B0EC1FFE017FB67EA331397DB838>I<007FB50003B512E0A3C6903AF8007FFC00D97FE0
+EB1FE0013FEC0F8094C7FC6D6C130E010F141E6E131C0107143C6E13386D6C13785E6D6C
+5B6D1301ED81C0EC7FC3EDC780DA3FE7C8FCEC1FEF15FE140F5D1407A26E7E140181825C
+82EC07BFED3FE0EC0E1F021E7F91381C0FF8143C91383807FCEC780302F07FECE0010101
+804A6C7F0103147F49488091C7123F4981010E6E7E131E496E7E017E140701FF4A7E0007
+6DEB3FFEB5D8F001B512FCA336397EB83B>88 D<EB7F803803FFF0487F380F80FE381F00
+7F486C7E6D6C7E81A26C486C7EEA0F001206C7FCA4EB03FF133FEBFFCF3803FE0FEA07F8
+EA0FE0EA1FC0EA3F80127FA2D8FF0014E0A4141FA27EEB8037003F903873F1C0391FE1E3
+FF260FFFC113800003018113003900FE007C23277DA527>97 D<EA03F812FFA3120F1203
+B0EC1F80ECFFF001F97F9038FBC0FC9038FF007E497F49EB1F804914C0150F16E0A2ED07
+F0A316F8AA16F0A3ED0FE0A216C0151F6D14806DEB3F006D137E9038E7C1FC9038C3FFF8
+018013E0C7EA3F80253B7EB92B>I<EB07F8EB3FFF4913803901FC07C03903F003E03907
+E007F0140FEA0FC0121F90388007E0003FEB03C0EC018048C8FCA35AAA7E7FA2003F1438
+A26C7E000F14707F6C6C13E03903F801C03901FE078039007FFF00EB3FFCEB07F01D277D
+A523>I<15FE143FA314031400B0EB0FE0EB3FF8EBFFFE3801FC0F3803F0073807E001EA
+0FC0001F13005B123FA248C7FCA35AAA7EA36C7EA2121FEBC001120F3807E0033A03F007
+FF802601F81E13F83800FFFC6D5A90390FC0FE00253B7DB92B>I<EB07F0EB3FFC49B4FC
+3901FC3F803903F00FC03907E007E0EA0FC0EC03F0EA1F80003F14F81401EA7F0015FCA3
+5A90B5FCA390C8FCA57EA36C7E151C121F6D1338120F6C6C13706C7E3901F801E03900FE
+07C090387FFF8090381FFE00EB03F81E277EA523>I<147E49B4FC0107138090380FCFC0
+90381F8FE0EB3F1F137EA29038FE0FC09038FC0780000190C7FCADB512F8A3D801FCC7FC
+B3AB487E387FFFFCA31B3B7FBA18>I<150F90391FC03FC090387FF0FF3A01FFFDE3E039
+03F07F873907E03F033A0FC01F81C0ED800048486C7EA2003F80A7001F5CA26C6C485AA2
+6C6C48C7FC3803F07E48B45A380E7FF0380C1FC090C9FC121CA2121EA2EA1F80380FFFFE
+ECFFE06C14F86C8081000F80381F800148C7EA7F80007E141F16C048140FA5007EEC1F80
+A26CEC3F006C6C137E6C6C5B3907F807F80001B512E06C6C1380D90FFCC7FC23387EA527
+>I<EA03F812FFA3120F1203B0EC0FC0EC3FF0ECFFF89038F9E1FC9038FB80FE140001FE
+137E157F5BA35BB3A4486C1480B538E3FFFCA3263A7EB92B>I<EA03C0487E487E487EA4
+6C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A313387FB716>I<EA03
+F812FFA3120F1203B191381FFFE0A3913807FE00EC03F815E05D4A5A92C7FC140E5C5C5C
+14F0EBF9F813FBEBFFFC497EEBFC7E147F497E816E7E140F811407816E7EA26E7EA26E7E
+3A07FC01FF80B500C713F8A3253A7EB929>107 D<EA03F812FFA3120F1203B3B3AD487E
+B512E0A3133A7FB916>I<2703F80FE0137F00FF903A3FF801FFC091267FFE0313F0913A
+F07F0783F83B0FF9C03F0E012603FB0001987F01FF90381FB8004902F07F495CA3495CB3
+A4486C496C487EB500E1B5000F13F8A33D257EA442>I<3903F80FC000FFEB3FF0ECFFF8
+9038F9E1FC390FFB80FE0003130001FE137E157F5BA35BB3A4486C1480B538E3FFFCA326
+257EA42B>I<EB07F8EB1FFE90387FFF803901FC0FE03903F003F048486C7EEBC000000F
+804848137EA2003F147F90C77E481580A34815C0AA6C1580A36C6CEB7F00A2001F147E6D
+13FE000F5C6C6C485A6C6C485A3901FC0FE039007FFF806D90C7FCEB07F822277EA527>
+I<3903F81F8000FFEBFFF001F97F9038FBC1FC3907FF007E6C487F49148049EB1FC0A2ED
+0FE0A216F0A2150716F8AA16F0150FA216E0151F16C0153F6D14806DEB7F006D13FEECC1
+FC9038FBFFF801F813E0EC3F8091C8FCAB487EB512E0A325357EA42B>I<3803F0FC38FF
+F1FE9038F3FF80EBF71F390FF63FC0EA03FE13FCEC1F80EC0F00EBF80691C7FCB3A5487E
+B512F8A31A257EA41F>114 D<EBFE0C3807FF9C4813FCEA1F01383C007C007C133C1278
+00F8131CA47E1400B4FCEA7FF013FF6C13C06C13E06C13F06C13F86C13FC38007FFE1307
+13000060137F00E0133F141F7EA46C131E143E6C133C6C137C38FF81F838F7FFF000E113
+C038C07F0018277DA51F>I<131CA5133CA3137CA213FC120112031207121FB512FCA338
+01FC00B21407A900001306EBFE0E137EEB7F1CEB3FF8EB0FF0EB03E018347FB21E>I<D8
+03F8137F00FFEB1FFFA3000F130100036D7EB3A55DA300015BA23A00FC037FC0D9FE0F13
+FCEB7FFEEB1FFCD907F0130026267EA42B>I<B538C3FFF0A33A0FFC007F806C48EB3F00
+0003143E151C6D133C00011438A26D137800001470A26D13F06D5BA21481013F5BA214C3
+011F5BA214E7010F90C7FCA2EB07FEA36D5AA36D5AA36D5AA324257EA329>I<B53A0FFF
+E3FFF8A33C07FC01FE007FC06C486C48EB3F00171E6C6C7F037E131CA26D017F133C0000
+4A1338A26DEC807890267F01DF1370A2EEC0F0D93F835C158FA2D91FC7EBE1C01507A2D9
+0FE7EBF380ECEE03A202FE13FF6D486C90C7FCA301035CECF800A201015C4A137CA20100
+14784A133835257FA338>I<B538C7FFF8A30003010113803A01FE00FC0000005C5D017F
+5B90383F81C0148390381FC38002E7C7FCEB0FEFEB07FE5C13031301801300805B497FEC
+BFC0EB071F496C7E010E7FEB1C0790383C03F801787F14019038F800FE12033A0FFC01FF
+80B5000F13FCA326247FA329>I<B538C3FFF0A33A0FFC007F806C48EB3F000003143E15
+1C6D133C00011438A26D137800001470A2017F5BA390383F81C0A390381FC380A214E701
+0F90C7FCA214FF6D5AA36D5AA36D5AA26D5AA35CA3495AA213035C127CEAFE0791C8FC5B
+130E485AEA787CEA3FF86C5AEA0FC024357EA329>I<001E1378383F81FC007F13FE13C3
+00FF13FFA2007F13FE1381003F13FC381E0078180A79B727>127
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fe hz2cmr10 10 30
+/Fe 30 128 df<91390FF003F091397FFC1FFC903A01FFFE7FFE903A07F80FFE3FD90FE0
+01F81380903A1F801FF07F90383F003F4914E001FEED3F0092381FC01E4992C7FC1201AC
+B812E0A32801FC001FC0C7FCB3AB486C497E267FFFC1B512C0A3313B7FBA2E>11
+D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA0700A2
+120E5A123C123812100B1A7A8916>44 D<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E
+0A0A7A8916>46 D<157015F8A44A7EA34A7EA34A7EA34A7FEC0E7FA2021E7FEC1C3FA202
+3C7FEC381FA34A6C7EA34A6C7EA349486C7EA3010380EC8001A201078091C7FCA249B67E
+A3010EC7127F496E7EA3496E7EA3496E7EA301F08116071201486C81D80FFEEC1FFEB5D8
+C003B512F8A3353C7DBB3C>65 D<B812E0A30001903880007F6C90C7120FEE03F01601A2
+1600A21770A417781738A2150EA21700A4151EA2153E15FE14FFA31400153E151EA2150E
+A692C8FCAD4813C0B612C0A32D397DB834>70 D<B612C0A3C6EBC0006D5AB3B3AD497EB6
+12C0A31A397FB81D>73 D<90380FE00390387FFC0748B5FC3903F01F8F3907C003DF4848
+6CB4FC48C77EA2003E80815AA200FC80A381A27EA3007F91C7FC7F7FEA3FF013FF6C13F0
+14FF6C14C06C14F06C80C6806D7F010F7F1300020F138014019138007FC0153F151F16E0
+150F126000E01407A57E16C0A26C140F16807E6CEC1F006C141E01C0133ED8FBF05B39F0
+FE01F039E07FFFE0011F5B26C001FEC7FC233D7CBA2C>83 D<EB7FC03801FFF800077F38
+0F807E48487E486C6C7E6D6C7E81A26C486C7EEA0F001206C7FCA4EB01FF131FEBFFE738
+03FE07EA07F8EA0FE0EA1FC0123FEA7F80A2D8FF001470A4140FA2EA7F80141B3A3FC031
+F8E0391FE0E1FF260FFFC013C000034913803A00FE003E0024277DA528>97
+D<EA03F812FFA3120F1203B0EC1FC0EC7FF09038F9FFFC9038FBE0FE9038FF003F49EB1F
+8049EB0FC04914E0150716F0A2ED03F8A316FCAA16F8A2150716F0A216E06DEB0FC0A26D
+EB1F8001E7EB3F009038E3C0FE9038C1FFF801805BC7EA3F80263B7EB92C>I<EB07F8EB
+3FFF4913803901FC07C03903F003E03907E007F0140FEA0FC0121F90388007E0003FEB03
+C0EC018048C8FCA35AAA7E7FA2003F1438A26C7E000F14707F6C6C13E03903F801C03901
+FE07806CB51200EB3FFCEB07F01D277DA523>I<157FEC1FFFA314016E7EB0EB07F0EB3F
+FCEB7FFE3901FC0FFF3803F00348487E48487E81485A123FA2127F90C7FCA25AAA7EA36C
+7EA2121F6D5B120F6C6C5A2603F00713C03A01FC1F7FFC3800FFFEEB3FF8D90FE0130026
+3B7DB92C>I<EB07F0EB3FFC49B4FC3901FC3F803903F00FC03907E007E0EA0FC0EC03F0
+EA1F80003F14F81401EA7F0015FCA35A90B5FCA390C8FCA57EA36C7E151C121F6D133812
+0F6C6C13706C7E3901F801E03900FE07C090387FFF8090381FFE00EB07F81E277EA523>
+I<14FEEB03FF010F138090381F8FC090383F0FE0EB7E1F13FE13FC0001EB0FC09038F807
+80000390C7FCADB512F8A3D803F8C7FCB3AB487EB512F8A31B3B7FBA18>I<ED07809039
+1FE03FE090387FF87F9039FFFCF1F03903F03FC33907E01F813A0FC00FC0E0160048486C
+7EA2003F80A7001F5CA26C6C485AA26C6C485A6C6C48C7FC3806FFFC380E7FF8380C1FE0
+90C9FC121C121EA36C7E90B5FC15F06C806C14FE81000F1580381F800048C7EA3FC0007E
+140F16E0481407A5007EEC0FC0A26CEC1F806C6CEB3F00D80FE013FE3907F803FC0001B5
+12F06C6C13C0D90FFEC7FC24387EA528>I<EA03F812FFA3120F1203B0EC0FE0EC3FF84A
+7EECE0FE9038F9807E9038FB007F01FE7F16805BA35BB3A4486CEB7FC0B538E1FFFEA327
+3A7EB92C>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3
+AA487EB512E0A313387FB716>I<EA03F812FFA3120F1203B191380FFFF0A302031300EC
+01FC15F05D4A5A4A5A4AC7FC141E5C5C14F813F9EBFBFC13FF80EBFE7F497E01F87F6E7E
+140F811407816E7E1401816E7EA281486C14C0B500E313FCA3263A7EB92A>107
+D<EA03F812FFA312071203B3B3AD487EB512E0A3133A7FB916>I<2703F80FE0137F00FF
+903A3FF801FFC091267FFE0313F0913AF07F0783F83B0FF9C03F0E012603FB0001987F01
+FF90381FB8004902F07F495CA3495CB3A4486C496C487EB500E1B5000F13F8A33D257EA4
+42>I<3903F80FE000FFEB3FF84A7EECE0FE390FF9807E3903FB007F01FE7F16805BA35B
+B3A4486CEB7FC0B538E1FFFEA327257EA42C>I<EB03F8EB1FFF017F13C09038FE0FE039
+03F803F8EBE0004848137C000F147E48487FA2003F158090C7121F4815C0A34815E0AA6C
+15C0A36C6CEB3F80A2001F15006C6C137EA26C6C5B3903F803F83901FE0FF039007FFFC0
+011F90C7FCEB07FC23277EA528>I<3903F81FC000FFEB7FF09038F9FFFC9038FBE0FE39
+07FF003F6C48148049EB1FC049EB0FE0A216F0150716F8A2150316FCAAED07F8A316F015
+0F16E06DEB1FC0A26DEB3F806DEB7F009038FBC1FE9038F9FFF801F85BEC3F8091C8FCAB
+487EB512E0A326357EA42C>I<3803F0FC38FFF1FE9038F3FF80EBF71F390FF63FC0EA03
+FE13FCEC1F80EC0F00EBF80691C7FCB3A5487EB512F8A31A257EA41F>114
+D<EBFE0C3807FF9C4813FCEA1F01383C007C007C133C127800F8131CA47E1400B4FCEA7F
+F013FF6C13C06C13E06C13F06C13F86C13FC38007FFE130713000060137F00E0133F141F
+7EA46C131E143E6C133C6C137C38FF81F838F7FFF000E113C038C07F0018277DA51F>I<
+131CA5133CA3137CA213FC120112031207121FB512FEA3D801FCC7FCB2EC0380A90000EB
+070013FE137EEB3F0EEB1FFC6D5AEB03F019347FB21F>I<D803F8EB3F8000FFEB0FFFA3
+000F13000003143FB3A5157FA3000114FFA23A00FC01BFE090397E073FFEEB3FFEEB1FFC
+D907F0138027267EA42C>I<B538C1FFF8A33A0FFC003FC06C48EB1F8000031500151E7F
+0001141CA26C6C5BA3017F5BA36D6C5AA214C1011F5BA214E3010F5BA214F7010790C7FC
+A2EB03FEA36D5AA36D5AA3147025257EA32A>I<B53A1FFFE1FFF8A3260FF8019038007F
+E02707F000FCEB1F806DED0F0000036E130E157E6D151E0001027F131C5D173C6C6CEC80
+38EC01DFA2017F6E5AEC038FA2D93F836D5AEC8707A2D91FC7EBF1C0ECCE03A2D90FEEEB
+FB8014FEECFC01010702FFC7FCA24A7E01035CA24A137EA20101147C4A133C0100143835
+257EA33A>I<B538C1FFF8A33A0FFC003FC06C48EB1F8000031500151E6C6C131CA36C6C
+5BA26D13786D1370A2EC80F0013F5BA290381FC1C0A390380FE380A214F7010790C7FCA2
+14FF6D5AA26D5AA36D5AA31470A214F05CA2495AA3387C038012FE49C8FCA2130EEAFC1E
+EA787CEA3FF86C5AEA0FC025357EA32A>121 D<001E133C383F80FE387FC1FFA200FF14
+80A2007F1400A2383F80FE381E003C190A79B728>127 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Ff hz5cmr10 10 36
+/Ff 36 128 df<DA03FE133F913A3FFFC1FFC091B500E713E0903B03FC01FFE3F0902607
+F000EB83F890261FC001130749485AD97F0013FE017EED03F001FE903901FC01E04992C7
+FC1201ACB812FEA32801FC0001FCC7FCB3AB486C497E3B7FFFF07FFFFCA3353B7FBA32>
+11 D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA07
+00A2120E5A123C123812100B1A79B918>39 D<121E123FEA7F80EAFFC0A213E0A2127F12
+3F121E1200A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A798918>44
+D<B512FEA617067F941D>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A798918>
+I<151EA3153FA24B7EA34B7EA34A7F15DFA29138038FF0A391380707F8A2020F7FEC0E03
+A2021E7FEC1C01A2023C7FEC3800A24A80167FA24A6D7EA20101814A131FA20103814A13
+0F91B6FC4981A291C71207010E811603A2496E7EA3496E7EA20178820170157FA201F082
+0001163F487ED80FFEEDFFF0B500C0011FEBFFC0A33A3C7DBB41>65
+D<B812FEA30001903880000F6C90C71201EE007F838383A383A318801703A216E0A294C7
+FCA41501A21503150F91B5FCA3EC000F15031501A21500A693C8FCAD4813C0B612C0A331
+397DB838>70 D<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81F>73
+D<D90FF81360D93FFF13E090B512C03901F807E13907E000F3D80F80137B90C7121F4814
+0F123E1507481403A200FC1401A415007EA27E6C15007F13E0EA3FF8EBFF806C13F86CEB
+FF806C14E06C14F86C806C80013F7F01071480D9007F13C0020713E0EC007FED1FF0150F
+150716F81503126012E01501A47E16F0A26C14036C15E0A26CEC07C06CEC0F80D8FBC0EB
+1F00D8F9F0133ED8F0FF13FC39E03FFFF8010F13E0D8C00190C7FC253D7BBA30>83
+D<003FB812F8A3D9E001EB800F90C7EB0001007EEE00FC007C177C0078173CA30070171C
+A400F0171E48170EA4C81500B3B0020313C0010FB612F0A337397DB83E>I<007FB5D880
+0FB51280A3C69026F80001EBE000D93FF06D90C7FC177E011F15786D7E6E5C01075D6D6C
+13016E495A6D5D6DEB80076E6C48C8FC161E91383FE01C91381FF03C5E91380FF8709138
+07FCF0EDFDE06EB45A805E806F7EA26F7E82157F4B7EEDE7FC02017FEC03C3ED81FF0207
+804AC6FC020E6D7E4A80023C133F4A6D7E02706D7E14F049486D7E4A6D7E130349486D7E
+91C87F5B011E6F7E013E6F7E13FF000701C0ECFFF8B500F0010FEBFFF0A33C397EB841>
+88 D<EB3FF03801FFFE00076D7E390FC01FC048C66C7E393F8003F001C07F6E7EA2381F
+80006CC77E1206C8FCA4147FEB0FFFEB7FF83801FF00EA07FCEA0FF0485A485A5B127F48
+C7130EA41401A2397F80037E14073A3FC00E3F1C261FF03C13FC3A07FFF81FF86C01E013
+F03A007F8007C027277DA52B>97 D<EA03F812FFA3120F1203B0EC07F8EC3FFE91B57E90
+39F9F01FC09039FF8007F04A6C7E491301496D7E4980167FA21780163FA317C0A81780A2
+167F1700A2167E16FE6D5C6D495A01F7495A9039E3800FE09039E1F03FC001C0B5C7FC90
+38803FFEC7EA0FF02A3B7EB930>I<EB03FE90381FFFC0017F13F09038FE01F83901F800
+7C484813FE3807E001EA0FC0121FEC00FC484813781530007F140090C8FCA25AA97EA27F
+123F15076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F090387FFFC0011F13
+80903803FC0020277DA526>I<ED07F0EC01FFA3EC001F1507B0EB03FC90381FFF87017F
+13C79038FF01F73901FC007FD803F0131F4848130F485A001F14075B123FA248C7FCA35A
+A87EA37F123FA26C6C130F120F6C6C131F6C6C133F6C6CEBF7FC3B00FE03E7FFC090387F
+FFC7011F1307D903F8EBF0002A3B7DB930>I<EB03FCEB1FFF017F13C09038FE0FE03901
+F803F03903E001F800076D7E4848137E121F49137F003F80A248C7FC1680A25A90B6FCA3
+90C9FCA57EA27F123FED03806C7EED07006C7E0007140ED803F85B6C6C5B3900FF81F090
+383FFFE0010F1380D901FEC7FC21277EA526>I<147F903801FFC0010713E090381FC3F0
+90383F03F8EB7E0713FE13FC0001EB03F0EC01E04848C7FCADB512FEA3D803F8C7FCB3AB
+487EB512F8A31D3B7FBA1A>I<ED01F0903907F007F890393FFE0FFC90B5EA9E3E3A01F8
+0FF87E3A03E003E03E0007ECF01C3A0FC001F800001F80EB8000003F80A7001F5CEBC001
+000F5C6C6C485A00035C9038F80FC00006B55AD93FFEC7FC380E07F090C9FCA2121EA27E
+7F90B512C06C14FC15FF6C15C016E04815F0391F80003F48C7EA07F8007E140116FC4814
+00A5007EEC01F8A26CEC03F06C6CEB07E0D80FE0EB1FC0D807FCEBFF800001B5EAFE00D8
+003F13F00107138027387EA52B>I<EA03F812FFA3120F1203B0EC03F8EC1FFF4A7F9138
+F81FC09039F9C00FE09039FB8007F0140001FE6D7EA25BA25BB3A4486C497EB500E0B512
+E0A32B3A7EB930>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA31207
+1203B3AA487EB512E0A313387EB718>I<EB01E0EB03F0EB07F8EB0FFCA4EB07F8EB03F0
+EB01E090C7FCA9EB01FC13FFA313071301B3B3A2123C127E00FF13F8130314F0A2387E07
+E0387C0FC0383FFF00EA0FFEEA03F8164984B71A>I<EA03F812FFA3120F1203B192B5FC
+A3ED7FF0ED3F80033EC7FC5D1578EC01E04A5A4A5A4AC8FC141E5C14FEEBF9FF13FB9038
+FFBF80EC1FC09038FC0FE013F86E7E6E7E6E7EA26E7E157F81826F7E8282486C14FCB539
+E07FFFC0A32A3A7EB92E>I<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>
+I<2703F803F8EB03F800FFD91FFFEB1FFF4A6D487F913BF81FC0F81FC03D0FF9C00FE1C0
+0FE03D03FB8007F38007F00200140001FED903FE6D7EA2495CA2495CB3A4486C496C497E
+B500E0B500E0B512E0A343257EA448>I<3903F803F800FFEB1FFF4A7F9138F81FC03A0F
+F9C00FE03A03FB8007F0140001FE6D7EA25BA25BB3A4486C497EB500E0B512E0A32B257E
+A430>I<EB01FE90380FFFC0013F13F09038FF03FC3901F8007E48487F4848EB1F804848
+EB0FC0A24848EB07E0003F15F0A248C7EA03F8A44815FCA96C15F8A26D1307003F15F0A2
+6C6CEB0FE0000F15C06C6CEB1F806C6CEB3F006C6C137E3900FF03FC90383FFFF0010F13
+C0D901FEC7FC26277EA52B>I<3903F807F800FFEB3FFE91B57E9039F9F03FC03A07FF80
+0FF06C90380003F85B496D7E496D7E82821780A3163F17C0A81780167FA217005E5E1501
+6D5C6D495A6D495A9039FB800FE09039F9F03FC001F8B5C7FCEC3FFEEC0FF091C9FCAB48
+7EB512E0A32A357EA430>I<3903F01F8000FFEB7FC0ECFFF0EBF1E3390FF387F8000313
+0713F79038F603F09038FE01E09038FC00C01500A25BB3A3487EB512F8A31D257EA422>
+114 D<90387F81803803FFF3000F13FF381F807F383E001F003C130F481307A200F81303
+A37E6C90C7FC6C7EEA7FF8EBFFC06C13F06C13FC6C7F6C7F00011480EA003F010113C0EB
+003F0060EB0FE000E01307A26C1303A37E15C06C13076C14806CEB0F00EBC07E38F3FFFC
+00E05B38C03FC01B277DA522>I<1338A51378A313F8A21201A212031207121FB61280A3
+D803F8C7FCB2EC01C0A93901FC0380A20000EB0700EB7F0EEB3FFEEB1FF8EB03F01A347E
+B222>I<D803F8EB03F800FF14FFA3000F140F00031403B3A41507A3150F12016D131B00
+00EC33FE903A7F01E3FFE090383FFFC36D1383903A03FE03F8002B267EA430>I<B539C0
+1FFF80A33B07FC0007FC006C48EB03F06F5A6C7E5E6D130300005DA2017F49C7FCA26E5A
+013F130EA26D6C5AA2ECE03C010F133814F001075BA2ECF8F001035B14FC903801FDC0A2
+14FF6D5BA26EC8FCA3143EA2141C29257EA32E>I<B53B8FFFF81FFF80A33D0FFC007FC0
+03FE006C4890393F8001F8715A0003021F5CA26C6C6E485A153FA26C6C6E485A1577A201
+7F9026F7F007C7FC15E302806D5AD93F81140E15C102C1EBFC1ED91FC3141C158002E3EB
+FE3C903A0FE7007E38A2D907F7EB7F7002FE133FA201035D4A131FA201015D4A130FA201
+005D4A1307A239257EA33E>I<B539E03FFFC0A300039039801FF800C69038000FE01680
+D97F8090C7FC90383FC01E011F5B14E06D6C5A6D6C5A903803F9E0ECFFC07F6D5B6EC8FC
+6E7E8181147FECF7F0903801E7F8ECC3FCEB03C190380780FE49487E011E6D7E011C6D7E
+013C131F017C80D801FC6D7E000F4A7EB590387FFFE0A32B247FA32E>I<B539C01FFF80
+A33B07FC0007FC006C48EB03F06D6D5A00015DA26D130300005D6D13076D91C7FCA29038
+3F800EA2ECC01E011F131C14E0010F5BA2ECF07801071370ECF8F001035BA2903801FDC0
+A214FF6D5BA26EC8FCA3143EA2141CA2143C143814781470A25C127C38FE01C0A2495A13
+074848C9FCEA783EEA3FFCEA1FF0EA0FC029357EA32E>I<001EEB0780003FEB0FC0397F
+801FE0EBC03F00FF14F0A2007F14E0EB801F393F000FC0001EEB07801C0A79B72B>127
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fg hz3cmr10 10 23
+/Fg 23 128 df<913907F801F891397FFE0FFE49B5EA3FFF903B07F80FFF1F8090270FE0
+07FC13C0903A1F800FF83F90383F001F4914F001FEED1F8092390FE00F004992C7FC1201
+ACB812F0A32801FC000FE0C7FCB3AB486C497E267FFFE1B512E0A3323B7FBA2F>11
+D<B812F0A30001903880003F6C90C71207EE03F8160116001778A21738A4173C171CA215
+07A21700A45DA25D157F91B5FCA3EC007F151F81A281A692C8FCAD4813C0B612C0A32E39
+7DB835>70 D<90390FF0018090387FFE0390B512833903F80FC73907C001EF390F8000FF
+48C7127F153F003E141FA248140FA200FC1407A415037EA27E6C91C7FC7F7FEA3FF8EBFF
+806C13F06C13FF15E06C80000114FC6C80013F7F1307D9007F1380020713C01400ED3FE0
+151F150F16F01507126000E01403A57E16E0A26C14076C15C0A26CEC0F806CEC1F00D8FB
+C0131ED8F9F0137C39F0FE01F839E07FFFF0010F13C0D8C00190C7FC243D7CBA2D>83
+D<EB3FE03801FFF84813FE3807C07F390F801F80486C6C7E01E07F6E7EA26C486C7EEA07
+80EA0300C7FCA4EB01FF131FEB7FE33801FE03EA07F8EA0FF0EA1FC0123FEA7F80A2D8FF
+001438A41407A2387F800F140D3A3FC018FC703A1FE070FFF03A0FFFE07FE0000301C013
+C03A007F001F0025277DA529>97 D<EA03F812FFA3120F1203B0EC1FE0EC7FF89038F9FF
+FE9038FBE07F9039FF801F809039FE000FC049EB07E04914F0150316F8A2ED01FCA316FE
+AA16FCA2150316F8A2ED07F06D14E0150F6D14C001E7EB3F809039E3C0FF009038C1FFFC
+9038807FF0C7EA1FC0273B7EB92D>I<EB07FCEB1FFF017F13C09038FC03E03901F001F0
+3903E003F800071307EA0FC0121F90388003F0003FEB01E0EC00C0007F140090C8FCA25A
+AA7E7FA2003F141C7F001F1438120F6D13706C7E3903F801E03901FE07C039007FFF8090
+383FFE00EB07F81E277DA524>I<ED3F80EC0FFFA31400153FB0EB07F0EB1FFEEB7FFF39
+01FE07BF3903F801FF3807E000000F147F49133F121F485AA2127F90C7FCA25AAA7EA36C
+7EA2121F6D137F000F14FF6C7E2603F00313E03A01FC0FBFFE3900FFFE3FEB3FFCD90FE0
+1380273B7DB92D>I<EB07F0EB3FFE497E3901FC1FC03903F007E03907E003F013C0000F
+EB01F8EA1F80003F14FC1400A248C712FEA35A90B5FCA390C8FCA57EA27F123F150E121F
+6D131C120F6C6C13386C7ED801FC13F03900FF03E090387FFF80011F1300EB03F81F277E
+A524>I<ED03C090390FE01FF090387FFC3F9039FFFE78F83901F83FE13903E00F803A07
+C007C070000FECE00048486C7EA2003F80A7001F5CA26C6C485A00075C6C6C485AD9F83F
+C7FC3806FFFE380E7FFCEB0FE0000CC9FC121C121EA2121F6C7E90B57E15F06C14FC6C14
+FF16804815C0381F800048C7EA1FE0007E140716F0481403A5007EEC07E0A26CEC0FC06C
+6CEB1F80D80FE0EB7F003907FC03FE0001B512F86C6C13E0D907FEC7FC25387EA529>
+103 D<EA03F812FFA3120F1203B0EC0FE0EC3FF8EC7FFEECF07F9038F9C03FD9FB001380
+01FF131F4914C05BA35BB3A4486CEB3FE0B500E1B5FCA3283A7EB92D>I<EA03C0487E48
+7E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A313387FB716
+>I<EB01E0EB03F0EB07F8EB0FFCA4EB07F8EB03F0EB01E090C7FCA9EB01FC13FFA31307
+1301B3B3A2123C127E00FF13F8130314F0A2387E07E0387C0FC0383FFF00EA0FFEEA03F8
+164984B719>I<EA03F812FFA3120F1203B1913807FFF8A302011380EDFE00EC00F8EC01
+E05D4A5A4AC7FC140E5C5C1478EBF9FC13FBEBFFFE147F13FE496C7E496C7EA26E7E6E7E
+A26E7E1401816E7E157E157F1680486CEBFFE0B500E313FEA3273A7EB92B>I<EA03F812
+FFA3120F1203B3B3AD487EB512E0A3133A7FB916>I<2703F807F0EB1FC000FFD91FFCEB
+7FF0913A7FFF01FFFC913AF07F83C1FE3C0FF9C01F87007E2603FB8001CE137F9027FF00
+0FDC7F4902F81480495CA3495CB3A4486C496CEB7FC0B500E1B53887FFFEA33F257EA444
+>I<3903F80FE000FFEB3FF8EC7FFEECF07F390FF9C03F2603FB00138001FF131F4914C0
+5BA35BB3A4486CEB3FE0B500E1B5FCA328257EA42D>I<EB03FC90381FFF80017F13E090
+38FE07F03901F801F848486C7E4848137E48487F4848EB1F80A2003F15C090C7120F4815
+E0A34815F0AA6C15E0A26D131F003F15C0A2001F15806C6CEB3F006D5B6C6C13FE6C6C48
+5A3900FE07F090387FFFE0011F1380D903FCC7FC24277EA529>I<3803F07E00FF13FF01
+F113C0EBF38F390FF71FE0EA03F613FE9038FC0FC0EC0780EC030091C7FC5BB3A4487EB5
+12F8A31B257EA420>114 D<EBFF06000313CE000F13FEEA1F80383C003E007C131E1278
+A200F8130EA37E6C90C7FC7EEA7FF0EBFF806C13E06C7F6C7F6C7F00017F6C6C7E1303EB
+007F0060EB3F8000E0131FA26C130FA37E15006C5B141E6C133E38FF80FC38F3FFF800E1
+13E038C07F8019277DA520>I<1338A51378A313F8A21201A212031207121FB512FEA338
+03F800B21407A90001130E13FC1200EB7E1CEB3FF8EB1FF0EB07E018347EB220>I<D803
+F8EB1FC000FFEB07FFA3000FEB007F0003141FB3A5153FA30001147F15FF3A00FC01DFF0
+90397E039FFF90383FFF1FEB1FFED907F813C028267EA42D>I<B53A1FFFE0FFFCA3260F
+F8019038003FF06C486C48EB0FC06DED078000031700157E6D017F5B0001160EA26DEC80
+1E000002FF131CA26DECC03C6D48143815CFD93F816D5A14831587D91FC36D5A14C71503
+D90FE7EBF9C0ECEE01A2D907FEEBFF804A7EA2010392C7FC4A7FA20101147E4A133EA201
+00143C4A131C36257EA33B>119 D<001C1338007F13FE38FF81FFA6387F00FE001C1338
+180A78B729>127 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fh hz4cmr10 10 36
+/Fh 36 128 df<DA07FE137E913A3FFF83FF8091B500CF13C0903B03FC03FFC7E090260F
+E001EB07F0903A1FC003FE0F90383F8007D97F0013FC017EED07E001FE903903F803C049
+92C7FC1201ACB812FCA32801FC0003F8C7FCB3AB486C497E267FFFF0B512F8A3343B7FBA
+31>11 D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA
+0700A2120E5A123C123812100B1A79B918>39 D<121E123FEA7F80EAFFC0A213E0A2127F
+123F121E1200A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A798918>44
+D<B512FCA616067F941C>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A798918>
+I<153CA3157EA315FFA34A7FA24A7F15BFA202077F151FA2020F7FEC0E0FA2021E7FEC1C
+07A2023C7FEC3803A202787FEC7001A202F07F4A7EA20101814A137FA2494880163FA249
+C76C7E91B6FCA24981010EC7120FA2496E7EA3496E7EA3496E7EA301F06E7E1201486C16
+80D80FFE020313C0B500C0017F13FFA3383C7DBB3F>65 D<B812FCA30001903880001F6C
+90C71201EE00FE177E173E171EA2170EA4170F1707A2ED01C0A21700A41503A21507151F
+91B5FCA3EC001F15071503A21501A692C8FCAD4813C0B612C0A330397DB837>70
+D<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81F>73
+D<D90FF013C090387FFE0190B512813903F80FC33907C001E7390F80007748C7123F151F
+003E140FA2481407A200FC1403A415017EA27E6C91C7FC7F7FEA3FF8EBFF806C13F06C13
+FF15E06C80000114FC6C80013F7F1307D9007F1380020713C01400ED3FE0151F150F16F0
+1507126000E01403A57E16E0A26C14076C15C0A26CEC0F806CEC1F00D8FBC0131ED8F9F0
+137C39F0FE01F839E07FFFF0010F13C0D8C00190C7FC243D7BBA2F>83
+D<003FB812F0A3D9E003EB001F90260001FE1303007EEE01F8007C160000781778A30070
+1738A400F0173C48171CA4C71600B3B0913807FF80011FB612E0A336397DB83D>I<007F
+B590383FFFFEA3C601F8010713C0D97FE0D901FEC7FC013F15F86D6C6D5A4C5A6D6C5C6D
+6C13034C5A6D6C91C8FC6D6C5B161E6DEB801C91387FC03C5E91383FE07091381FF0F0ED
+F1E091380FF9C0EC07FF5E6E90C9FCA2806E7FA26F7E8215FF82913801CFF81403ED87FC
+91380703FE140F91380E01FF4A6C7F143C02386D7E4A6D7E14F04A6D7E495A01036E7E4A
+6D7E49C7FC496E7E010E6E7E131E013E6E7F01FF8200076D01037FB500F0011FEBFFC0A3
+3A397EB83F>88 D<EB3FE03801FFFC000713FF390FC03F80391F000FC0486C6C7E01C07F
+6E7EA2381F8001D80F007F1206C7FCA414FF130FEB7FF13801FF01EA07F8EA0FF0EA1FE0
+EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC01C7E383A1FF0787FF83A0F
+FFF03FF0000301E013E03A007F000F8026277DA52A>97 D<EA03F812FFA3120F1203B0EC
+0FF0EC3FFE91B5FC9039FBF03FC09039FF800FE091380003F001FC80150149806F7EA282
+82A21780A91700A316FEA25E15016D5C6D495A6D495A9039E7800FC09039E3E03F8001C0
+B5C7FC9038807FFCC7EA0FE0293B7EB92F>I<EB03FE90381FFFC0017F13F09038FE01F8
+3901F8007C484813FE3807E001EA0FC0121FEC00FC484813781530007F140090C8FCA25A
+A97EA27F123F15076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F090387FFF
+C0011F1380903803FC0020277DA526>I<ED0FE0EC03FFA3EC003F150FB0EB03F8EB1FFF
+017F13CF9038FE03EF3901F800FF4848133F4848131F485A001F140F5B123FA248C7FCA3
+5AA97EA27F123FA26C6C131F120F6D133F0007147F3A03F801EFF83B01FE07CFFF803900
+7FFF8F90381FFE0FD907F8EBE000293B7DB92F>I<EB03FCEB1FFF017F13C09038FE0FE0
+3901F803F03903E001F800076D7E4848137E121F49137F003F80A248C7FC1680A25A90B6
+FCA390C9FCA57EA27F123FED03806C7EED07006C7E0007140ED803F85B6C6C5B3900FF80
+F090383FFFE0010F1380D901FEC7FC21277EA526>I<143F903801FFC0010713E090380F
+E3F090381F83F8EB3F07137F137E9038FE03F09038FC01E0000190C7FCADB512FEA3D801
+FCC7FCB3AB487E387FFFFCA31D3B7FBA1A>I<ED03E090390FF00FF090393FFC1FF890B5
+EA3C7C3A01F81FF0FC3A03E007C07C3A07C003E038000FECF000001F80EB8001003F80A7
+001F5CEBC003000F5C00075C6C6C485A9038F81F800006B5C7FCEB3FFC380E0FF0000CC9
+FC121EA3121F6C7E90B512C015F86C14FE6CECFF8016C04815E0391F80007F48C7EA0FF0
+007E140316F8481401A5007EEC03F0A26CEC07E06C6CEB0FC0D80FE0EB3F803A07FC01FF
+000001B512FC6C6C13F0010790C7FC26387EA52A>I<EA03F812FFA3120F1203B0EC07F8
+EC1FFEEC7FFF9138F03F809039F9C00FC0D9FB807F140001FE6D7EA25BA25BB3A4486C49
+7EB500E1B512C0A32A3A7EB92F>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01
+F812FFA312071203B3AA487EB512E0A313387EB718>I<EB01E0EB03F0EB07F8EB0FFCA4
+EB07F8EB03F0EB01E090C7FCA9EB01FC13FFA313071301B3B3A2123C127E00FF13F81303
+14F0A2387E07E0387C0FC0383FFF00EA0FFEEA03F8164984B71A>I<EA03F812FFA3120F
+1203B1913801FFFEA36E13E06FC7FC157E15785D4A5A4A5A4AC8FC141E5C147C14FCEBF9
+FEEBFBFF9038FF3F8013FE496C7E496C7E1407816E7E6E7EA26E7E157F81826F7E82486C
+EB3FF8B500E0B51280A3293A7EB92D>I<EA03F812FFA3120F1203B3B3AD487EB512E0A3
+133A7EB918>I<2703F803F8EB03F800FFD91FFFEB1FFF4A6D487F913BF81FC0F81FC03D
+0FF9C00FE1C00FE03D03FB8007F38007F00200140001FED903FE6D7EA2495CA2495CB3A4
+486C496C497EB500E0B500E0B512E0A343257EA448>I<3903F807F800FFEB1FFEEC7FFF
+9138F03F803A0FF9C00FC02603FB807F140001FE6D7EA25BA25BB3A4486C497EB500E1B5
+12C0A32A257EA42F>I<EB03FE90380FFF80013F13E09038FE03F83901F800FC4848137E
+48487F4848EB1F80001F15C049130F003F15E0A248C7EA07F0A44815F8A96C15F0A26D13
+0F003F15E0A26C6CEB1FC0000F15806D133F6C6CEB7F006C6C13FE3900FE03F890387FFF
+F0011F13C0D903FEC7FC25277EA52A>I<3903F80FF000FFEB3FFE91B5FC9039FBF03FC0
+3A07FF800FE06C496C7E01FC6D7EA2496D7E82150082A3EE7F80A917005EA25E15015EA2
+6D495A6D495A6D495A6E485A9039FBE07F8001F8B5C7FCEC7FFCEC0FE091C9FCAB487EB5
+12E0A329357EA42F>I<3803F03F00FFEB7F809038F1FFE014C7390FF38FF03803F70F13
+F69038FE07E09038FC03C0EC018091C7FCA25BB3A3487EB512F8A31C257EA421>114
+D<EBFF83000313E7000F13FFEA1F80383E003F487F00787FA200F87FA37E6C90C7FC6C7E
+EA7FF8EBFF806C13E06C13F86C7F6C7F00017F6C7E01031380EB003F0060EB1FC000E013
+0FA26C1307A37E15806C130F1500B4131EEBC07C38F3FFF800E15B38C07F801A277DA521
+>I<131CA5133CA3137CA213FC120112031207121FB61280A3D801FCC7FCB215E0A93900
+FE01C0A290387E038090383F87006DB4FCEB0FFCEB01F81B347FB221>I<D803F8EB07F0
+00FFEB01FFA3000FEB001F00031407B3A4150FA3151F120115376C6CEB77FC903A7F01E7
+FFC090383FFFC76D1307D903FCEBF0002A267EA42F>I<B538C03FFFA33A07FC000FF86C
+48EB03E016C07F000115807F0000EC0700A26D5B6D130EA26D6C5AA2ECC03C011F1338A2
+6D6C5AA2ECF0F001075BA214F901035B14FD6DB45AA36D90C7FCA2147EA3143CA228257E
+A32D>I<B53A8FFFF03FFFA3260FF8009038800FFC000791397F0003F0EF01E000036E14
+C0A26C6C9138800380A36C6C9138C00700157FA2017F9038FFE00E15E70280141ED93F81
+EBF01C15C302C1EBF83CD91FC31438158102E3EBFC7890260FE7001370A2D907F76D5A02
+FE137EA20103EC7FC04A133FA201015D4A131FA2010092C7FC4A7F0270130E38257EA33D
+>I<B539E07FFF80A300039039803FF000C69038001FC093C7FC90387F801E013F131CEC
+C03C6D6C5A010F5B903807F1E0ECF9C0EB03FF6D5B6D90C8FCA26E7E143F4A7E4A7E81EB
+01E7903803C7F890380783FCEC01FEEB0F00011E7F496D7E0138133F01F86D7E486C8000
+0F4A7EB590B512C0A32A247FA32D>I<B538C03FFFA33A07FC000FF86C48EB07E0ED03C0
+6C7E16806D130700001500A2017F130EA2EC801E013F131CA26D6C5AA2ECE078010F1370
+A26D6C5AA214F901035BA26DB45AA36D90C7FCA2147EA3143CA21438A214781470A25CA2
+EA7C0100FE5B1303495A91C8FCEAFC1FEA783EEA3FFCEA1FF0EA0FC028357EA32D>I<00
+1E130F003FEB1F80397F803FC0EBC07F00FF14E0A2007F14C0EB803F393F001F80001EEB
+0F001B0A79B72A>127 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fi cmr10 10 38
+/Fi 38 128 df<DA07FC13FC91393FFF07FF49B5009F1380903B03FC07FF8FC0903B0FE0
+03FE0FE0903A1FC007FC1F90383F800FD97F0013F8017EED0FC001FE903907F007804992
+C7FC1201ACB812F8A32801FC0007F0C7FCB3AB486C497E267FFFE0B512F0A3333B7FBA30
+>11 D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA07
+00A2120E5A123C123812100B1A7AB917>39 D<121E123FEA7F80EAFFC0A213E0A2127F12
+3F121E1200A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A7A8917>44
+D<B512FCA616067F941C>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A7A8917>
+I<1538157CA315FEA34A7EA34A7FA34A7F153FA2020F7FEC0E1FA2021E7FEC1C0FA2023C
+7FEC3807A202787FEC7003A202F07FECE001A20101804A7EA20103814A137FA201078191
+C7123F91B6FC4981A2010EC7121F011E81011C140FA2013C8101381407A2017881017014
+03A201F08116011201486C81D80FFE02071380B500C090B512FEA3373C7DBB3E>65
+D<B812FCA30001903880001F6C90C71201707E177E173E171EA2170EA4170F83ED01C0A3
+94C7FCA31503A21507151F91B5FCA3EC001F15071503A21501A218E0A3170192C713C0A4
+1703A3EF0780A2170FA2171F173F17FF486D010F1300B9FCA333397DB839>69
+D<B812F8A30001903880001F6C90C71203EE01FC1600177C173CA2171CA4171E170EA2ED
+0380A21700A41507A2150F153F91B5FCA3EC003F150F1507A21503A692C8FCAD4813C0B6
+12C0A32F397DB836>I<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81E>73
+D<D90FF813C090383FFE0190B512813901F80FE33907E001F7390F80007F90C7123F4814
+1F003E140FA2481407A200FC1403A415017EA27E6C91C7FC7F13E0EA3FF8EBFF806C13F8
+6CEBFF806C14E06C14F86C806C80013F7F01071480D9007F13C0020713E0EC007FED1FF0
+150F150716F81503126012E01501A47E16F0A26C14036C15E0A26CEC07C06CEC0F80D8FB
+C0EB1F00D8F9F0133ED8F0FF13FC39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>83
+D<003FB812E0A3D9E003EB003F90260001FE1307007EEE03F0007C160100781600A30070
+1770A400F01778481738A4C71600B3B0913807FF80011FB612E0A335397DB83C>I<007F
+B590387FFFFCA3C601F8010F1380D97FE0D903FCC7FC013FEC01F06D6C5C5F6D6C13036D
+6C495A94C8FC6D6C5B161E6D6C131C6DEB803C5E91387FC07091383FE0F0EDE1E091381F
+F1C0EC0FF3EDFB806EB4C9FCA26E5A6E7EA26E7F6F7E15FF825C913803DFF0ED8FF81407
+91380F07FC91380E03FE141E91381C01FF4A7E02788002706D7E14F049486D7E4A6D7E13
+0349486D7E91C76C7E5B011E6E7E1601013E8101FF8200076D01077FB500F0013FEBFF80
+A339397EB83E>88 D<EB3FE0EBFFFC000313FF3907C03F80390F800FC0486C6C7E01E07F
+6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7FF13801FF01EA07F8EA0FF0EA1F
+E0EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC01C7E383A1FF0787FF83A
+0FFFF03FF0000301E013E03A007F000F8026277DA52A>97 D<EA03F812FFA3120F1203B0
+EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC09039FE0007E049EB03F0A249EB
+01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F86D14F0ED07E06DEB0FC09039
+E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0283B7EB92E>I<EB03FC9038
+1FFF80017F13E09038FE01F03901F800F83903F001FC3807E003EA0FC0121F90388001F8
+003FEB00F01560007F140090C8FCA25AA97EA27FA2003F140E7F001F141C6C7E00071438
+6C7ED801FC13F03900FF03E090387FFFC0011F1300EB07F81F277DA525>I<ED1FC0EC07
+FFA3EC007F151FB0EB07F8EB1FFE90387FFF9F9038FE07DF3901F800FF4848137F484813
+3F4848131F121F485AA2127F90C7FCA35AA97EA27F123FA2121F6C6C133F157F6C6C13FF
+3A03F001DFF03A01FC079FFF39007FFF1FEB3FFED907F013C0283B7DB92E>I<EB07F8EB
+1FFF017F13809038FC0FC03901F003E03903E001F0000714F8390FC000FC121F4913FE00
+3F147EA248C7127FA35A90B6FCA390C8FCA57EA27F123F15076C7E150E6C7E0007141C6C
+6C133CD801FC13783900FF01F090383FFFC06D1380903803FC0020277EA525>I<147E90
+3803FF80010F13C090381FC7E090383F07F0EB7E0F13FE13FC0001EB07E09038F803C000
+0390C7FCADB512FCA3D803F8C7FCB3AB487EB512F8A31C3B7FBA19>I<ED03E090390FF0
+0FF090393FFC1FF890B5EA3C7C3A01F81FF0FC3A03E007C07C3A07C003E038000FECF000
+001F80EB8001003F80A7001F5CEBC003000F5C00075C6C6C485A9038F81F800006B5C7FC
+EB3FFC380E0FF090C9FC121EA3121F6C7E90B512C015F86C14FE6CECFF8016C04815E039
+1F80007F48C7EA0FF0007E140316F8481401A5007EEC03F0A26CEC07E06C6CEB0FC0D80F
+E0EB3F803A07FC01FF000001B512FC6C6C13F0010790C7FC26387EA52A>I<EA03F812FF
+A3120F1203B0EC07F0EC1FFCEC7FFF9138F07F809038F9C01FD9FB807F9038FF000F4980
+5BA35BB3A4486C497EB500E1B51280A3293A7EB92E>I<EA03C0487E487E487EA46C5A6C
+5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A313387EB718>I<EB01E0EB03
+F0EB07F8EB0FFCA4EB07F8EB03F0EB01E090C7FCA9EB01FC13FFA313071301B3B3A2123C
+127E00FF13F8130314F0A2387E07E0387C0FC0383FFF00EA0FFEEA03F8164984B719>I<
+EA03F812FFA3120F1203B1913803FFFCA36E13C0913800FE005D15F04A5A4A5A4A5A4AC7
+FC141E5C5C14FCEBF9FE13FBEBFF7F496C7EEBFC1F01F87F6E7E6E7EA26E7E6E7EA26E7E
+157FA2ED3F8016C0486CEB7FF0B500E1B5FCA3283A7EB92C>I<EA03F812FFA3120F1203
+B3B3AD487EB512E0A3133A7EB918>I<2703F807F8EB0FF000FFD91FFEEB3FFCDA7FFFEB
+FFFE913AF03F81E07F3D0FF9C00FC3801F802603FB80D9E7007F020013E601FED907FC6D
+7EA2495CA2495CB3A4486C496C497EB500E1B500C3B51280A341257EA446>I<3903F807
+F000FFEB1FFCEC7FFF9138F07F80390FF9C01F2603FB807F9038FF000F49805BA35BB3A4
+486C497EB500E1B51280A329257EA42E>I<EB03FE90380FFF80013F13E09038FE03F839
+01F800FC4848137E48487F4848EB1F80001F15C049130F003F15E0A248C7EA07F0A44815
+F8A96C15F0A26D130F003F15E0A26C6CEB1FC0000F15806D133F6C6CEB7F006C6C13FE39
+00FE03F890387FFFF0011F13C0D903FEC7FC25277EA52A>I<3903F80FE000FFEB7FFC90
+38F9FFFE9039FBE07F803A07FF801FC03A03FE000FE049EB07F0A249EB03F816FC150116
+FEA3ED00FFA916FE1501A316FC150316F86DEB07F0ED0FE06D14C09039FF803F809039FB
+E07F009038F9FFFE9038F87FF8EC1FC091C8FCAB487EB512E0A328357EA42E>I<3803F0
+3F00FFEB7F809038F1FFE014C7390FF38FF03803F70F13F69038FE07E09038FC03C0EC01
+8091C7FCA25BB3A3487EB512F8A31C257EA421>114 D<EBFF83000313E7000F13FFEA1F
+80383E003F487F00787FA200F87FA37E6C90C7FC6C7EEA7FF8EBFF806C13E06C13F86C7F
+6C7F00017F6C7E01031380EB003F0060EB1FC000E0130FA26C1307A37E15806C130F1500
+B4131EEBC07C38F3FFF800E15B38C07F801A277DA521>I<131CA5133CA3137CA213FC12
+0112031207121FB6FCA3D801FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D
+5AEB03F01A347FB220>I<D803F8EB0FE000FFEB03FFA3000FEB003F0003140FB3A5151F
+A2153F1201156F6C6CEBEFF8903A7E03CFFF8090383FFF8F6D130FD903FCEBE00029267E
+A42E>I<B538C07FFEA33A0FFC001FF0D803F8EB07C016807F00011500A26D5B0000140E
+A2017F5BA2EC803C013F1338A26D6C5AA214E0010F5BA214F101075BA2903803FB80A214
+FF6D90C7FCA36D5AA2147CA3143827257EA32C>I<B53A8FFFF07FFEA3260FF800903880
+0FF8000791397F0007E0EF03C000031780816DEC80070001027F1400A26D6E5A000002FF
+130E15EF6DECE01ED97F01141C15C70281EBF03CD93F8314381583D91FC36D5AECC701A2
+D90FE76D5AECEE00A2D907FEEBFFC04A137FA201035D4A133FA2010192C7FC4A7FA20100
+141E4A130E37257EA33C>I<B500C0B5FCA300039038007FF06C48EB3F806C6C013EC7FC
+6D133CEB3F806E5A011F5B6D6C5A14F1903807FBC06DB45A6D90C8FCA26D5A147F818114
+FF497FECCFF0EB03C790380783F890380F03FCEB0E0190381E00FE497F496D7E01F8133F
+000181D80FFC497EB548B51280A329247FA32C>I<B538C07FFEA33A07FC001FF06C48EB
+07C016807F00011500A26C6C130EA26D131E6D131CA26D6C5AA2ECC078011F1370A2ECE0
+F0010F5B14F0903807F1C0A214FB01035BA26DB4C7FCA36D5AA2147CA31438A214781470
+A25CA21301007C5BEAFE035C130749C8FCEAFC1EEA783CEA3FF86C5AEA0FC027357EA32C
+>I<BD12C0A35203809753>124 D<001C131C007F137F39FF80FF80A6397F007F00001C13
+1C190A78B72A>127 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fj cmbx12 12 23
+/Fj 23 121 df<BA1280A419C0D8003F90C7123F17031700187F183F181F180F19E01807
+A31803A3EE03E0F001F0A495C7FC1607A3160F161F167F92B5FCA5ED007F161F160F1607
+A31603A693C9FCAFB712F8A53C447CC346>70 D<923807FFC092B512FE0207ECFFC0021F
+15F091267FFE0013FC902601FFF0EB1FFF010701C0010713C04990C700017F49486E7F49
+486F7E49486F7E49486F7E488448496F13804A814819C04A814819E0A24890C96C13F0A2
+4819F8A348487013FCA500FF19FEAD007F19FCA26D5EA26C19F8A36C6D4B13F0A36C6D4B
+13E0A26C6D4B13C06C19806E5D6C19006C6D4B5A6D6C4B5A6D6C4B5A6D6C6C01035B6D6D
+495B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002004AC8FC030713
+C047467AC454>79 D<DAFFE0130C010701FE131C013F9038FF803C49ECE07C48B6EAF0FC
+489038801FFD3A07FE0003FFD80FF813004848143F49141F003F150F160748481403A216
+0112FF1600A27F177C7FA27F01FE92C7FC6C6C7E14F8ECFFC06C14FCEDFFC06C15F86C81
+16FF6C826C826C826C82013F81010F811303D9003F801403DA001F7F15016F7E041F1380
+8282127800F881A282A27EA218007EA26C4B5AA26D5D01E014076D5D01FC4A5AD9FF80EB
+3FE0489039F801FFC0D8FC3FB65A486C92C7FCD8F00714FC48C614F0480107138031467A
+C43E>83 D<003FBA12E0A59026FE000FEBC003D87FF09338007FF049173F0180170F1907
+90C7FC007E1803A3007C1801A400FC19F8481800A5C81700B3B3A20107B87EA545437CC2
+4E>I<903801FFF0011F13FF017F14C048B612F04848C66C7ED807F8EB1FFC486C6D7E6D
+6D7E486C81818381836C5A6C5A6C5A6C5AC8FCA30203B5FC91B6FC1307013F13F19038FF
+FE01000313F0481380481300485A485A485AA2485AA45DA26C6C5BA26C6C010E13F86C6C
+013CEBFFC03A0FFF80F87F6CEBFFF06CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97
+D<EB3FE0B5FCA512037EB1ED0FFC92387FFFC002E3B512F002EF14FC9139FFE01FFE9238
+0007FF02FC010113804A15C04A6D13E04A147F18F018F8A2173F18FCA318FEAB18FCA4EF
+7FF8A218F0A2EFFFE06E15C06E4913806E5B023F90380FFE00903AFE1FE03FFCD9FC07B5
+5A496C14E049C61480C8D80FF8C7FC37467EC43E>I<EC3FF849B57E010F14E04914F890
+397FF007FC9039FFC001FE4849487E48495A484A1380485AA2485A123F6F13006F5A4848
+6D5A6F5A93C7FCA212FFAA127FA27FA2123FEE07C06C7EEE0F806C7E6CED1F006C7F6C6D
+133E6C01F013FC90397FFC03F86DB55A010F14C0010391C7FC9038003FF82A2F7CAD32>
+I<4CB4FC0307B5FCA5ED001F82B1EC3FF0903803FFFE010FEBFF8F013F14EF90267FF807
+B5FC3901FFC00148496C7E4890C77E49140F120F485AA2123FA2485AA412FFAA127FA412
+3F7F121FA2000F5D7F6C6C147F6C92B512806CD9C00314FE6C9038F01FEF013FB512CF6D
+140F010713FC9026007FC0EBF80037467CC43E>I<EC3FF849B5FC010F14C0013F14F090
+397FF01FF89039FFC007FC48496C7E48496C7E48481580000F80484815C0167F003F16E0
+A25B127FEE3FF0A212FFA290B7FCA401F8C9FCA5127FA36C7EA2001FED01F0A26C7EEE03
+E06C6C14076C6DEB0FC06C6DEB1F806C01F0EB3F0090397FFE01FE011FB55A010714F001
+0014C0DA1FFCC7FC2C2F7DAD33>I<DAFFE013FC010F9038FE03FF013FD9FF8F138090B8
+12C048D9C07F1307489039001FF87F4848EB0FFC000F9238FE3F80491307001F9238FF0E
+0094C7FC003F82A7001F93C7FCA2000F5D6D130F00075D6C6C495A6C9038C07FF091B55A
+481580D8078F49C8FC018013E0000F90CAFCA47FA213F090B612C016FC6CEDFF80836C16
+F0836C826C821203000F82D81FF0C77ED83FC01407007F6F1380498000FF81A56C6C4A13
+00A26C6C4A5A6D14076C6C4A5AD80FFEEC3FF83B03FFE003FFE06C90B65A6C6C92C7FC01
+0F14F8D9007F90C8FC32427DAC38>103 D<EB3FE0B5FCA512037EB1ED03FF031F13E04B
+13F892B57E9139E1F81FFE9139E3C00FFF9138E78007DAEE008002FE7F4A815CA25CA35C
+B3A7B600C1B61280A539457DC43E>I<137C48B4FC487F487FA2487FA56C5BA26C5B6C90
+C7FCEA007C90C8FCAAEB3FE0EA7FFFA512037EB3AFB61280A519467DC51F>I<EB3FE0B5
+FCA512037EB3B3B3A3B612C0A51A457DC41F>108 D<90277FC003FFEC07FEB5011F01E0
+90383FFFC04B01F84913F092B56C48B57E913DC1F81FFE03F03FFC913DC3C00FFF07801F
+FE00039026C7800790380F000F6CD9CE00029C8002DE6D01BC7F02DC03F8158002F85DA2
+4A5DA34A5DB3A7B600C1B60083B6FCA5582D7DAC5D>I<90397FC003FFB5011F13E04B13
+F892B57E9139C1F81FFE9139C3C00FFF00039038C780076CD9CE008002DE7F02DC8114F8
+A25CA35CB3A7B600C1B61280A5392D7DAC3E>I<EC1FFC49B512C0010714F0011F14FC90
+397FF80FFF9026FFC0017F48496C7F4890C76C7E48486E7E000F8249141F001F82A24848
+6E7EA2007F82A400FF1780AA007F1700A46C6C4A5AA2001F5EA26C6C4A5A00075E6D147F
+6C6D495A6CD9E0035B27007FF80F90C7FC6DB55A010F14F8010114C09026001FFCC8FC31
+2F7DAD38>I<90397FC03F80B5EBFFE002C113F802C313FC9138C7C7FEECCF0700039038
+CE0FFF6C13DE14FC14F8ED07FEA29138F003FCED00F01600A25CB3A6B612F0A5282D7EAC
+2E>114 D<90391FFC038090B5128F000314FF5A380FF003381FC0004848133F48C7FC15
+1FA248140FA27FA26D90C7FC13F0EBFF806C13FCECFF806C14E015F86C806C806C801201
+6C1580011F14C01301D9000F13E014010078EB007F00F8143FA26C141FA36C15C0A27E6D
+EB3F807F6DEBFF009038FC03FE90B55A00F814F0D8F03F5B26E007FEC7FC232F7CAD2C>
+I<EB03E0A61307A3130FA3131FA2133F137F13FF5A5A001F90B51280B7FCA4000101E0C7
+FCB3A3ED03E0AA6CEC07C014F0017F1480ECF80F90393FFC1F0090381FFFFE6D5B010313
+F09038007FC023407EBE2C>I<D93FE0EC7FC0B549B5FCA50003EC00076C81B3A85EA35E
+7E5E043B7F6D6C017BEBFF8090393FFC03F36DB512E36D1483010314039026003FF849C7
+FC392E7DAC3E>I<B6398007FFFCA5000101F0C7EA7E006C167C8017FC017F5D6E130101
+3F5D6E1303011F5D6E13076D5D1580160F6D01C05B161F6D92C7FC6F5A6D143EEDF07E6D
+147C15F816FC6E6C5A15FD023F5B15FF6E5BA26E5BA36E5BA26E90C8FCA26E5AA26E5AA2
+362C7EAB3B>I<B6000FB539C03FFFF0A500019027E0007FF0C7EAF800707E6E16016C6F
+6C5C80017F4D5A836E013F1407013F6F5C804C140F011F04805B6E90B5131F6D02F901C0
+90C7FC158003815D6D02F0EBE03E03C3157E6D9139E07FF07C15E303E715FC6D4A6C6C5A
+03FF14F96D9139801FFDF0A218FF6E496C5BA26E486D5BA36E486D5BA26E486D90C8FCA3
+6E486D5AA26E48147C4C2C7EAB51>I<B690B512F0A5C601F8903807E0006D6C495A013F
+141F6E495A6D6C49C7FC6DEB80FE6D6D5AEDC1F86DEBE3F06D13F76DEBFFE06E5B5E6E90
+C8FC806E7FA26E7F6E7F4A7F5C4A7F4A7F91387F3FFE91387E1FFF14FC49486C7F01036D
+7F49486C7F49487E02C08049486C7F49C76C7E496E7EB5D8F003B512FCA5362C7EAB3B>
+I E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 0 531 a Fj(Original)0 685 y Fi(This)51 b(is)g(a)h(test)g
+(paragraph)e(for)h(T)1221 702 y(E)1267 685 y(X's)i(paragraph-)0
+784 y(breaking)48 b(algorithm.)102 b(It)51 b(is)f(a)g(fairly)e(complex)
+h(al-)0 884 y(gorithm,)69 b(nev)n(ertheless)61 b(impro)n(v)n(emen)n(ts)
+e(seem)i(p)r(os-)0 983 y(sible.)199 b(As)83 b(y)n(ou)e(will)f(note,)96
+b(I)82 b(stu\013ed)i(this)0 1083 y(paragraph|longnon)n(breaki)o(ngw)m
+(or)o(d|with)20 b(long)j(non-)0 1183 y(breaking)36 b(w)n(ords)i(just)h
+(to)g(mak)n(e)e(the)i(algorithm)34 b(w)n(ork)0 1282 y(harder)c(and)h
+(to|longnon)n(breakingw)n(ord|sho)m(w)25 b(some)0 1382
+y(impro)n(v)n(emen)n(ts)i(that)33 b(can)e(b)r(e)i(had)f(b)n(y)f(allo)n
+(wing)d(fon)n(t|)0 1482 y(longnon)n(breakingw)n(ord|wi)o(dth)22
+b(v)-5 b(ariations.)0 1713 y Fj(Three)38 b(v)-6 b(arian)m(ts)0
+1867 y Fh(This)48 b(is)g(a)h(test)f(paragraph)h(for)g(T)1215
+1885 y Fi(E)1261 1867 y Fh(X's)g(paragraph-)0 1966 y(breaking)e
+(algorithm.)95 b(It)47 b(is)h(a)g(fairly)f(complex)e(al-)0
+2066 y(gorithm,)61 b(nev)n(ertheless)54 b(impro)n(v)n(emen)n(ts)e(seem)
+h(p)r(os-)0 2166 y(sible.)193 b(As)81 b(y)n(ou)e(will)g(note,)93
+b(I)79 b(stu)p Fi(\013)p Fh(ed)i(this)0 2265 y Fi(para)p
+Fg(g)p Fi(raph|)p Fg(l)p Fi(ongnon)n Fg(b)p Fi(reakingw)n
+Fg(o)p Fi(r)o(d|wi)o(th)23 b Fg(l)p Fi(ong)k(n)p Fg(o)p
+Fi(n-)0 2365 y Fh(breaking)34 b(w)n(ords)h(just)g(to)f(mak)n(e)f(the)h
+(algorithm)f(w)n(ork)0 2464 y Fi(h)p Fh(a)p Fi(rd)p Fh(e)p
+Fi(r)27 b(a)p Fh(n)p Fi(d)g(to|)p Fg(l)p Fi(on)p Fh(g)p
+Fi(no)p Fh(n)n Fi(br)p Fh(e)p Fi(ak)p Fh(i)p Fi(n)p Fh(g)p
+Fi(w)n(o)p Fh(r)p Fi(d|)p Fh(sh)p Fi(o)n(w)e Fh(s)p Fi(om)p
+Fh(e)0 2564 y(impro)n(v)n(em)p Fi(e)p Fh(n)n(ts)f(that)j(can)h(b)r(e)g
+(had)g(b)n Fi(y)f Fh(allo)n(wing)g(fon)n(t)p Fi(|)0 2664
+y Fh(longnon)n(breakingw)n(ord)p Fi(|)p Fh(width)h(v)-5
+b(ariations.)0 2896 y Fj(Fiv)m(e)38 b(v)-6 b(arian)m(ts)0
+3049 y Ff(This)44 b(is)g(a)g(test)g(paragraph)g(for)g(T)1208
+3067 y Fi(E)1255 3049 y Ff(X's)g(paragraph-)0 3148 y(breaking)g
+(algorithm.)87 b(It)45 b(is)f(a)h(fairly)f(complex)h(al-)0
+3248 y(gorithm,)36 b(nev)n(ertheless)f(impro)n(v)n(emen)n(ts)e(seem)i
+(p)r(ossi-)0 3348 y(ble.)44 b(As)29 b(y)n(ou)g(will)h(note,)h(I)f(stu)p
+Fi(\013)p Ff(ed)g(this)f(paragraph)p Fi(|)0 3447 y Fe(longnon)n(b)p
+Fg(r)p Fe(eakingw)n(ord)p Fi(|)p Fe(w)p Fg(i)p Fe(th)g(long)f(non)n
+(break)p Fg(i)p Fe(ng)h(w)n(ords)0 3547 y Ff(just)53
+b(to)f(mak)n(e)g(the)h(algorithm)f(w)n(ork)g(harder)h(and)0
+3647 y(to)p Fi(|)p Ff(longnon)n(breakingw)n(ord)p Fi(|)p
+Ff(sho)n(w)40 b(some)g(impro)n(v)n(e-)0 3746 y(men)n(ts)65
+b(that)g(can)h(b)r(e)h(had)f(b)n(y)e(allo)n(wing)j(fon)n(t)p
+Fi(|)0 3846 y Ff(longnon)n(breakingw)n(ord)p Fi(|)p Ff(width)28
+b(v)-5 b(ariations.)0 4078 y Fj(Sev)m(en)38 b(v)-6 b(arian)m(ts)0
+4231 y Fd(This)23 b(is)f(a)h(test)f(paragraph)h(for)f(T)988
+4249 y Fi(E)1035 4231 y Fd(X's)g(paragraph-breaking)0
+4331 y(algo)p Fe(r)p Fd(ithm)p Fe(.)36 b Fd(It)29 b(is)e(a)h
+Fe(f)p Fd(airly)f(c)p Fe(o)p Fd(mplex)f(a)p Fe(l)p Fd(gor)p
+Fe(i)p Fd(thm)p Fe(,)i Fd(nev)n(e)p Fe(r)p Fd(the-)0
+4430 y Fe(less)h Fd(i)p Fe(mpro)n Fd(v)n Fe(emen)n(ts)g(se)p
+Fd(e)p Fe(m)g(p)r(oss)p Fd(i)p Fe(ble.)39 b(A)p Fd(s)27
+b Fe(y)n(ou)h(w)p Fd(i)p Fe(ll)f(note)p Fd(,)h Fe(I)0
+4530 y(stu)p Fi(\013)p Fe(ed)h(th)p Fg(i)p Fe(s)g(pa)p
+Fg(r)p Fe(agrap)p Fg(h)p Fi(|)p Fe(lon)p Fg(g)p Fe(non)n(b)p
+Fg(r)p Fe(eak)p Fg(i)p Fe(ngw)n Fg(o)p Fe(rd)p Fi(|)p
+Fe(w)p Fg(i)p Fe(t)p Fg(h)0 4629 y(long)f(n)p Fi(o)p
+Fg(n)n(breaking)g(w)n Fi(o)p Fg(rds)e(just)i(to)f(m)p
+Fi(a)p Fg(k)n(e)g(the)h(a)p Fi(l)p Fg(gorithm)0 4729
+y Fi(w)n Fh(or)p Fi(k)f Fh(h)p Fi(ar)p Fh(d)p Fi(e)p
+Fh(r)g Fi(a)p Fh(n)p Fi(d)g Fh(t)p Fi(o|)p Fg(l)p Fi(o)p
+Fh(n)p Fi(g)p Fh(n)p Fi(on)n Fh(b)p Fi(r)p Fh(e)p Fi(a)p
+Fh(k)p Fi(in)p Fh(g)p Fi(w)n Fh(o)p Fi(r)p Fh(d)p Fi(|)p
+Fh(sh)p Fi(o)n Fh(w)0 4829 y Ff(s)p Fc(o)p Ff(m)p Fc(e)h
+Ff(i)p Fc(m)p Ff(pro)n Fc(v)n Ff(e)p Fc(m)p Ff(en)n Fc(t)p
+Ff(s)f(t)p Fc(h)p Ff(a)p Fc(t)g Ff(ca)p Fc(n)h Ff(b)r
+Fc(e)g Ff(h)p Fc(a)p Ff(d)g Fc(b)n Ff(y)f(a)p Fc(ll)p
+Ff(o)n Fc(w)p Fh(i)p Fc(n)p Ff(g)0 4928 y Fc(fon)n(t)p
+Fi(|)p Fc(longnon)n(breakingw)n(ord)p Fi(|)p Fc(width)h(v)-5
+b(ariations.)0 5160 y Fj(Sev)m(en)38 b(smaller)h(v)-6
+b(arian)m(ts)0 5313 y Fd(This)22 b(is)g(a)g(test)g(paragraph)h(for)e(T)
+985 5331 y Fc(E)1035 5313 y Fd(X's)h(paragraph-breaking)0
+5413 y(alg)p Fe(o)p Fd(rithm)p Fe(.)36 b Fd(It)28 b(is)f(a)h(fair)p
+Fe(l)p Fd(y)f(com)p Fe(p)p Fd(lex)f(algo)p Fe(r)p Fd(ithm)p
+Fe(,)h Fd(nev)n Fe(e)p Fd(rthe-)1918 531 y Fe(less)i
+Fd(i)p Fe(mpro)n(v)n Fd(e)p Fe(men)n(ts)f(se)p Fd(e)p
+Fe(m)h(p)r(oss)p Fd(i)p Fe(ble.)39 b(A)p Fd(s)27 b Fe(y)n(ou)h(w)p
+Fd(i)p Fe(ll)f(note)p Fd(,)h Fe(I)1918 631 y(stu)p Fc(\013)p
+Fe(ed)h(th)p Fg(i)p Fe(s)g(pa)p Fg(r)p Fe(agrap)p Fg(h)p
+Fc(|)p Fe(lon)p Fg(g)p Fe(non)n(b)p Fg(r)p Fe(eak)p Fg(i)p
+Fe(ngw)n Fg(o)p Fe(rd)p Fc(|)p Fe(w)p Fg(i)p Fe(t)p Fg(h)1918
+731 y(long)f(n)p Fi(o)p Fg(n)n(breaking)f(w)n Fi(o)p
+Fg(rds)g(just)h(to)f(m)p Fi(a)p Fg(k)n(e)g(the)g(a)p
+Fi(l)p Fg(gorithm)1918 830 y Fi(w)n Fh(or)p Fi(k)g Fh(h)p
+Fi(ar)p Fh(d)p Fi(e)p Fh(r)g Fi(a)p Fh(n)p Fi(d)g Fh(t)p
+Fi(o)p Fc(|)p Fg(l)p Fi(o)p Fh(n)p Fi(g)p Fh(n)p Fi(on)n
+Fh(b)p Fi(r)p Fh(e)p Fi(a)p Fh(k)p Fi(in)p Fh(g)p Fi(w)n
+Fh(o)p Fi(r)p Fh(d)p Fc(|)p Fh(sh)p Fi(o)n Fh(w)1918
+930 y Ff(s)p Fc(o)p Ff(m)p Fc(e)h Ff(i)p Fc(m)p Ff(pro)n
+Fc(v)n Ff(e)p Fc(m)p Ff(en)n Fc(t)p Ff(s)e(t)p Fc(h)p
+Ff(a)p Fc(t)i Ff(ca)p Fc(n)g Ff(b)r Fc(e)g Ff(h)p Fc(a)p
+Ff(d)g Fc(b)n Ff(y)f(a)p Fc(ll)p Ff(o)n Fc(w)p Fh(i)p
+Fc(n)p Ff(g)1918 1029 y Fc(fon)n(t|longnon)n(breakingw)n(ord|width)h(v)
+-5 b(ariations.)1918 1271 y Fj(Original)38 b(with)g Fb(n)p
+Fa(emergencystretch)1918 1428 y Fd(This)22 b(is)g(a)g(test)g(paragraph)
+h(for)e(T)2903 1446 y Fc(E)2953 1428 y Fd(X's)g(paragraph-breaking)1918
+1528 y(alg)p Fe(o)p Fd(rithm)p Fe(.)35 b Fd(It)29 b(is)e(a)h(fair)p
+Fe(l)p Fd(y)f(com)p Fe(p)p Fd(lex)f(algo)p Fe(r)p Fd(ithm)p
+Fe(,)h Fd(nev)n Fe(e)p Fd(rthe-)1918 1627 y Fe(less)i
+Fd(i)p Fe(mpro)n(v)n Fd(e)p Fe(men)n(ts)f(se)p Fd(e)p
+Fe(m)h(p)r(oss)p Fd(i)p Fe(ble.)39 b(A)p Fd(s)27 b Fe(y)n(ou)h(w)p
+Fd(i)p Fe(ll)f(note)p Fd(,)h Fe(I)1918 1727 y(stu)p Fc(\013)p
+Fe(ed)h(th)p Fg(i)p Fe(s)g(pa)p Fg(r)p Fe(agrap)p Fg(h)p
+Fc(|)p Fe(lon)p Fg(g)p Fe(non)n(b)p Fg(r)p Fe(eak)p Fg(i)p
+Fe(ngw)n Fg(o)p Fe(rd)p Fc(|)p Fe(w)p Fg(i)p Fe(t)p Fg(h)1918
+1826 y(long)f(n)p Fi(o)p Fg(n)n(breaking)f(w)n Fi(o)p
+Fg(rds)g(just)h(to)f(m)p Fi(a)p Fg(k)n(e)g(the)g(a)p
+Fi(l)p Fg(gorithm)1918 1926 y Fi(w)n Fh(or)p Fi(k)g Fh(h)p
+Fi(ar)p Fh(d)p Fi(e)p Fh(r)g Fi(a)p Fh(n)p Fi(d)g Fh(t)p
+Fi(o)p Fc(|)p Fg(l)p Fi(o)p Fh(n)p Fi(g)p Fh(n)p Fi(on)n
+Fh(b)p Fi(r)p Fh(e)p Fi(a)p Fh(k)p Fi(in)p Fh(g)p Fi(w)n
+Fh(o)p Fi(r)p Fh(d)p Fc(|)p Fh(sh)p Fi(o)n Fh(w)1918
+2026 y Ff(s)p Fc(o)p Ff(m)p Fc(e)h Ff(i)p Fc(m)p Ff(pro)n
+Fc(v)n Ff(e)p Fc(m)p Ff(en)n Fc(t)p Ff(s)e(t)p Fc(h)p
+Ff(a)p Fc(t)i Ff(ca)p Fc(n)g Ff(b)r Fc(e)g Ff(h)p Fc(a)p
+Ff(d)g Fc(b)n Ff(y)f(a)p Fc(ll)p Ff(o)n Fc(w)p Fh(i)p
+Fc(n)p Ff(g)1918 2125 y Fc(fon)n(t|longnon)n(breakingw)n(ord|width)h(v)
+-5 b(ariations.)1918 2367 y Fj(Three)25 b(v)-6 b(arian)m(ts)26
+b(with)e Fb(n)p Fa(emergencystretch)1918 2524 y Fd(This)e(is)g(a)g
+(test)g(paragraph)h(for)e(T)2903 2542 y Fc(E)2953 2524
+y Fd(X's)g(paragraph-breaking)1918 2623 y(alg)p Fe(o)p
+Fd(rithm)p Fe(.)35 b Fd(It)29 b(is)e(a)h(fair)p Fe(l)p
+Fd(y)f(com)p Fe(p)p Fd(lex)f(algo)p Fe(r)p Fd(ithm)p
+Fe(,)h Fd(nev)n Fe(e)p Fd(rthe-)1918 2723 y Fe(less)i
+Fd(i)p Fe(mpro)n(v)n Fd(e)p Fe(men)n(ts)f(se)p Fd(e)p
+Fe(m)h(p)r(oss)p Fd(i)p Fe(ble.)39 b(A)p Fd(s)27 b Fe(y)n(ou)h(w)p
+Fd(i)p Fe(ll)f(note)p Fd(,)h Fe(I)1918 2823 y(stu)p Fc(\013)p
+Fe(ed)h(th)p Fg(i)p Fe(s)g(pa)p Fg(r)p Fe(agrap)p Fg(h)p
+Fc(|)p Fe(lon)p Fg(g)p Fe(non)n(b)p Fg(r)p Fe(eak)p Fg(i)p
+Fe(ngw)n Fg(o)p Fe(rd)p Fc(|)p Fe(w)p Fg(i)p Fe(t)p Fg(h)1918
+2922 y(long)f(n)p Fi(o)p Fg(n)n(breaking)f(w)n Fi(o)p
+Fg(rds)g(just)h(to)f(m)p Fi(a)p Fg(k)n(e)g(the)g(a)p
+Fi(l)p Fg(gorithm)1918 3022 y Fi(w)n Fh(or)p Fi(k)g Fh(h)p
+Fi(ar)p Fh(d)p Fi(e)p Fh(r)g Fi(a)p Fh(n)p Fi(d)g Fh(t)p
+Fi(o)p Fc(|)p Fg(l)p Fi(o)p Fh(n)p Fi(g)p Fh(n)p Fi(on)n
+Fh(b)p Fi(r)p Fh(e)p Fi(a)p Fh(k)p Fi(in)p Fh(g)p Fi(w)n
+Fh(o)p Fi(r)p Fh(d)p Fc(|)p Fh(sh)p Fi(o)n Fh(w)1918
+3122 y Ff(s)p Fc(o)p Ff(m)p Fc(e)h Ff(i)p Fc(m)p Ff(pro)n
+Fc(v)n Ff(e)p Fc(m)p Ff(en)n Fc(t)p Ff(s)e(t)p Fc(h)p
+Ff(a)p Fc(t)i Ff(ca)p Fc(n)g Ff(b)r Fc(e)g Ff(h)p Fc(a)p
+Ff(d)g Fc(b)n Ff(y)f(a)p Fc(ll)p Ff(o)n Fc(w)p Fh(i)p
+Fc(n)p Ff(g)1918 3221 y Fc(fon)n(t|longnon)n(breakingw)n(ord|width)h(v)
+-5 b(ariations.)1918 3463 y Fj(Fiv)m(e)38 b(v)-6 b(arian)m(ts)38
+b(with)f Fb(n)p Fa(emergencystretch)1918 3620 y Fd(This)22
+b(is)g(a)g(test)g(paragraph)h(for)e(T)2903 3638 y Fc(E)2953
+3620 y Fd(X's)g(paragraph-breaking)1918 3719 y(alg)p
+Fe(o)p Fd(rithm)p Fe(.)35 b Fd(It)29 b(is)e(a)h(fair)p
+Fe(l)p Fd(y)f(com)p Fe(p)p Fd(lex)f(algo)p Fe(r)p Fd(ithm)p
+Fe(,)h Fd(nev)n Fe(e)p Fd(rthe-)1918 3819 y Fe(less)i
+Fd(i)p Fe(mpro)n(v)n Fd(e)p Fe(men)n(ts)f(se)p Fd(e)p
+Fe(m)h(p)r(oss)p Fd(i)p Fe(ble.)39 b(A)p Fd(s)27 b Fe(y)n(ou)h(w)p
+Fd(i)p Fe(ll)f(note)p Fd(,)h Fe(I)1918 3919 y(stu)p Fc(\013)p
+Fe(ed)h(th)p Fg(i)p Fe(s)g(pa)p Fg(r)p Fe(agrap)p Fg(h)p
+Fc(|)p Fe(lon)p Fg(g)p Fe(non)n(b)p Fg(r)p Fe(eak)p Fg(i)p
+Fe(ngw)n Fg(o)p Fe(rd)p Fc(|)p Fe(w)p Fg(i)p Fe(t)p Fg(h)1918
+4018 y(long)f(n)p Fi(o)p Fg(n)n(breaking)f(w)n Fi(o)p
+Fg(rds)g(just)h(to)f(m)p Fi(a)p Fg(k)n(e)g(the)g(a)p
+Fi(l)p Fg(gorithm)1918 4118 y Fi(w)n Fh(or)p Fi(k)g Fh(h)p
+Fi(ar)p Fh(d)p Fi(e)p Fh(r)g Fi(a)p Fh(n)p Fi(d)g Fh(t)p
+Fi(o)p Fc(|)p Fg(l)p Fi(o)p Fh(n)p Fi(g)p Fh(n)p Fi(on)n
+Fh(b)p Fi(r)p Fh(e)p Fi(a)p Fh(k)p Fi(in)p Fh(g)p Fi(w)n
+Fh(o)p Fi(r)p Fh(d)p Fc(|)p Fh(sh)p Fi(o)n Fh(w)1918
+4218 y Ff(s)p Fc(o)p Ff(m)p Fc(e)h Ff(i)p Fc(m)p Ff(pro)n
+Fc(v)n Ff(e)p Fc(m)p Ff(en)n Fc(t)p Ff(s)e(t)p Fc(h)p
+Ff(a)p Fc(t)i Ff(ca)p Fc(n)g Ff(b)r Fc(e)g Ff(h)p Fc(a)p
+Ff(d)g Fc(b)n Ff(y)f(a)p Fc(ll)p Ff(o)n Fc(w)p Fh(i)p
+Fc(n)p Ff(g)1918 4317 y Fc(fon)n(t|longnon)n(breakingw)n(ord|width)h(v)
+-5 b(ariations.)1918 4559 y Fj(Sev)m(en)27 b(v)-6 b(arian)m(ts)27
+b(with)f Fb(n)p Fa(emergencystretch)1918 4716 y Fd(This)c(is)g(a)g
+(test)g(paragraph)h(for)e(T)2903 4734 y Fc(E)2953 4716
+y Fd(X's)g(paragraph-breaking)1918 4815 y(alg)p Fe(o)p
+Fd(rithm)p Fe(.)35 b Fd(It)29 b(is)e(a)h(fair)p Fe(l)p
+Fd(y)f(com)p Fe(p)p Fd(lex)f(algo)p Fe(r)p Fd(ithm)p
+Fe(,)h Fd(nev)n Fe(e)p Fd(rthe-)1918 4915 y Fe(less)i
+Fd(i)p Fe(mpro)n(v)n Fd(e)p Fe(men)n(ts)f(se)p Fd(e)p
+Fe(m)h(p)r(oss)p Fd(i)p Fe(ble.)39 b(A)p Fd(s)27 b Fe(y)n(ou)h(w)p
+Fd(i)p Fe(ll)f(note)p Fd(,)h Fe(I)1918 5015 y(stu)p Fc(\013)p
+Fe(ed)h(th)p Fg(i)p Fe(s)g(pa)p Fg(r)p Fe(agrap)p Fg(h)p
+Fc(|)p Fe(lon)p Fg(g)p Fe(non)n(b)p Fg(r)p Fe(eak)p Fg(i)p
+Fe(ngw)n Fg(o)p Fe(rd)p Fc(|)p Fe(w)p Fg(i)p Fe(t)p Fg(h)1918
+5114 y(long)f(n)p Fi(o)p Fg(n)n(breaking)f(w)n Fi(o)p
+Fg(rds)g(just)h(to)f(m)p Fi(a)p Fg(k)n(e)g(the)g(a)p
+Fi(l)p Fg(gorithm)1918 5214 y Fi(w)n Fh(or)p Fi(k)g Fh(h)p
+Fi(ar)p Fh(d)p Fi(e)p Fh(r)g Fi(a)p Fh(n)p Fi(d)g Fh(t)p
+Fi(o)p Fc(|)p Fg(l)p Fi(o)p Fh(n)p Fi(g)p Fh(n)p Fi(on)n
+Fh(b)p Fi(r)p Fh(e)p Fi(a)p Fh(k)p Fi(in)p Fh(g)p Fi(w)n
+Fh(o)p Fi(r)p Fh(d)p Fc(|)p Fh(sh)p Fi(o)n Fh(w)1918
+5313 y Ff(s)p Fc(o)p Ff(m)p Fc(e)h Ff(i)p Fc(m)p Ff(pro)n
+Fc(v)n Ff(e)p Fc(m)p Ff(en)n Fc(t)p Ff(s)e(t)p Fc(h)p
+Ff(a)p Fc(t)i Ff(ca)p Fc(n)g Ff(b)r Fc(e)g Ff(h)p Fc(a)p
+Ff(d)g Fc(b)n Ff(y)f(a)p Fc(ll)p Ff(o)n Fc(w)p Fh(i)p
+Fc(n)p Ff(g)1918 5413 y Fc(fon)n(t|longnon)n(breakingw)n(ord|width)h(v)
+-5 b(ariations.)p eop
+%%Page: 2 2
+2 1 bop 0 531 a Fj(The)38 b(used)g(v)-6 b(arian)m(ts)0
+685 y Fd(Fl)r(\177)-41 b(ussigk)n(eitsgleic)n(hgewic)n(h)n(t)25
+b(und)j(Sto\013w)n(ec)n(hsel)0 784 y Fe(Fl)r(\177)-42
+b(ussigk)n(eitsgleic)n(hgewic)n(h)n(t)31 b(und)d(Sto\013w)n(ec)n(hsel)0
+884 y Fg(Fl)r(\177)-43 b(ussigk)n(eitsgleic)n(hgewic)n(h)n(t)30
+b(und)e(Sto\013w)n(ec)n(hsel)0 983 y Fi(Fl)r(\177)-44
+b(ussigk)n(eitsglei)o(c)n(hgewi)o(c)m(h)n(t)22 b(und)28
+b(Sto\013w)n(ec)n(hsel)0 1083 y Fh(Fl)r(\177)-45 b(ussigk)n(eitsgleic)n
+(hgewic)n(h)n(t)25 b(und)j(Sto\013w)n(ec)n(hsel)0 1183
+y Ff(Fl)r(\177)-46 b(ussigk)n(eitsgleic)n(hgewic)n(h)n(t)29
+b(und)f(Sto\013w)n(ec)n(hsel)0 1282 y Fc(Fl)r(\177)-46
+b(ussigk)n(eitsgleic)n(hgewic)n(h)n(t)29 b(und)f(Sto\013w)n(ec)n(hsel)0
+1515 y Fj(Setting)37 b(b)s(o)m(xes)i(with)e(stretc)m(h)0
+1668 y Fd(Fl)r(\177)-44 b(ussigk)n(eitsgleic)n(hgewic)n(h)n(t)21
+b(und)k(Sto)p Fi(\013)p Fd(w)n(ec)n(hsel)0 1768 y Fe(F)p
+Fd(l)r Fe(\177)-44 b(us)p Fd(s)p Fe(igk)n(e)p Fd(i)p
+Fe(tsg)p Fd(l)p Fe(eic)n(h)p Fd(g)p Fe(ewic)n(h)n Fd(t)30
+b Fe(und)e Fd(S)p Fg(t)p Fd(o)p Fi(\013)p Fe(w)n(ec)n(h)p
+Fd(s)p Fe(el)0 1867 y Fg(Fl)r(\177)-44 b(u)p Fe(s)p Fg(sigk)n(eitsg)p
+Fe(l)p Fg(eic)n(hgew)p Fe(i)p Fg(c)n(h)n(t)30 b(und)e(S)p
+Fe(t)p Fg(o)p Fi(\013)p Fg(w)n(ec)n(h)p Fe(s)p Fg(el)0
+1967 y(F)p Fi(l)r Fg(\177)-44 b(us)p Fi(s)p Fg(igk)n(e)p
+Fi(i)p Fg(tsg)p Fi(l)p Fg(eic)n(h)p Fi(g)p Fg(ewic)n
+Fi(h)n Fg(t)25 b(und)j(S)p Fi(t)p Fg(o)p Fi(\013)p Fg(w)n
+Fi(e)p Fg(c)n(hse)p Fi(l)0 2066 y Fg(F)p Fi(l)r(\177)-44
+b Fg(u)p Fi(s)p Fg(s)p Fi(i)p Fg(g)p Fi(k)n Fg(e)p Fi(i)p
+Fg(t)p Fi(s)p Fg(g)p Fi(l)p Fg(e)p Fi(i)p Fg(c)n Fi(h)p
+Fg(g)p Fi(e)p Fg(w)o Fi(i)o(c)n Fg(h)n Fi(t)22 b Fg(u)p
+Fi(n)p Fg(d)28 b Fi(S)p Fg(to)p Fi(\013)p Fg(w)n Fi(e)p
+Fg(c)n Fi(h)p Fg(s)p Fi(e)p Fg(l)0 2166 y Fi(F)p Fg(l)r
+Fi(\177)-44 b(u)p Fg(s)p Fi(s)p Fg(i)p Fi(gk)n Fg(e)p
+Fi(its)p Fg(g)p Fh(l)p Fg(e)p Fi(ic)n(h)p Fg(g)p Fi(ew)p
+Fg(i)p Fi(c)n(h)n Fg(t)25 b Fi(un)p Fg(d)j Fi(Sto\013w)n(ec)n
+Fg(h)p Fi(sel)0 2266 y(Fl)r(\177)-44 b(ussigk)n(eitsglei)o(c)n(hgewi)o
+(c)m(h)n(t)22 b(und)28 b(Sto\013w)n(ec)n(hsel)0 2365
+y(F)p Fh(l)r Fi(\177)-44 b(u)p Fh(s)p Fi(s)p Fh(i)p Fi(gk)n
+Fh(e)p Fi(its)p Fh(g)p Fg(l)p Fh(e)p Fi(ic)n(h)p Fh(g)p
+Fi(ew)p Fh(i)p Fi(c)n(h)n Fh(t)23 b Fi(un)p Fh(d)28 b
+Fi(Sto\013w)n(ec)n Fh(h)p Fi(sel)0 2465 y Fh(F)p Fi(l)r(\177)-44
+b Fh(u)p Fi(s)p Fh(s)p Fi(i)p Fh(g)p Fi(k)n Fh(e)p Fi(i)p
+Fh(t)p Fi(s)p Fh(g)p Fi(l)p Fh(e)p Fi(i)p Fh(c)n Fi(h)p
+Fh(g)p Fi(e)p Fh(w)p Fi(ic)m Fh(h)n Fi(t)22 b Fh(u)p
+Fi(n)p Fh(d)28 b Fi(S)p Fh(to)p Fi(\013)p Fh(w)n Fi(e)p
+Fh(c)n Fi(h)p Fh(s)p Fi(e)p Fh(l)0 2565 y(F)p Fi(l)r
+Fh(\177)-44 b(us)p Fi(s)p Fh(igk)n(e)p Fi(i)p Fh(tsg)p
+Fi(l)p Fh(eic)n(h)p Fi(g)p Fh(ewic)n Fi(h)n Fh(t)22 b(und)28
+b(S)p Fi(t)p Fh(o)p Fi(\013)p Fh(w)n Fi(e)p Fh(c)n(hse)p
+Fi(l)0 2664 y Fh(Fl)r(\177)-44 b(u)p Ff(s)p Fh(sigk)n(eitsg)p
+Ff(l)p Fh(eic)n(hgew)p Ff(i)p Fh(c)n(h)n(t)25 b(und)j(S)p
+Ff(t)p Fh(o)p Fi(\013)p Fh(w)n(ec)n(h)p Ff(s)p Fh(el)0
+2764 y Ff(F)p Fc(l)r Ff(\177)-44 b(us)p Fc(s)p Ff(igk)n(e)p
+Fc(i)p Ff(tsg)p Fc(l)p Ff(eic)n(h)p Fc(g)p Ff(ewic)n(h)n
+Fc(t)30 b Ff(und)e Fc(S)p Fh(t)p Fc(o)p Fi(\013)p Ff(w)n(ec)n(h)p
+Fc(s)p Ff(el)0 2864 y Fc(Fl)r(\177)-44 b(ussigk)n(eitsgleic)n(hgewic)n
+(h)n(t)34 b(und)d(Sto)p Fi(\013)p Fc(w)n(ec)n(hsel)p
+eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/systems/tex-extensions/clasen/examples/example4/example4.tex b/systems/tex-extensions/clasen/examples/example4/example4.tex
new file mode 100644
index 0000000000..a7c488511c
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/example4.tex
@@ -0,0 +1,128 @@
+\documentclass[a4paper,twocolumn]{article}
+\pagestyle{empty}
+\hzstate=1
+\def\cs#1{\begingroup\normalfont\ttfamily\textbackslash#1\endgroup}
+\def\cmrvariants{
+\font\n=cmr10
+\font\1=hz1cmr10
+\font\2=hz2cmr10
+\font\3=hz3cmr10
+\font\4=hz4cmr10
+\font\5=hz5cmr10
+\font\6=hz6cmr10
+}
+
+\def\novariants{
+\begingroup
+ \cmrvariants
+ \fontvariant\n=\nullfont
+\endgroup}
+
+\def\threevariants{
+\begingroup
+ \cmrvariants
+ \fontvariant\n=\3
+ \fontvariant\n=\4
+\endgroup}
+
+\def\fivevariants{
+\begingroup
+ \cmrvariants
+ \fontvariant\n=\2
+ \fontvariant\n=\3
+ \fontvariant\n=\4
+ \fontvariant\n=\5
+\endgroup}
+
+\def\sevenvariants{
+\begingroup
+ \cmrvariants
+ \fontvariant\n=\1
+ \fontvariant\n=\2
+ \fontvariant\n=\3
+ \fontvariant\n=\4
+ \fontvariant\n=\5
+ \fontvariant\n=\6
+\endgroup}
+
+\def\testpar{This is a test paragraph for \TeX's
+paragraph-breaking algorithm. It is a fairly complex algorithm,
+nevertheless improvements seem possible. As you will note, I
+stuffed this paragraph---\hbox to0pt{}longnonbreakingword---with long
+nonbreaking words just to make the algorithm work harder and
+to---\hbox to0pt{}longnonbreakingword---show some improvements that
+can be had by allowing font---\hbox to0pt{}longnonbreakingword---width
+variations.}
+
+\begin{document}
+\emergencystretch=0pt
+
+\subsection*{Original}\message{Original}
+\testpar\par
+
+\subsection*{Three variants}\message{3 variants}
+\threevariants
+\testpar\par
+
+\subsection*{Five variants}\message{5 variants}
+\fivevariants
+\testpar\par
+
+\subsection*{Seven variants}\message{7 variants}
+\sevenvariants
+\testpar\par
+
+\subsection*{Original with \cs{emergencystretch}}\message{Original+es}
+\novariants
+\testpar{\emergencystretch1em\par}
+
+\subsection*{Three variants with \cs{emergencystretch}}\message{3 variants+es}
+\threevariants
+\testpar{\emergencystretch1em\par}
+
+\subsection*{Five variants with \cs{emergencystretch}}\message{5 variants+es}
+\fivevariants
+\testpar{\emergencystretch1em\par}
+
+\subsection*{Seven variants with \cs{emergencystretch}}\message{7 variants+es}
+\sevenvariants
+\testpar{\emergencystretch1em\par}
+
+\subsection*{The used variants}
+\novariants\cmrvariants\1%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent\2%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent\3%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent\n%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent\4%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent\5%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent\6%
+Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par
+
+\subsection*{Setting boxes with stretch}
+\sevenvariants
+\hbox spread-12pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-8pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-4pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-3pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-2pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-1pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 0pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 1pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 2pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 3pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 4pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 8pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread12pt{\n Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+
+\end{document}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/systems/tex-extensions/clasen/examples/example4/gdiff1.gif b/systems/tex-extensions/clasen/examples/example4/gdiff1.gif
new file mode 100644
index 0000000000..9317b43c26
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/gdiff1.gif
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example4/hz.mf b/systems/tex-extensions/clasen/examples/example4/hz.mf
new file mode 100644
index 0000000000..4cb5f477e7
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz.mf
@@ -0,0 +1,7 @@
+if unknown hz_stretch: hz_stretch:=1; fi
+
+let BEGINCHAR = beginchar;
+def beginchar(expr n, w, h, d) =
+ BEGINCHAR(n,(w)*hz_stretch,h,d)
+enddef;
+
diff --git a/systems/tex-extensions/clasen/examples/example4/hz1cmr10.mf b/systems/tex-extensions/clasen/examples/example4/hz1cmr10.mf
new file mode 100644
index 0000000000..334deaa9f2
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz1cmr10.mf
@@ -0,0 +1,79 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+hz_stretch=0.94;
+input hz
+
+generate roman % switch to the driver file
+
diff --git a/systems/tex-extensions/clasen/examples/example4/hz2cmr10.mf b/systems/tex-extensions/clasen/examples/example4/hz2cmr10.mf
new file mode 100644
index 0000000000..2bdf14e5b6
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz2cmr10.mf
@@ -0,0 +1,78 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+hz_stretch=0.96;
+input hz
+
+generate roman % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example4/hz3cmr10.mf b/systems/tex-extensions/clasen/examples/example4/hz3cmr10.mf
new file mode 100644
index 0000000000..c84a552860
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz3cmr10.mf
@@ -0,0 +1,78 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+hz_stretch=0.98;
+input hz
+
+generate roman % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example4/hz4cmr10.mf b/systems/tex-extensions/clasen/examples/example4/hz4cmr10.mf
new file mode 100644
index 0000000000..e9c6be8167
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz4cmr10.mf
@@ -0,0 +1,78 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+hz_stretch=1.02;
+input hz
+
+generate roman % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example4/hz5cmr10.mf b/systems/tex-extensions/clasen/examples/example4/hz5cmr10.mf
new file mode 100644
index 0000000000..3ed95657bc
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz5cmr10.mf
@@ -0,0 +1,78 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+hz_stretch=1.04;
+input hz
+
+generate roman % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example4/hz6cmr10.mf b/systems/tex-extensions/clasen/examples/example4/hz6cmr10.mf
new file mode 100644
index 0000000000..c612317011
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/hz6cmr10.mf
@@ -0,0 +1,78 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+hz_stretch=1.06;
+input hz
+
+generate roman % switch to the driver file
diff --git a/systems/tex-extensions/clasen/examples/example4/ocmr10.mf b/systems/tex-extensions/clasen/examples/example4/ocmr10.mf
new file mode 100644
index 0000000000..c0dabaade4
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/ocmr10.mf
@@ -0,0 +1,10 @@
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+def generate suffix t= enddef;
+
+input cmr10;
+
+input oroman; % switch to the driver file
+
+bye. \ No newline at end of file
diff --git a/systems/tex-extensions/clasen/examples/example4/ocomlig.mf b/systems/tex-extensions/clasen/examples/example4/ocomlig.mf
new file mode 100644
index 0000000000..4967be7fb5
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/ocomlig.mf
@@ -0,0 +1,59 @@
+% This file defines characters common to roman and italic text fonts
+% that appear only when |ligs>0|.
+
+% Character codes \0042, \0055, \0134, \0173, and \0174 are generated.
+
+ligtable "`": "`"=:oct"134";
+ligtable "'": "'"=:oct"042", "?" kern 2u#, "!" kern 2u#;
+
+ligtable "-": "-"=:oct"173", marginchar kern -6u#;
+ligtable oct"173": "-"=:oct"174";
+
+cmchar "Closing quotes";
+beginchar(oct"042",7u#+max(2u#,dot_size#),asc_height#,0);
+italcorr asc_height#*slant+dot_size#-4.1u#;
+adjust_fit(0,0);
+x1-.5dot_size=hround .6u; y2+.5dot_size=h;
+x2-x1=hround(1.5u+max(2u,dot_size)); y2=y1;
+comma(1,a,dot_size,.25u,comma_depth); % left dot and tail
+comma(2,b,dot_size,.25u,comma_depth); % right dot and tail
+penlabels(1,2); endchar;
+
+cmchar "Hyphen";
+beginchar("-",6u#,x_height#,0);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric thickness; thickness=if hefty:bar else:.75[hair,stem] fi;
+pickup crisp.nib; pos1(thickness,90); pos2(thickness,90);
+top y1r=top y2r=vround(.5h+.5thickness); rt x2=hround(w-u)+eps;
+if monospace: x2=w-x1 else: lft x1=hround .2u-eps fi;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+cmchar "Opening quotes";
+beginchar(oct"134",7u#+max(2u#,dot_size#),asc_height#,0);
+italcorr asc_height#*slant-.1u#;
+adjust_fit(0,0);
+x2+.5dot_size=hround(w-.6u); y1+.5dot_size=h-comma_depth;
+x2-x1=hround(1.5u+max(2u,dot_size)); y2=y1;
+ammoc(1,a,dot_size,.25u,comma_depth); % left dot and tail
+ammoc(2,b,dot_size,.25u,comma_depth); % right dot and tail
+penlabels(1,2); endchar;
+
+cmchar "En dash";
+beginchar(oct"173",9u#,x_height#,0);
+italcorr .61803x_height#*slant+.5u#;
+adjust_fit(0,0);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(.61803h+.5vair); lft x1=-eps; rt x2=w+eps;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+cmchar "Em dash";
+beginchar(oct"174",18u#,x_height#,0);
+italcorr .61803x_height#*slant+.5u#;
+adjust_fit(letter_fit#,letter_fit#);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(.61803h+.5vair); lft x1=-eps; rt x2=w+eps;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
diff --git a/systems/tex-extensions/clasen/examples/example4/oroman.mf b/systems/tex-extensions/clasen/examples/example4/oroman.mf
new file mode 100644
index 0000000000..bac0a9bb12
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example4/oroman.mf
@@ -0,0 +1,81 @@
+% The Computer Modern Roman family of fonts (by D. E. Knuth, 1979--1985)
+
+if ligs>1: font_coding_scheme:="TeX text";
+ spanish_shriek=oct"074"; spanish_query=oct"076";
+else: font_coding_scheme:=if ligs=0: "TeX typewriter text"
+ else: "TeX text without f-ligatures" fi;
+ spanish_shriek=oct"016"; spanish_query=oct"017"; fi
+
+mode_setup; font_setup;
+
+input romanu; % upper case (majuscules)
+input romanl; % lower case (minuscules)
+input greeku; % upper case Greek letters
+input romand; % numerals
+input romanp; % ampersand, question marks, currency sign
+input romspl; % lowercase specials (dotless \i, ligature \ae, etc.)
+input romspu; % uppercase specials (\AE, \OE, \O)
+input punct; % punctuation symbols common to roman and italic text
+input accent; % accents common to roman and italic text
+
+marginchar:=oct"200";
+
+beginchar(marginchar,10u#,0,0)
+endchar;
+
+if ligs>1: input romlig; fi % letter ligatures
+if ligs>0: input ocomlig; fi % ligatures common with italic text
+if ligs<=1: input romsub; fi % substitutes for ligatures
+
+ligtable "!": "`" =: spanish_shriek, marginchar kern -5u#-width_adj#;
+ligtable "?": "`" =: spanish_query, marginchar kern -8.5u#;
+
+ligtable ",": marginchar kern -5u#;
+ligtable ".": marginchar kern -5u#;
+ligtable ":": marginchar kern -5u#;
+ligtable ";": marginchar kern -5u#;
+ligtable oct"042": marginchar kern -(7u#+max(2u#,dot_size#));
+ligtable marginchar:
+"`" kern -5u#,
+oct"134" kern -(7u#+max(2u#,dot_size#));
+
+font_slant slant; font_x_height x_height#;
+if monospace: font_normal_space 9u#; % no stretching or shrinking
+ font_quad 18u#;
+ font_extra_space 9u#;
+else: font_normal_space 6u#+2letter_fit#;
+ font_normal_stretch 3u#; font_normal_shrink 2u#;
+ font_quad 18u#+4letter_fit#;
+ font_extra_space 2u#;
+ k#:=-.5u#; kk#:=-1.5u#; kkk#:=-2u#; % three degrees of kerning
+ ligtable "k": if serifs: "v": "a" kern -u#, fi\\"w": "e" kern k#,
+ "a" kern k#, "o" kern k#, "c" kern k#;
+ ligtable "P": "A" kern kk#,
+ "y": "o" kern k#, "e" kern k#, "a" kern k#, "." kern kk#, "," kern kk#;
+ ligtable "F": "V": "W": if serifs: "o" kern kk#, "e" kern kk#, "u" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ else: "o" kern k#, "e" kern k#, "u" kern k#,
+ "r" kern k#, "a" kern k#, "A" kern kk#, fi
+ "K": "X": "O" kern k#, "C" kern k#, "G" kern k#, "Q" kern k#;
+ ligtable "T": "y" kern if serifs: k# else: kk# fi,
+ "Y": "e" kern kk#, "o" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kk#, "u" kern kk#;
+ ligtable "O": "D": "X" kern k#, "W" kern k#, "A" kern k#,
+ "V" kern k#, "Y" kern k#;
+ if serifs: ligtable "h": "m": "n":
+ "t" kern k#, "u" kern k#, "b" kern k#, "y" kern k#, "v" kern k#, "w" kern k#;
+ ligtable "c": "h" kern k#, "k" kern k#; fi
+ ligtable "o": "b": "p": "e" kern -k#, "o" kern -k#, "x" kern k#,
+ "d" kern -k#, "c" kern -k#, "q" kern -k#,
+ "a": if serifs: "v" kern k#, "j" kern u#, else: "r" kern k#, fi
+ "t": "y" kern k#,
+ "u": "w" kern k#;
+ ligtable "A": if serifs: "R": fi\\ "t" kern k#,
+ "C" kern k#, "O" kern k#, "G" kern k#, "U" kern k#, "Q" kern k#,
+ "L": "T" kern kk#, "Y" kern kk#, "V" kern kkk#, "W" kern kkk#;
+ ligtable "g": "j" kern -k#; % logjam
+ ligtable "I": "I" kern -k#; fi % Richard III
+ % there are ligature/kern programs for |"f"| in the {\tt romlig} file
+ % and for |"-"|, |"`"|, and |"'"| in the {\tt comlig} file
+bye.
+
diff --git a/systems/tex-extensions/clasen/examples/example5/example5.dvi b/systems/tex-extensions/clasen/examples/example5/example5.dvi
new file mode 100644
index 0000000000..0d434334ca
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/example5.dvi
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example5/example5.log b/systems/tex-extensions/clasen/examples/example5/example5.log
new file mode 100644
index 0000000000..d8a0a14dcb
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/example5.log
@@ -0,0 +1,68 @@
+This is TeX, Version 3.14159 (with experimental extensions) (Web2C 7.2) (format=latex 1998.7.23) 23 JUL 1998 23:14
+**&../latex example5
+(example5.tex
+LaTeX2e <1997/12/01> patch level 1
+Babel <v3.6h> and hyphenation patterns for american, german, loaded.
+(/usr/local/share/texmf/tex/latex/base/article.cls
+Document Class: article 1997/10/10 v1.3x Standard LaTeX document class
+(/usr/local/share/texmf/tex/latex/base/size10.clo
+File: size10.clo 1997/10/10 v1.3x Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+) (example5.aux)
+\openout1 = `example5.aux'.
+
+LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 26.
+LaTeX Font Info: ... okay on input line 26.
+LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 26.
+LaTeX Font Info: ... okay on input line 26.
+LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 26.
+LaTeX Font Info: ... okay on input line 26.
+LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 26.
+LaTeX Font Info: ... okay on input line 26.
+LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 26.
+LaTeX Font Info: ... okay on input line 26.
+LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 26.
+LaTeX Font Info: ... okay on input line 26.
+LaTeX Font Info: Try loading font information for OMS+cmtt on input line 29.
+
+LaTeX Font Info: No file OMScmtt.fd. on input line 29.
+
+
+LaTeX Font Warning: Font shape `OMS/cmtt/m/n' undefined
+(Font) using `OMS/cmsy/m/n' instead
+(Font) for symbol `textbackslash' on input line 29.
+
+LaTeX Font Info: External font `cmex10' loaded for size
+(Font) <12> on input line 42.
+LaTeX Font Info: External font `cmex10' loaded for size
+(Font) <8> on input line 42.
+LaTeX Font Info: External font `cmex10' loaded for size
+(Font) <6> on input line 42.
+[1
+
+] (example5.aux)
+
+LaTeX Font Warning: Some font shapes were not available, defaults substituted.
+
+ )
+Here is how much of TeX's memory you used:
+ 232 strings out of 10889
+ 2288 string characters out of 147219
+ 47976 words of memory out of 263001
+ 3218 multiletter control sequences out of 10000+0
+ 7334 words of font info for 27 fonts, out of 200000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 23i,4n,18p,171b,160s stack positions out of 300i,100n,500p,30000b,4000s
+
+Output written on example5.dvi (1 page, 4264 bytes).
diff --git a/systems/tex-extensions/clasen/examples/example5/example5.ps b/systems/tex-extensions/clasen/examples/example5/example5.ps
new file mode 100644
index 0000000000..93b923d533
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/example5.ps
@@ -0,0 +1,446 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.76a Copyright 1997 Radical Eye Software (www.radicaleye.com)
+%%Title: example5.dvi
+%%Pages: 1
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSCommandLine: dvips -a -D600 -mode ljfive example5.dvi -o
+%+ example5.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource: TeX output 1998.07.23:2314
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N
+/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id
+gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp
+add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add
+/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{
+dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1
+adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2
+idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string
+putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval
+adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg}
+{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{
+adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2
+chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{]
+}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{dup length product length le{dup length product
+exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}
+ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}
+imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false
+RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round
+exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto
+rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup
+/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{
+-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}
+B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B
+/bos{/SS save N}B /eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (example5.dvi)
+@start
+%DVIPSBitmapFont: Fa cmbx12 12 10
+/Fa 10 117 df<EA07C0EA1FE0EA3FF8127F13FCEAFFFEA313FFA27EA27E7EEA07CFEA00
+0FA2131EA4133CA21378A213F0120113E0EA03C01207EA0F80EA1F00120E12041022788E
+1F>44 D<903801FFF0011F13FF017F14C048B612F04848C66C7ED807F8EB1FFC486C6D7E
+6D6D7E486C81818381836C5A6C5A6C5A6C5AC8FCA30203B5FC91B6FC1307013F13F19038
+FFFE01000313F0481380481300485A485A485AA2485AA45DA26C6C5BA26C6C010E13F86C
+6C013CEBFFC03A0FFF80F87F6CEBFFF06CECE01FC66CEB8007D90FFCC9FC322F7DAD36>
+97 D<4CB4FC0307B5FCA5ED001F82B1EC3FF0903803FFFE010FEBFF8F013F14EF90267F
+F807B5FC3901FFC00148496C7E4890C77E49140F120F485AA2123FA2485AA412FFAA127F
+A4123F7F121FA2000F5D7F6C6C147F6C92B512806CD9C00314FE6C9038F01FEF013FB512
+CF6D140F010713FC9026007FC0EBF80037467CC43E>100 D<EC3FF849B5FC010F14C001
+3F14F090397FF01FF89039FFC007FC48496C7E48496C7E48481580000F80484815C0167F
+003F16E0A25B127FEE3FF0A212FFA290B7FCA401F8C9FCA5127FA36C7EA2001FED01F0A2
+6C7EEE03E06C6C14076C6DEB0FC06C6DEB1F806C01F0EB3F0090397FFE01FE011FB55A01
+0714F0010014C0DA1FFCC7FC2C2F7DAD33>I<DAFFE013FC010F9038FE03FF013FD9FF8F
+138090B812C048D9C07F1307489039001FF87F4848EB0FFC000F9238FE3F80491307001F
+9238FF0E0094C7FC003F82A7001F93C7FCA2000F5D6D130F00075D6C6C495A6C9038C07F
+F091B55A481580D8078F49C8FC018013E0000F90CAFCA47FA213F090B612C016FC6CEDFF
+80836C16F0836C826C821203000F82D81FF0C77ED83FC01407007F6F1380498000FF81A5
+6C6C4A1300A26C6C4A5A6D14076C6C4A5AD80FFEEC3FF83B03FFE003FFE06C90B65A6C6C
+92C7FC010F14F8D9007F90C8FC32427DAC38>103 D<EB3FE0B5FCA512037EB1ED03FF03
+1F13E04B13F892B57E9139E1F81FFE9139E3C00FFF9138E78007DAEE008002FE7F4A815C
+A25CA35CB3A7B600C1B61280A539457DC43E>I<137C48B4FC487F487FA2487FA56C5BA2
+6C5B6C90C7FCEA007C90C8FCAAEB3FE0EA7FFFA512037EB3AFB61280A519467DC51F>I<
+90397FC003FFB5011F13E04B13F892B57E9139C1F81FFE9139C3C00FFF00039038C78007
+6CD9CE008002DE7F02DC8114F8A25CA35CB3A7B600C1B61280A5392D7DAC3E>110
+D<EC1FFC49B512C0010714F0011F14FC90397FF80FFF9026FFC0017F48496C7F4890C76C
+7E48486E7E000F8249141F001F82A248486E7EA2007F82A400FF1780AA007F1700A46C6C
+4A5AA2001F5EA26C6C4A5A00075E6D147F6C6D495A6CD9E0035B27007FF80F90C7FC6DB5
+5A010F14F8010114C09026001FFCC8FC312F7DAD38>I<EB03E0A61307A3130FA3131FA2
+133F137F13FF5A5A001F90B51280B7FCA4000101E0C7FCB3A3ED03E0AA6CEC07C014F001
+7F1480ECF80F90393FFC1F0090381FFFFE6D5B010313F09038007FC023407EBE2C>116
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fb ocmr10 10 13
+/Fb 13 109 df<121E123FEA7F80EAFFC0A7EA7F80ABEA3F00AA121EAA120EC7FCA8121E
+123FEA7F80EAFFC0A4EA7F80EA3F00121E0A3C7ABB17>33 D<001E130F003FEB1F80397F
+803FC039FFC07FE0A201E013F0A2007F133F003F131F001EEB0F7000001300A4484813E0
+A339038001C0A23907000380A2000EEB070048130E003C131E0038131C001013081C1A7D
+B92A>I<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA
+0700A2120E5A123C123812100B1A7AB917>39 D<B512FCA616067F941C>45
+D<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A7A8917>I<121E123FEA7F80EAFF
+C0A4EA7F80EA3F00121EC7FCB0121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A247AA3
+17>58 D<121E123FEA7F80EAFFC0A4EA7F80EA3F00121EC7FCB0121E123FEA7F8012FF13
+C0A3127F123F121F1201A4EA0380A312071300A2120E121E121C5AA212100A347AA317>
+I<EB3FF03801FFFE0007EBFF80390FC03FC0391E000FE048EB07F048EB03F8A200FE14FC
+7EA4127E003C14F8C7120715F0140FEC1FE0EC3F801500147E5C5C495A5C13035C5C1307
+A291C7FCAA90C8FCA8130F497E497E497EA46D5A6D5A6DC7FC1E3B7CBA27>63
+D<48148039038001C00007130301001380000EEB070048130EA2485BA2485BA3485BA400
+EFEB778039FF807FC001C013E001E013F0A2007F133FA2393FC01FE0391F800FC0390F00
+07801C1A76B92A>92 D<5AEA038012071300120E5AA25AA25AA35AA412EFEAFF8013C013
+E0A2127FA2EA3FC0EA1F80EA0F000B1A7BB917>96 D<EB3FE0EBFFFC000313FF3907C03F
+80390F800FC0486C6C7E01E07F6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7F
+F13801FF01EA07F8EA0FF0EA1FE0EA3FC0EA7F80A2D8FF00141CA41403A2387F80071406
+3A3FC01C7E383A1FF0787FF83A0FFFF03FF0000301E013E03A007F000F8026277DA52A>
+I<EA03F812FFA3120F1203B0EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC090
+39FE0007E049EB03F0A249EB01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F8
+6D14F0ED07E06DEB0FC09039E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0
+283B7EB92E>I<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>108
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fc cmr12 12 4
+/Fc 4 62 df<1438147814F81303130F137FB5FCA213F71387EA0007B3B3AFEB1FFE007F
+B61280A4214278C131>49 D<EB03FE90381FFFC0017F13F090B57E3903F00FFE3907C003
+FF48C71380000EEC7FC048EC3FE0003C141F003815F048140F16F8127CB414076D14FC7F
+A46C5AA26CC7FCC8FC16F8150FA216F0151F16E0ED3FC0A2ED7F80160015FEA24A5A4A5A
+4A5A5D4A5A4AC7FC143E5C5C495A5C495A4948131C49C7FC131E4914385B5B485A491478
+485A48C812F048B6FC5A5A5AB7FC16E0A326427BC131>I<14FF010713E0011F13F84913
+FE49C67E01F8EB3F804848EB0FC0D803C0EB07E00007140349EB01F0120F90C7FCED00F8
+5AA37FA27FED01F07FD80FF8EB03E07F6CB4EB07C09138800F806C9038E01F006CEBF03E
+ECFC7C6CEBFFF06D5B011F5B6D13F001037F010F13FE90383F7FFFD97C3F1380D9F80F13
+C02601E00713E02603C00113F048486C13F8000FEC3FFC48C7121F003EEC07FE15034814
+00167FA248153FA2161FA4161E7E127C163C7E003F15786C15F06C6C1301D807E0EB03E0
+D803F8EB0FC06CB4EBFF806C9038FFFE00013F5B010F13F0010190C7FC28447CC131>56
+D<007FBAFCBB1280A26C1900CEFCB0007FBAFCBB1280A26C190041187BA44C>61
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fd cmtt12 12 13
+/Fd 13 117 df<EB3FFC48B57E4814E048804880488048809038E007FF02017FEC007F6C
+486D7E6C48131F6CC77FC8120FA4151FEC7FFF0107B5FC133F90B6FC12035A48EBF00F38
+1FFE00EA3FF0EA7FC090C7FC5A5AA3151F7E153F6C6C137F9038C001FF263FF80FEBFFF0
+90B7FC6C16F86C14F76C14E36C028113F0C69038FE003FD93FE090C7FC2D2E7BAC33>97
+D<ECFFF0010713FE497F013F14804914C090B612E04815F048EBC01F3807FE00EA0FF849
+EB0FE04848EB07C04848EB038092C7FC5B127F90C9FCA25A5AA87EA27E7FA26C6CEB01F0
+6DEB03F8121F01F813076C6C14F06CB4130F6C9038E03FE06C90B512C07E6D14806DEBFE
+006D5B010713F0010013C0252E79AC33>99 D<ED7FF815FF4A7FA380157F1501AAEB01FE
+90380FFFC1013F13F14913F990B512FD4814FF5A481380390FFE003F01F8130F48481307
+485A4913035B007F140190C7FCA25AA25AA87E6C1403A27F15076C7E150F6C6C131F6D13
+3FD80FFC137F2607FF81B512F06C90B612F86C02FD13FC6C14F96D13F16D01E013F8010F
+018013F0D903FCC8FC2E3E7DBC33>I<147F903803FFF0011F13FC497F90B6FC48158048
+15C0028013E03907FE003FD80FF8EB0FF04848EB07F85B4848EB03FC5B007F1401A290C7
+13FE15005A90B6FCA516FCA248C9FC7E7EA27F123F6D147C6C7E6D14FE6C7E01FE13016C
+6CEB07FC6C9038E01FF86C90B5FC6C15F06D14E06D14C0010F1400010313FC9038003FC0
+272E7BAC33>I<D901FEEB3FC0903A0FFFC1FFF04901E713F84990B512FC5B90B7FC5A48
+0103EBE1F82607FC00EB80F049017F130048486D7E49131F001F8149130FA76D131F000F
+5D6D133F6C6C495A6D13FF2603FF0390C7FCECFFFE485C5D485C01DF5B01CF5BD9C1FEC8
+FC01C0C9FCA37FEA07F290B512FC6CECFFC016F04815FC48814881273FE0000713800180
+9038007FC048C8EA1FE0007E150F160700FE16F0481503A56C1507007E16E0D87F80141F
+D83FE0EC7FC0D81FF8903801FF809038FF801F6C90B612006C5D000115F86C5D013F14C0
+010F91C7FC010013F02E447DAB33>103 D<EA3FFC127F487EA3127F123F1200AA4AB4FC
+020F13C04A7F027F7F91B57E90B67E82ECFE07ECF0014A6C7E5C4A7FA291C7FCA35BB3A3
+3B3FFFF80FFFFC486D4813FEB56C4813FFA36C496C13FE6C496C13FC303D7FBC33>I<EB
+01E0497E497E497EA46D5A6D5A6D5A90C9FCA9383FFFF85A80A47EEA0001B3AB007FB612
+C016E0B712F0A36C15E016C0243E78BD33>I<02FC137E3A7FC3FE01FF27FFCFFF077F90
+B5008F7F03DF7F92B57EA26C010F13873B07FC07FE03F801F813FC02031301A201F013F8
+A301E013F0B3A43C7FFE0FFF07FF80B5028713C04A138FA36E1387D87FFE02071380322C
+80AB33>109 D<4AB4FC263FFC0F13C0007F497F26FFFE7F7F91B57E90B67E6C816CEBFE
+07C6EBF0014A6C7E5C4A7FA291C7FCA35BB3A33B3FFFF80FFFFC486D4813FEB56C4813FF
+A36C496C13FE6C496C13FC302C7FAB33>I<EB01FE90380FFFC0013F13F0497F90B57E48
+8048804801031380260FFC0013C049137FD81FE0EB1FE0A24848EB0FF0491307007F15F8
+90C71203A300FEEC01FCA96C1403A26C15F8A26D1307003F15F06D130F6D131F6C6CEB3F
+E06D137F6C6CEBFFC02607FF0313806C90B512006C5C6C5C6D5B6D5B010F13C0D901FEC7
+FC262E7AAC33>I<15FF263FFC0713E0007F011F7F26FFFE7F7F91B57E90B67E6C816CD9
+FE071380C6D9F80013C002E0EB3FE04A131F4AEB0FF091C7FCEE07F85B1603A217FC1601
+A81603A217F87F160717F06E130F6E131FEE3FE06EEB7FC09138F001FFDAFE07138091B6
+12005E495C6E5B021F13E06E5BDA01FEC7FC91C9FCAE383FFFF8487FB57EA36C5B6C5B2E
+427FAB33>I<ED03FE3B7FFF801FFF80B5017F13C002C1B512E002C314F014C714CF6C90
+38DFFE0F3B001FFFF007E09238C003C092C8FC5C5C5CA25CA25CA45CB0007FB512FEB6FC
+81A35D7E2C2C7DAB33>114 D<EB03C01307497EAA003FB612FC5AB77EA36C5DA226000F
+E0C8FCB3161FA2EE3F80A46E137F170001075C6E485AECFE076DB55A5E6D5C6D5C6E1380
+021F90C7FCEC07F829387EB633>116 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fe cmsy10 12 2
+/Fe 2 111 df<007FB912E0BA12F0A26C18E03C04789A4D>0 D<126012F0A21278A37EA3
+7EA37EA26C7EA36C7EA36C7EA36C7EA21378A37FA37FA37FA26D7EA36D7EA36D7EA36D7E
+A21478A380A380A280A36E7EA36E7EA36E7EA26E7EA31578A381A381A281A3ED0780A3ED
+03C0A3ED01E0A2ED00F0A31678A3163CA3161EA2160C27647BCA32>110
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Ff cmtt10 10 18
+/Ff 18 122 df<121C123E127FEAFF80B0EA7F00AF123EC7FCA8121C123E127FEAFF80A3
+EA7F00123E121C09346FB32C>33 D<007FB6FCA2B71280A26C1500A221067B9B2C>45
+D<136013F0EA01F8EA03FCEA07F8EA0FF0EA1FC01380123FEA7F00A2127E12FE5AA5B4FC
+138013C013E0127FA2EA3FC0EA1F80EA0F000E1B71B82C>96 D<3801FFF0000713FE486D
+7E48804880819038C01FF8391F8007FC380F0001000680C8FCA2140FEB07FF137F48B5FC
+12075A4813F8383FFC00EA7FE0EAFF8090C7FC5AA36C1301A2387F8007383FE03F90B612
+FC6C15FE7E6C143F0001EBFC1F3A007FC00FFC27247CA32C>I<903803FFF0011F13FC01
+7F7F90B6FC4815805A48EB007FD80FF8EB3F00D81FE0131E4848130C4990C7FC127F90C9
+FCA25A5AA67E7EA26DEB0F806C6CEB1FC07F6C6C133FD80FFCEB7F803907FF81FF6C90B5
+12006C5C6C5C6D5B011F13E0010390C7FC22247BA32C>99 D<EC07FF4A13805CA28080EC
+003FA9EB0FF8EB3FFE90B512BF4814FF5A5A380FFC0F381FF00349C6FC4848137F485A15
+3F90C7FC5A5AA87E6C147FA26D13FF6C7E5C381FF007380FFC1F6CB612FC6C15FE6CECBF
+FF6C143FD97FFC13FE90390FF01FFC28337DB22C>I<EB03FE90381FFFC0017F13F090B5
+7E488048803907FE03FF260FF8001380D81FE0137F4848EB3FC049131F127F90C713E015
+0FB7FCA516C048C9FC7E7E7FED07C06C6CEB0FE07F6C6C131FD80FFCEB3FC03907FF80FF
+6C90B512806C15006C5C013F13F8010F5B0101138023247CA32C>I<ED03F0903907F81F
+FC90391FFE3FFE017FB5FC90B7FC5A48ECFE7F3A07FE1FF87ED9F003133C000FECFC00EB
+E001001F80EBC000A5EBE001000F5CEBF00300075CEBFE1F90B55A5D485C5DD9DFFEC7FC
+EBC7F801C0C8FCA27F6CB512E015FE6CECFF80000F15C04815E04815F09039C0003FF848
+C7EA03FC007E140000FE15FE48157EA46C15FE007E15FCD87F801303D83FE0EB0FF8D81F
+FEEBFFF06CB612E06C15C06C1580C6ECFE00013F13F80103138028387EA42C>103
+D<EA3FF8487E12FFA2127F123F1201A9EC07F8EC3FFE91B5FC01FD8090B67E82ECF81F91
+38C00FF0EC800714005BA35BB13B3FFFE03FFF80486D4813C0B56CB512E0A26C496C13C0
+6C496C13802B3380B22C>I<EB0380497E497E497EA36D5A6D5A6D5A90C8FCA7383FFFE0
+487FB5FCA27E7EEA0007B3A6007FB512FCB612FE15FFA215FE6C14FC20347AB32C>I<3A
+3FC1F803F03A7FE7FC0FF8B538FE3FFC6E487E6C91B5FC7E3B07FE1FFC3F8001FC13F890
+39F80FF01F01F013E0A301E013C0B2D83FFC01F813F03B7FFE1FFC3FF8B5393FFE7FFCA2
+3B7FFE1FFC3FF83B3FFC0FF81FF02E2481A32C>109 D<393FF807F8397FFC3FFE00FF90
+B5FC01FD806CB67E6C810001EBF81F9138C00FF0EC800714005BA35BB13B3FFFE03FFF80
+486D4813C0B56CB512E0A26C496C13C06C496C13802B2480A32C>I<EB07FCEB1FFF017F
+13C048B512F048804880390FFC07FE391FF001FF497E4848EB7F8049133F48C7EA1FC0A3
+00FEEC0FE0A76C141F6C15C0A26D133F003F15806D137F6C6CEBFF00EBF803390FFE0FFE
+6CB55A6C5C6C5C6C6C13C0011F90C7FCEB07FC23247CA32C>I<393FF80FF0397FFC7FFE
+D8FFFDB5FC90B612806C15C06C15E000019038F03FF09138C00FF891380003FC5BED01FE
+491300A216FF167FA816FF6D14FE15017FED03FC91388007F8ECC00F9138F03FF091B512
+E016C001FD148001FC1400EC7FFCEC0FF091C8FCAC383FFFE0487FB57EA26C5B6C5B2836
+80A32C>I<D83FFFEB3FC048903881FFE0B5008713F0028F13F86C019F13FC6C13BF3900
+3FFFE3ED01F89138FC00F04A13604A1300A25CA25CA35CAD003FB512F04880B6FCA27E6C
+5C26247EA32C>114 D<90383FF8700003B512F85A5A5A5A387FC01F38FF000700FC1303
+A36CEB01F06C6CC7FCEA7FFC383FFFF06C13FF6C14C06C14E0C614F0010F13F89038007F
+FCEC03FE003CEB00FF007E143F12FE7EA26D137F6D13FEEBF00790B512FC15F815F015E0
+00F8148039701FFC0020247AA32C>I<130F497E133FA8003FB6FC481580B7FCA36C1500
+26003F80C7FCAFED0380ED07C0ED0FE0A3151F02C013C0011F133F9138F07F806DB5FC16
+006D5B6D13F801005BEC3FC0232E7EAD2C>I<3A3FFF01FFFC48018313FEB512C7A26C13
+836C010113FC3A03F8001F800001143F6D140012005D6D137E137EA2017F5B7FA2EC81F8
+131FA2EB0FC1ECC3F0A2EB07E35D14E71303ECF7C0130114FF5D7FA292C7FC80A2147EA3
+14FE5CA21301000C5BEA3F03387F87F0138F495AEBFFC0A26C5B6C48C8FC6C5AEA07F027
+367EA32C>121 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fg cmsy10 10 3
+/Fg 3 111 df<15FE1407141FEC7FC0ECFE00495AEB03F0A2495AB3A8495AA2495A49C7
+FC13FEEA07FCEAFFF0138013F0EA07FCC67E133F6D7E6D7EA26D7EB3A86D7EA2EB01FC6D
+7EEC7FC0EC1FFE140714001F537BBD2A>102 D<127EEAFFE013F8EA07FEC67EEB3F806D
+7E130F6D7EB3A86D7EA26D7E6D7E147FEC3FC0EC0FFE1403140FEC3FC0EC7F0014FC495A
+495AA2495AB3A8495A131F495A01FFC7FCEA07FEEAFFF813E0007EC8FC1F537BBD2A>I<
+126012F0A21278A37EA37EA37EA36C7EA36C7EA36C7EA36C7EA31378A37FA37FA37FA36D
+7EA36D7EA26D7EA36D7EA31478A380A380A380A3EC0780A3EC03C0A3EC01E0A3EC00F0A3
+1578A3153CA3151EA2150C1F537BBD2A>110 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fh cmr10 10 33
+/Fh 33 122 df<DA07FC13FC91393FFF07FF49B5009F1380903B03FC07FF8FC0903B0FE0
+03FE0FE0903A1FC007FC1F90383F800FD97F0013F8017EED0FC001FE903907F007804992
+C7FC1201ACB812F8A32801FC0007F0C7FCB3AB486C497E267FFFE0B512F0A3333B7FBA30
+>11 D<14E01301EB03C0EB0780EB0F00131EA25B5B13F85B12015B12035B1207A2485AA2
+121F90C7FCA25AA2123EA2127EA5127C12FCB2127C127EA5123EA2123FA27EA27F120FA2
+6C7EA212037F12017F12007F13787F7FA27FEB0780EB03C0EB01E01300135278BD20>40
+D<126012F012787E7E7EA26C7E6C7E7F12017F12007F1378137CA27FA2133F7FA21480A2
+130FA214C0A5130714E0B214C0130FA51480A2131FA21400A25B133EA25BA2137813F85B
+12015B12035B485A48C7FCA2121E5A5A5A126013527CBD20>I<121E123FEA7F80EAFFC0
+A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A
+7A8917>44 D<B512FCA616067F941C>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E
+0A0A7A8917>I<EB01C013031307131F13FFB5FCA2131F1200B3B3A8497E007FB512F0A3
+1C3879B72A>49 D<B591380FFFFE80A2C66D010013E06EEC3F80EF1F00D9EFF0140E8013
+E7EBE3FC8013E1EBE0FF81147F81143F6E7E81140F6E7E8114036E7E8180ED7F8016C015
+3FED1FE016F0150FED07F816FC1503ED01FE16FF81EE7F8E17CE163FEE1FEE17FE160FA2
+16071603A216011600A2486C157E486C153EEA0FFEB500E0141E170EA237397DB83E>78
+D<003FB812E0A3D9E003EB003F90260001FE1307007EEE03F0007C160100781600A30070
+1770A400F01778481738A4C71600B3B0913807FF80011FB612E0A335397DB83C>84
+D<48148039038001C00007130301001380000EEB070048130EA2485BA2485BA3485BA400
+EFEB778039FF807FC001C013E001E013F0A2007F133FA2393FC01FE0391F800FC0390F00
+07801C1A76B92A>92 D<EB3FE0EBFFFC000313FF3907C03F80390F800FC0486C6C7E01E0
+7F6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7FF13801FF01EA07F8EA0FF0EA
+1FE0EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC01C7E383A1FF0787FF8
+3A0FFFF03FF0000301E013E03A007F000F8026277DA52A>97 D<EA03F812FFA3120F1203
+B0EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC09039FE0007E049EB03F0A249
+EB01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F86D14F0ED07E06DEB0FC090
+39E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0283B7EB92E>I<EB03FC90
+381FFF80017F13E09038FE01F03901F800F83903F001FC3807E003EA0FC0121F90388001
+F8003FEB00F01560007F140090C8FCA25AA97EA27FA2003F140E7F001F141C6C7E000714
+386C7ED801FC13F03900FF03E090387FFFC0011F1300EB07F81F277DA525>I<ED1FC0EC
+07FFA3EC007F151FB0EB07F8EB1FFE90387FFF9F9038FE07DF3901F800FF4848137F4848
+133F4848131F121F485AA2127F90C7FCA35AA97EA27F123FA2121F6C6C133F157F6C6C13
+FF3A03F001DFF03A01FC079FFF39007FFF1FEB3FFED907F013C0283B7DB92E>I<EB07F8
+EB1FFF017F13809038FC0FC03901F003E03903E001F0000714F8390FC000FC121F4913FE
+003F147EA248C7127FA35A90B6FCA390C8FCA57EA27F123F15076C7E150E6C7E0007141C
+6C6C133CD801FC13783900FF01F090383FFFC06D1380903803FC0020277EA525>I<147E
+903803FF80010F13C090381FC7E090383F07F0EB7E0F13FE13FC0001EB07E09038F803C0
+000390C7FCADB512FCA3D803F8C7FCB3AB487EB512F8A31C3B7FBA19>I<ED03E090390F
+F00FF090393FFC1FF890B5EA3C7C3A01F81FF0FC3A03E007C07C3A07C003E038000FECF0
+00001F80EB8001003F80A7001F5CEBC003000F5C00075C6C6C485A9038F81F800006B5C7
+FCEB3FFC380E0FF090C9FC121EA3121F6C7E90B512C015F86C14FE6CECFF8016C04815E0
+391F80007F48C7EA0FF0007E140316F8481401A5007EEC03F0A26CEC07E06C6CEB0FC0D8
+0FE0EB3F803A07FC01FF000001B512FC6C6C13F0010790C7FC26387EA52A>I<EA03F812
+FFA3120F1203B0EC07F0EC1FFCEC7FFF9138F07F809038F9C01FD9FB807F9038FF000F49
+805BA35BB3A4486C497EB500E1B51280A3293A7EB92E>I<EA03C0487E487E487EA46C5A
+6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A313387EB718>I<EA03F812
+FFA3120F1203B1913803FFFCA36E13C0913800FE005D15F04A5A4A5A4A5A4AC7FC141E5C
+5C14FCEBF9FE13FBEBFF7F496C7EEBFC1F01F87F6E7E6E7EA26E7E6E7EA26E7E157FA2ED
+3F8016C0486CEB7FF0B500E1B5FCA3283A7EB92C>107 D<EA03F812FFA3120F1203B3B3
+AD487EB512E0A3133A7EB918>I<2703F807F8EB0FF000FFD91FFEEB3FFCDA7FFFEBFFFE
+913AF03F81E07F3D0FF9C00FC3801F802603FB80D9E7007F020013E601FED907FC6D7EA2
+495CA2495CB3A4486C496C497EB500E1B500C3B51280A341257EA446>I<3903F807F000
+FFEB1FFCEC7FFF9138F07F80390FF9C01F2603FB807F9038FF000F49805BA35BB3A4486C
+497EB500E1B51280A329257EA42E>I<EB03FE90380FFF80013F13E09038FE03F83901F8
+00FC4848137E48487F4848EB1F80001F15C049130F003F15E0A248C7EA07F0A44815F8A9
+6C15F0A26D130F003F15E0A26C6CEB1FC0000F15806D133F6C6CEB7F006C6C13FE3900FE
+03F890387FFFF0011F13C0D903FEC7FC25277EA52A>I<3903F80FE000FFEB7FFC9038F9
+FFFE9039FBE07F803A07FF801FC03A03FE000FE049EB07F0A249EB03F816FC150116FEA3
+ED00FFA916FE1501A316FC150316F86DEB07F0ED0FE06D14C09039FF803F809039FBE07F
+009038F9FFFE9038F87FF8EC1FC091C8FCAB487EB512E0A328357EA42E>I<3803F03F00
+FFEB7F809038F1FFE014C7390FF38FF03803F70F13F69038FE07E09038FC03C0EC018091
+C7FCA25BB3A3487EB512F8A31C257EA421>114 D<EBFF83000313E7000F13FFEA1F8038
+3E003F487F00787FA200F87FA37E6C90C7FC6C7EEA7FF8EBFF806C13E06C13F86C7F6C7F
+00017F6C7E01031380EB003F0060EB1FC000E0130FA26C1307A37E15806C130F1500B413
+1EEBC07C38F3FFF800E15B38C07F801A277DA521>I<131CA5133CA3137CA213FC120112
+031207121FB6FCA3D801FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB
+03F01A347FB220>I<D803F8EB0FE000FFEB03FFA3000FEB003F0003140FB3A5151FA215
+3F1201156F6C6CEBEFF8903A7E03CFFF8090383FFF8F6D130FD903FCEBE00029267EA42E
+>I<B538C07FFEA33A0FFC001FF0D803F8EB07C016807F00011500A26D5B0000140EA201
+7F5BA2EC803C013F1338A26D6C5AA214E0010F5BA214F101075BA2903803FB80A214FF6D
+90C7FCA36D5AA2147CA3143827257EA32C>I<B53A8FFFF07FFEA3260FF8009038800FF8
+000791397F0007E0EF03C000031780816DEC80070001027F1400A26D6E5A000002FF130E
+15EF6DECE01ED97F01141C15C70281EBF03CD93F8314381583D91FC36D5AECC701A2D90F
+E76D5AECEE00A2D907FEEBFFC04A137FA201035D4A133FA2010192C7FC4A7FA20100141E
+4A130E37257EA33C>I<B500C0B5FCA300039038007FF06C48EB3F806C6C013EC7FC6D13
+3CEB3F806E5A011F5B6D6C5A14F1903807FBC06DB45A6D90C8FCA26D5A147F818114FF49
+7FECCFF0EB03C790380783F890380F03FCEB0E0190381E00FE497F496D7E01F8133F0001
+81D80FFC497EB548B51280A329247FA32C>I<B538C07FFEA33A07FC001FF06C48EB07C0
+16807F00011500A26C6C130EA26D131E6D131CA26D6C5AA2ECC078011F1370A2ECE0F001
+0F5B14F0903807F1C0A214FB01035BA26DB4C7FCA36D5AA2147CA31438A214781470A25C
+A21301007C5BEAFE035C130749C8FCEAFC1EEA783CEA3FF86C5AEA0FC027357EA32C>I
+E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 565 531 a Fh(This)33 b(do)r(cumen)n(t)h(demonstrates)f(the)i
+(use)g(of)f Fg(n)p Ff(marginchar)d Fh(k)n(erning)h(for)i(hanging)440
+631 y(punktuation)22 b(and)h(h)n(yphenation.)34 b(The)23
+b(same)f(metho)r(d)g(can)h(b)r(e)g(used)g(to)g(ac)n(hiev)n(e)e(optical)
+440 731 y(margin)k(correction)f(\(a)k(fon)n(t)g(can)f(pro)n(vide)e
+(more)h(than)i(one)f Fg(n)p Ff(marginchar)p Fh(\).)565
+830 y(Note)20 b(that)g(the)g(algorithm)c(deals)i(prop)r(erly)g(with)i
+(ligatures)c(\(\\\),)22 b Fg(n)p Ff(parindent)p Fh(,)17
+b(hang-)440 930 y(ing)26 b(inden)n(tation)g(and)h(complex)e
+(discretionaries)e(\()p Fg(n)p Ff(discretionary)p Fg(f)p
+Ff(!)p Fg(g)o(f)p Ff(`)o Fg(gf)o Ff(!`)o Fg(g)p Fh(\).)565
+1029 y(The)i(di\013eren)n(t)f(break)h(in)f(the)i(p)r(en)n(ultimate)d
+(line)g(demonstrates)g(that)j(the)g Fg(n)p Ff(margin-)440
+1129 y(char)g Fh(k)n(erning)f(is)i(in)g(fact)h(tak)n(en)f(in)n(to)f
+(accoun)n(t)h(during)f(line-breaking.)440 1362 y Fe(n)p
+Fd(marginchar)p Fc(=)k Fe(\000)p Fc(1)676 1515 y Fb(\\bla)f(bla)g(bla")
+f(bla)h(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g
+(bla)g(bla)f(bla)h(bla?)676 1614 y(`bla)d(bla)f(bla')g(bla)h(bla)f(bla)
+g(bla)g(bla)h(bla)f(bla)g(bla)h(bla)f(bla)g(bla)g(bla)h(bla)f(bla)g
+(bla)h(bla)676 1714 y(bla)h(bla)f(bla)g(bla)g(bla)h(bla)f(bla)g(bla)h
+(bla)f(bla)g(bla)h(bla)f(bla)g(bla)h(bla)f(bla)g(bla)h(bla)f(bla-)440
+1814 y(bla)32 b(bla)f(bla)h(bla)g(bla)g(bla)f(bla)h(bla)g(bla)f(bla)h
+(bla)g(bla)g(bla)f(bla)h(bla)g(bla)f(bla)h(bla)g(bla)g(bla!)440
+1913 y(`bla)f(bla)f(bla')h(bla)f(bla)h(bla)f(bla)h(bla)f(bla)h(bla)f
+(bla)h(bla)f(bla)h(bla)f(bla)h(bla)f(bla)h(bla)f(bla)h(bla)440
+2013 y(bla)i(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)
+g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)440
+2113 y(bla)d(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)f(bla)h(bla)
+g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla:)43 b(bla:)440
+2212 y(bla:)i(bla)31 b(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)440
+2312 y(bla)38 b(bla)g(bla;)43 b(bla)38 b(bla)g(bla)g(bla)g(bla)g(bla)f
+(bla)h(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla-)440
+2411 y(bla.)49 b(bla)31 b(bla)f(bla)h(bla)g(bla)g(bla)f(bla)h(bla)g
+(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)440
+2511 y(bla;)26 b(bla)h(bla)f(bla)h(bla)f(bla)g(bla)h(bla)f(bla)g(bla)h
+(bla)f(bla)h(bla)f(bla)g(bla)h(bla)f(bla.)440 2743 y
+Fe(n)p Fd(marginchar)p Fc(=)k(128)p Fa(,)37 b(hanging)i(inden)m(tation)
+f(and)h Fe(n)p Fd(parindent)635 2897 y Fb(\\bla)33 b(bla)h(bla")f(bla)g
+(bla)h(bla)g(bla)f(bla)h(bla)f(bla)h(bla)g(bla)f(bla)h(bla)g(bla)f(bla)
+h(bla)g(bla?)653 2996 y(`bla)27 b(bla)f(bla')h(bla)g(bla)f(bla)h(bla)f
+(bla)h(bla)f(bla)h(bla)g(bla)f(bla)h(bla)f(bla)h(bla)f(bla)h(bla)g(bla)
+676 3096 y(bla)g(bla)g(bla)g(bla)h(bla)f(bla)g(bla)g(bla)g(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)h(bla)f(bla)g(bla-)440
+3196 y(bla)33 b(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla!)417
+3295 y(`bla)40 b(bla)f(bla')h(bla)g(bla)g(bla)f(bla)h(bla)g(bla)f(bla)h
+(bla)g(bla)f(bla)h(bla)g(bla)f(bla)h(bla)g(bla)g(bla)440
+3395 y(bla)33 b(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)440
+3494 y(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)
+g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla:)440
+3594 y(bla:)41 b(bla:)h(bla)29 b(bla)g(bla)g(bla)h(bla)f(bla)g(bla)g
+(bla)h(bla)f(bla)g(bla)g(bla)g(bla)h(bla)f(bla)g(bla)g(bla)h(bla)440
+3694 y(bla)h(bla)g(bla)g(bla;)i(bla)e(bla)g(bla)f(bla)h(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)g(bla-)440
+3793 y(bla.)49 b(bla)31 b(bla)f(bla)h(bla)g(bla)g(bla)f(bla)h(bla)g
+(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)440
+3893 y(bla;)26 b(bla)h(bla)f(bla)h(bla)f(bla)g(bla)h(bla)f(bla)g(bla)h
+(bla)f(bla)h(bla)f(bla)g(bla)h(bla)f(bla.)440 4125 y
+Fe(n)p Fd(marginchar)p Fc(=)k(128)p Fa(,)37 b(hanging)i(inden)m(tation)
+f(and)h Fe(n)p Fd(noindent)635 4279 y Fb(\\bla)33 b(bla)h(bla")f(bla)g
+(bla)h(bla)g(bla)f(bla)h(bla)f(bla)h(bla)g(bla)f(bla)h(bla)g(bla)f(bla)
+h(bla)g(bla?)653 4378 y(`bla)27 b(bla)f(bla')h(bla)g(bla)f(bla)h(bla)f
+(bla)h(bla)f(bla)h(bla)g(bla)f(bla)h(bla)f(bla)h(bla)f(bla)h(bla)g(bla)
+676 4478 y(bla)g(bla)g(bla)g(bla)h(bla)f(bla)g(bla)g(bla)g(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)h(bla)f(bla)g(bla-)440
+4577 y(bla)33 b(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla!)417
+4677 y(`bla)40 b(bla)f(bla')h(bla)g(bla)g(bla)f(bla)h(bla)g(bla)f(bla)h
+(bla)g(bla)f(bla)h(bla)g(bla)f(bla)h(bla)g(bla)g(bla)440
+4777 y(bla)33 b(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)440
+4876 y(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)
+g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla)g(bla:)440
+4976 y(bla:)41 b(bla:)h(bla)29 b(bla)g(bla)g(bla)h(bla)f(bla)g(bla)g
+(bla)h(bla)f(bla)g(bla)g(bla)g(bla)h(bla)f(bla)g(bla)g(bla)h(bla)440
+5076 y(bla)h(bla)g(bla)g(bla;)i(bla)e(bla)g(bla)f(bla)h(bla)g(bla)g
+(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)g(bla-)440
+5175 y(bla.)49 b(bla)31 b(bla)f(bla)h(bla)g(bla)g(bla)f(bla)h(bla)g
+(bla)g(bla)f(bla)h(bla)g(bla)g(bla)g(bla)f(bla)h(bla)g(bla)g(bla)440
+5275 y(bla;)26 b(bla)h(bla)f(bla)h(bla)f(bla)g(bla)h(bla)f(bla)g(bla)h
+(bla)f(bla)h(bla)f(bla)g(bla)h(bla)f(bla.)1851 5662 y
+Fh(1)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/systems/tex-extensions/clasen/examples/example5/example5.tex b/systems/tex-extensions/clasen/examples/example5/example5.tex
new file mode 100644
index 0000000000..a12cccb48d
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/example5.tex
@@ -0,0 +1,61 @@
+\documentclass[a4paper]{article}
+\def\cs#1{{\normalfont\ttfamily\textbackslash#1}}
+\font\orm=ocmr10
+
+\def\testpar{``bla bla bla'' bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla?
+`bla bla bla' bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla\-bla bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla\discretionary{!}{`}{!{}`}bla bla bla'
+bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla: bla:
+bla: bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla; bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla\-bla.
+bla bla bla bla bla bla bla bla bla bla bla bla
+bla bla bla bla bla bla bla bla; bla bla bla bla
+bla bla bla bla bla bla bla bla bla bla bla bla.
+}
+
+\begin{document}
+\hyphenpenalty=-1000 % to show a hyphen
+
+This document demonstrates the use of \cs{marginchar} kerning
+for hanging punktuation and hyphenation. The same method can
+be used to achieve optical margin correction (a font can provide
+more than one \cs{marginchar}).
+
+Note that the algorithm deals properly with ligatures (``),
+\cs{parindent}, hanging indentation and complex discretionaries
+(\cs{discretionary}\texttt{\{!\}\{`\}\{!{}`\}}).
+
+The different break in the penultimate line demonstrates that
+the \cs{margin\-char} kerning is in fact taken into account during
+line-breaking.
+
+\subsection*{\cs{marginchar}$=-1$} \marginchar\orm=-1
+\parindent=0pt
+\hangindent=1cm
+\hangafter=-3
+\orm\testpar
+
+\subsection*{\cs{marginchar}$=128$, hanging indentation and \cs{parindent}} \marginchar\orm=128
+\parindent=0pt
+\hangindent=1cm
+\hangafter=-3
+\orm\testpar
+
+\subsection*{\cs{marginchar}$=128$, hanging indentation and \cs{noindent}} \marginchar\orm=128
+\noindent
+\parindent=0pt
+\hangindent=1cm
+\hangafter=-3
+\orm\testpar
+
+\end{document}
diff --git a/systems/tex-extensions/clasen/examples/example5/ocmr10.mf b/systems/tex-extensions/clasen/examples/example5/ocmr10.mf
new file mode 100644
index 0000000000..03fab02de0
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/ocmr10.mf
@@ -0,0 +1,15 @@
+if unknown cmbase: input cmbase fi
+mode_setup;
+
+def generate suffix t = enddef;
+input cmr10
+font_setup;
+
+beginchar(128,0,0,0)
+endchar;
+
+input oroman.mf
+bye.
+
+
+
diff --git a/systems/tex-extensions/clasen/examples/example5/ocomlig.mf b/systems/tex-extensions/clasen/examples/example5/ocomlig.mf
new file mode 100644
index 0000000000..7596a027c6
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/ocomlig.mf
@@ -0,0 +1,62 @@
+% This file defines characters common to roman and italic text fonts
+% that appear only when |ligs>0|.
+
+% Character codes \0042, \0055, \0134, \0173, and \0174 are generated.
+
+ligtable "`": "`"=:oct"134";
+ligtable "'": "'"=:oct"042", "?" kern 2u#, "!" kern 2u#,
+ marginchar kern -5u#;
+
+ligtable "-": "-"=:oct"173", marginchar kern -3u#;
+ligtable oct"173": "-"=:oct"174";
+
+ligtable oct"042": marginchar kern -(7u#+max(2u#,dot_size#));
+
+cmchar "Closing quotes";
+beginchar(oct"042",7u#+max(2u#,dot_size#),asc_height#,0);
+italcorr asc_height#*slant+dot_size#-4.1u#;
+adjust_fit(0,0);
+x1-.5dot_size=hround .6u; y2+.5dot_size=h;
+x2-x1=hround(1.5u+max(2u,dot_size)); y2=y1;
+comma(1,a,dot_size,.25u,comma_depth); % left dot and tail
+comma(2,b,dot_size,.25u,comma_depth); % right dot and tail
+penlabels(1,2); endchar;
+
+cmchar "Hyphen";
+beginchar("-",6u#,x_height#,0);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric thickness; thickness=if hefty:bar else:.75[hair,stem] fi;
+pickup crisp.nib; pos1(thickness,90); pos2(thickness,90);
+top y1r=top y2r=vround(.5h+.5thickness); rt x2=hround(w-u)+eps;
+if monospace: x2=w-x1 else: lft x1=hround .2u-eps fi;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+cmchar "Opening quotes";
+beginchar(oct"134",7u#+max(2u#,dot_size#),asc_height#,0);
+italcorr asc_height#*slant-.1u#;
+adjust_fit(0,0);
+x2+.5dot_size=hround(w-.6u); y1+.5dot_size=h-comma_depth;
+x2-x1=hround(1.5u+max(2u,dot_size)); y2=y1;
+ammoc(1,a,dot_size,.25u,comma_depth); % left dot and tail
+ammoc(2,b,dot_size,.25u,comma_depth); % right dot and tail
+penlabels(1,2); endchar;
+
+cmchar "En dash";
+beginchar(oct"173",9u#,x_height#,0);
+italcorr .61803x_height#*slant+.5u#;
+adjust_fit(0,0);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(.61803h+.5vair); lft x1=-eps; rt x2=w+eps;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+cmchar "Em dash";
+beginchar(oct"174",18u#,x_height#,0);
+italcorr .61803x_height#*slant+.5u#;
+adjust_fit(letter_fit#,letter_fit#);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(.61803h+.5vair); lft x1=-eps; rt x2=w+eps;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
diff --git a/systems/tex-extensions/clasen/examples/example5/oligs.mf b/systems/tex-extensions/clasen/examples/example5/oligs.mf
new file mode 100644
index 0000000000..7a93c911bf
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/oligs.mf
@@ -0,0 +1,6 @@
+ligtable "?": marginchar kern -8.5u#;
+ligtable "!": marginchar kern -(5u#+width_adj#);
+ligtable ":": marginchar kern -5u#;
+ligtable ";": marginchar kern -5u#;
+ligtable "'": marginchar kern -5u#;
+ligtable marginchar: "`" kern -5u#;
diff --git a/systems/tex-extensions/clasen/examples/example5/oroman.mf b/systems/tex-extensions/clasen/examples/example5/oroman.mf
new file mode 100644
index 0000000000..ae15846861
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example5/oroman.mf
@@ -0,0 +1,71 @@
+% The Computer Modern Roman family of fonts (by D. E. Knuth, 1979--1985)
+
+if ligs>1: font_coding_scheme:="TeX text";
+ spanish_shriek=oct"074"; spanish_query=oct"076";
+else: font_coding_scheme:=if ligs=0: "TeX typewriter text"
+ else: "TeX text without f-ligatures" fi;
+ spanish_shriek=oct"016"; spanish_query=oct"017"; fi
+
+mode_setup; font_setup;
+
+input romanu; % upper case (majuscules)
+input romanl; % lower case (minuscules)
+input greeku; % upper case Greek letters
+input romand; % numerals
+input romanp; % ampersand, question marks, currency sign
+input romspl; % lowercase specials (dotless \i, ligature \ae, etc.)
+input romspu; % uppercase specials (\AE, \OE, \O)
+input punct; % punctuation symbols common to roman and italic text
+input accent; % accents common to roman and italic text
+
+marginchar=128;
+
+if ligs>1: input romlig; fi % letter ligatures
+if ligs>0: input ocomlig; fi % ligatures common with italic text
+if ligs<=1: input romsub; fi % substitutes for ligatures
+
+ligtable "!": "`" =: spanish_shriek, marginchar kern -(5u#+width_adj#);
+ligtable "?": "`" =: spanish_query, marginchar kern -8.5u#;
+ligtable ":": marginchar kern -5u#;
+ligtable ";": marginchar kern -5u#;
+ligtable marginchar: "`" kern -5u#, oct"134" kern -(7u#+max(2u#,dot_size#));
+
+font_slant slant; font_x_height x_height#;
+if monospace: font_normal_space 9u#; % no stretching or shrinking
+ font_quad 18u#;
+ font_extra_space 9u#;
+else: font_normal_space 6u#+2letter_fit#;
+ font_normal_stretch 3u#; font_normal_shrink 2u#;
+ font_quad 18u#+4letter_fit#;
+ font_extra_space 2u#;
+ k#:=-.5u#; kk#:=-1.5u#; kkk#:=-2u#; % three degrees of kerning
+ ligtable "k": if serifs: "v": "a" kern -u#, fi\\"w": "e" kern k#,
+ "a" kern k#, "o" kern k#, "c" kern k#;
+ ligtable "P": "A" kern kk#,
+ "y": "o" kern k#, "e" kern k#, "a" kern k#, "." kern kk#, "," kern kk#;
+ ligtable "F": "V": "W": if serifs: "o" kern kk#, "e" kern kk#, "u" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ else: "o" kern k#, "e" kern k#, "u" kern k#,
+ "r" kern k#, "a" kern k#, "A" kern kk#, fi
+ "K": "X": "O" kern k#, "C" kern k#, "G" kern k#, "Q" kern k#;
+ ligtable "T": "y" kern if serifs: k# else: kk# fi,
+ "Y": "e" kern kk#, "o" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kk#, "u" kern kk#;
+ ligtable "O": "D": "X" kern k#, "W" kern k#, "A" kern k#,
+ "V" kern k#, "Y" kern k#;
+ if serifs: ligtable "h": "m": "n":
+ "t" kern k#, "u" kern k#, "b" kern k#, "y" kern k#, "v" kern k#, "w" kern k#;
+ ligtable "c": "h" kern k#, "k" kern k#; fi
+ ligtable "o": "b": "p": "e" kern -k#, "o" kern -k#, "x" kern k#,
+ "d" kern -k#, "c" kern -k#, "q" kern -k#,
+ "a": if serifs: "v" kern k#, "j" kern u#, else: "r" kern k#, fi
+ "t": "y" kern k#,
+ "u": "w" kern k#;
+ ligtable "A": if serifs: "R": fi\\ "t" kern k#,
+ "C" kern k#, "O" kern k#, "G" kern k#, "U" kern k#, "Q" kern k#,
+ "L": "T" kern kk#, "Y" kern kk#, "V" kern kkk#, "W" kern kkk#;
+ ligtable "g": "j" kern -k#; % logjam
+ ligtable "I": "I" kern -k#; fi % Richard III
+ % there are ligature/kern programs for |"f"| in the {\tt romlig} file
+ % and for |"-"|, |"`"|, and |"'"| in the {\tt comlig} file
+bye.
diff --git a/systems/tex-extensions/clasen/examples/example6/README b/systems/tex-extensions/clasen/examples/example6/README
new file mode 100644
index 0000000000..0882e8ae13
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/README
@@ -0,0 +1,15 @@
+This directory contains an example showing a very simple-minded
+LaTeX interface to the \fontvariants primitive. If you replace
+your teTeX 0.9 mktex{mf,tfm,pk} scripts with the variants in this
+direcory and put {t1,}stretch.mf somewhere in your MFINPUTS path
+and stretch.sty somewhere in your TEXINPUTS path, you can test font
+stretching with any LaTeX document by simply adding the line
+
+\usepackage[T1]{fontenc,stretch} \enablestretch
+
+to the document preamble. You can turn font stretching off and on using
+\disablestretch/\enablestretch anywhere in your document.
+
+stretch.sty adds 6 variants (0.97, 0.98, 0.99, 1.01, 1.02, 1.03) to
+any font of the EC family. A reasonable interface would of course
+allow more detailed selection of font variants.
diff --git a/systems/tex-extensions/clasen/examples/example6/example6.dvi b/systems/tex-extensions/clasen/examples/example6/example6.dvi
new file mode 100644
index 0000000000..9ddd1d5372
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/example6.dvi
Binary files differ
diff --git a/systems/tex-extensions/clasen/examples/example6/example6.log b/systems/tex-extensions/clasen/examples/example6/example6.log
new file mode 100644
index 0000000000..81dcf3fd26
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/example6.log
@@ -0,0 +1,235 @@
+This is TeX, Version 3.14159 (with experimental extensions) (Web2C 7.2) (format=latex 1998.7.24) 9 AUG 1998 17:39
+**&../latex example6.tex
+(example6.tex
+LaTeX2e <1997/12/01> patch level 1
+Babel <v3.6h> and hyphenation patterns for american, german, loaded.
+(/usr/local/share/texmf/tex/latex/base/article.cls
+Document Class: article 1997/10/10 v1.3x Standard LaTeX document class
+(/usr/local/share/texmf/tex/latex/base/size10.clo
+File: size10.clo 1997/10/10 v1.3x Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+) (stretch.sty
+Package: stretch 1998/04/18 experimental interface to experimental TeX
+ extensions -- DO NOT USE!!!!
+
+(/usr/local/share/texmf/tex/latex/base/t1cmr.fd
+File: t1cmr.fd 1998/01/10 v2.5f Standard LaTeX font definitions
+))
+(/usr/local/share/texmf/tex/latex/base/fontenc.sty
+Package: fontenc 1998/01/16 v1.9m Standard LaTeX package
+
+(/usr/local/share/texmf/tex/latex/base/t1enc.def
+File: t1enc.def 1998/01/16 v1.9m Standard LaTeX file
+LaTeX Font Info: Redeclaring font encoding T1 on input line 81.
+)
+adding variants for <ecrm1000>< >...
+(fontvariants of ecrm1000: ecrm1000, ecrm1000w0970) ecrm1000w0970
+(fontvariants of ecrm1000: ecrm1000, ecrm1000w0980, ecrm1000w0970)
+ecrm1000w0980
+(fontvariants of ecrm1000: ecrm1000, ecrm1000w0990, ecrm1000w0980, ecrm1000w097
+0) ecrm1000w0990
+(fontvariants of ecrm1000: ecrm1000w1010, ecrm1000, ecrm1000w0990, ecrm1000w098
+0, ecrm1000w0970) ecrm1000w1010
+(fontvariants of ecrm1000: ecrm1000w1020, ecrm1000w1010, ecrm1000, ecrm1000w099
+0, ecrm1000w0980, ecrm1000w0970) ecrm1000w1020
+(fontvariants of ecrm1000: ecrm1000w1030, ecrm1000w1020, ecrm1000w1010, ecrm100
+0, ecrm1000w0990, ecrm1000w0980, ecrm1000w0970) ecrm1000w1030
+)
+No file example6.aux.
+\openout1 = `example6.aux'.
+
+LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 15.
+LaTeX Font Info: ... okay on input line 15.
+LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 15.
+LaTeX Font Info: ... okay on input line 15.
+LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 15.
+LaTeX Font Info: ... okay on input line 15.
+LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 15.
+LaTeX Font Info: ... okay on input line 15.
+LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 15.
+LaTeX Font Info: ... okay on input line 15.
+LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 15.
+LaTeX Font Info: ... okay on input line 15.
+disabling font stretching...
+adding variants for <ecrm1200>< >...
+(fontvariants of ecrm1200: ecrm1200, ecrm1200w0970) ecrm1200w0970
+(fontvariants of ecrm1200: ecrm1200, ecrm1200w0980, ecrm1200w0970)
+ecrm1200w0980
+(fontvariants of ecrm1200: ecrm1200, ecrm1200w0990, ecrm1200w0980, ecrm1200w097
+0) ecrm1200w0990
+(fontvariants of ecrm1200: ecrm1200w1010, ecrm1200, ecrm1200w0990, ecrm1200w098
+0, ecrm1200w0970) ecrm1200w1010
+(fontvariants of ecrm1200: ecrm1200w1020, ecrm1200w1010, ecrm1200, ecrm1200w099
+0, ecrm1200w0980, ecrm1200w0970) ecrm1200w1020
+(fontvariants of ecrm1200: ecrm1200w1030, ecrm1200w1020, ecrm1200w1010, ecrm120
+0, ecrm1200w0990, ecrm1200w0980, ecrm1200w0970) ecrm1200w1030
+adding variants for <ecbx1200>< >...
+(fontvariants of ecbx1200: ecbx1200, ecbx1200w0970) ecbx1200w0970
+(fontvariants of ecbx1200: ecbx1200, ecbx1200w0980, ecbx1200w0970)
+ecbx1200w0980
+(fontvariants of ecbx1200: ecbx1200, ecbx1200w0990, ecbx1200w0980, ecbx1200w097
+0) ecbx1200w0990
+(fontvariants of ecbx1200: ecbx1200w1010, ecbx1200, ecbx1200w0990, ecbx1200w098
+0, ecbx1200w0970) ecbx1200w1010
+(fontvariants of ecbx1200: ecbx1200w1020, ecbx1200w1010, ecbx1200, ecbx1200w099
+0, ecbx1200w0980, ecbx1200w0970) ecbx1200w1020
+(fontvariants of ecbx1200: ecbx1200w1030, ecbx1200w1020, ecbx1200w1010, ecbx120
+0, ecbx1200w0990, ecbx1200w0980, ecbx1200w0970) ecbx1200w1030
+
+Underfull \hbox (badness 1565) in paragraph at lines 20--20
+\T1/cmr/m/n/10 This is a test para-graph for T[]X's paragraph-
+ []
+
+
+Underfull \hbox (badness 1117) in paragraph at lines 20--20
+\T1/cmr/m/n/10 breaking al-go-rithm. It is a fairly com-plex al-
+ []
+
+
+Underfull \hbox (badness 2237) in paragraph at lines 20--20
+\T1/cmr/m/n/10 go-rithm, nev-er-the-less im-prove-ments seem pos-si-
+ []
+
+
+Overfull \hbox (2.36005pt too wide) in paragraph at lines 20--20
+[]\T1/cmr/m/n/10 longnonbreakingword---show some im-prove-ments that
+ []
+
+LaTeX Font Info: Try loading font information for T1+cmtt on input line 22.
+(/usr/local/share/texmf/tex/latex/base/t1cmtt.fd
+File: t1cmtt.fd 1998/01/10 v2.5f Standard LaTeX font definitions
+)
+Underfull \hbox (badness 1565) in paragraph at lines 23--23
+\T1/cmr/m/n/10 This is a test para-graph for T[]X's paragraph-
+ []
+
+
+Underfull \hbox (badness 1117) in paragraph at lines 23--23
+\T1/cmr/m/n/10 breaking al-go-rithm. It is a fairly com-plex al-
+ []
+
+
+Underfull \hbox (badness 2237) in paragraph at lines 23--23
+\T1/cmr/m/n/10 go-rithm, nev-er-the-less im-prove-ments seem pos-si-
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 23--23
+[]\T1/cmr/m/n/10 longnonbreakingword---with long non-break-ing
+ []
+
+
+Underfull \hbox (badness 1248) in paragraph at lines 23--23
+\T1/cmr/m/n/10 words just to make the al-go-rithm work harder
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 23--23
+\T1/cmr/m/n/10 and to---[]longnonbreakingword---show some im-
+ []
+
+enabling font stretching...
+50.64595 -!-> 230.99963
+(adjust_excess: 4.56107 --> 00000000
+ got 1.1646)210.61523 -!-> 202.28477
+(adjust_excess: 0.96045 --> 660606606606666666666666606666666666066666066
+ got -5.24559)208.7268 -!-> 205.33923
+(adjust_excess: 0.98376 --> 50556006500006666060664540654064600650645550640
+ got -3.31505)202.58942 -!-> 202.56213
+(adjust_excess: 0.99986 --> 03330333333333033333333303030333333000340200
+ got -0.00555)222.94556 -!-> 223.39038
+(adjust_excess: 1.002 --> 30323303023323313333023233331333023332332003
+ got 0.4427)202.08954 -!-> 207.0055
+(adjust_excess: 1.02432 --> 000011010001000010000000000000000000000000
+ got 4.73111)210.14313 -!-> 220.61328
+(adjust_excess: 1.04982 --> 0000000000000000000000000000000000000000
+ got 5.72714)217.03033 -!-> 204.2284
+(adjust_excess: 0.94101 --> 6666066666666606066066666666666006606666606
+ got -5.60672)174.54071 -!-> 227.27832
+(adjust_excess: 1.30215 --> 000000000000000000000000000000000000
+ got 4.32672)181.83891 -!-> 222.00183
+(adjust_excess: 1.22087 --> 00000000000000000000000000000
+ got 1.68195)210.61523 -!-> 202.28477
+(adjust_excess: 0.96045 --> 660606606606666666666666606666666666066666066
+ got -5.24559)208.7268 -!-> 205.33923
+(adjust_excess: 0.98376 --> 50556006500006666060664540654064600650645550640
+ got -3.31505)202.58942 -!-> 202.56213
+(adjust_excess: 0.99986 --> 03330333333333033333333303030333333000340200
+ got -0.00555)222.94556 -!-> 223.39038
+(adjust_excess: 1.002 --> 30323303023323313333023233331333023332332003
+ got 0.4427)202.08954 -!-> 207.0055
+(adjust_excess: 1.02432 --> 000011010001000010000000000000000000000000
+ got 4.73111)210.14313 -!-> 220.61328
+(adjust_excess: 1.04982 --> 0000000000000000000000000000000000000000
+ got 5.72714)217.03033 -!-> 204.2284
+(adjust_excess: 0.94101 --> 6666066666666606066066666666666006606666606
+ got -5.60672)174.54071 -!-> 227.27832
+(adjust_excess: 1.30215 --> 000000000000000000000000000000000000
+ got 4.32672)142.23326 -!-> 216.3782
+(adjust_excess: 1.52129 --> 00000000000000000000000
+ got 3.1719)178.92853 -!-> 166.92853
+(adjust_excess: 0.93294 --> 606660666006606066666066066660666666660
+ got -4.43079)
+Overfull \hbox (5.34753pt too wide) detected at line 33
+\x F\x l\x ^^fcss\x i\x gke\x it\x sg\x l\x e\x i\x chgew\x i\x ch\x t \x und S
+\x t\x o\T1/cmr/m/n/10 ff\x wechse\x l
+ []
+
+178.92853 -!-> 170.92853
+(adjust_excess: 0.95529 --> 606660666006606066666066066660666666660
+ got -4.43079)
+Overfull \hbox (1.34753pt too wide) detected at line 34
+\x F\x l\x ^^fcss\x i\x gke\x it\x sg\x l\x e\x i\x chgew\x i\x ch\x t \x und S
+\x t\x o\T1/cmr/m/n/10 ff\x wechse\x l
+ []
+
+178.92853 -!-> 174.92853
+(adjust_excess: 0.97765 --> 506650665006606066666065066650665655550
+ got -3.91612)178.92853 -!-> 175.92853
+(adjust_excess: 0.98323 --> 505550555006605065455055064550645545540
+ got -2.9408)178.92853 -!-> 176.92853
+(adjust_excess: 0.98882 --> 405440544006405054444054054440644444440
+ got -1.94975)178.92853 -!-> 177.92853
+(adjust_excess: 0.99442 --> 403440434004404034434034043430443443440
+ got -0.99596)178.92853 -!-> 179.92853
+(adjust_excess: 1.00558 --> 203220232002202032232032023230223223220
+ got 0.99574)178.92853 -!-> 180.92853
+(adjust_excess: 1.01118 --> 201220122000201012222012012220022222220
+ got 1.94945)178.92853 -!-> 181.92853
+(adjust_excess: 1.01677 --> 101110111000001001211011002110021121120
+ got 2.94054)178.92853 -!-> 182.92853
+(adjust_excess: 1.02235 --> 100010001000000000000001000010001011110
+ got 3.91585)178.92853 -!-> 186.92853
+(adjust_excess: 1.04471 --> 000000000000000000000000000000000000000
+ got 4.4305)178.92853 -!-> 190.92853
+(adjust_excess: 1.06706 --> 000000000000000000000000000000000000000
+ got 4.4305)
+Underfull \hbox (badness 1168) detected at line 45
+\x Fl^^fcssigkeitsgleichgewicht und Sto\T1/cmr/m/n/10 ff\x wechsel
+ []
+
+disabling font stretching...
+[1
+
+] (example6.aux) )
+Here is how much of TeX's memory you used:
+ 259 strings out of 10928
+ 2994 string characters out of 147947
+ 49322 words of memory out of 263001
+ 3210 multiletter control sequences out of 10000+0
+ 20297 words of font info for 36 fonts, out of 200000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 23i,4n,19p,208b,168s stack positions out of 300i,100n,500p,30000b,4000s
+
+Output written on example6.dvi (1 page, 4760 bytes).
diff --git a/systems/tex-extensions/clasen/examples/example6/example6.ps b/systems/tex-extensions/clasen/examples/example6/example6.ps
new file mode 100644
index 0000000000..e7a32c510e
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/example6.ps
@@ -0,0 +1,856 @@
+%!PS-Adobe-2.0
+%%Creator: dvips 5.76a Copyright 1997 Radical Eye Software (www.radicaleye.com)
+%%Title: example6.dvi
+%%Pages: 1
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%EndComments
+%DVIPSCommandLine: dvips -a -D600 -mode ljfive example6.dvi -o
+%+ example6.ps
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource: TeX output 1998.08.09:1739
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N
+/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id
+gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp
+add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add
+/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{
+dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1
+adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2
+idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string
+putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval
+adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg}
+{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{
+adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2
+chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{]
+}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop false[(Display)(NeXT)
+(LaserWriter 16/600)]{dup length product length le{dup length product
+exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}
+ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}
+imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false
+RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round
+exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto
+rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail{dup
+/delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}B /d{
+-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B
+/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}
+B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B
+/bos{/SS save N}B /eos{SS restore}B end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (example6.dvi)
+@start
+%DVIPSBitmapFont: Fa ecrm1000w1020 10 20
+/Fa 20 253 df<DA07FE137E913A3FFF83FF8091B500CF13C0903B03FC03FFC7E090260F
+E001EB07F0903A1FC003FE0F90383F8007D97F0013FC017EED07E001FE903903F803C049
+92C7FC1201ACB812FCA32801FC0003F8C7FCB3AB486C497E267FFFF0B512F8A3343B7FBA
+31>27 D<B812FCA30001903880001F6C90C71201EE00FE177E173E171EA2170EA4170F17
+07A2ED01C0A21700A41503A21507151F91B5FCA3EC001F15071503A21501A692C8FCAD48
+13C0B612C0A330397DB837>70 D<D90FF013C090387FFE0190B512813903F80FC33907C0
+01E7390F80007748C7123F151F003E140FA2481407A200FC1403A415017EA27E6C91C7FC
+7F7FEA3FF8EBFF806C13F06C13FF15E06C80000114FC6C80013F7F1307D9007F13800207
+13C01400ED3FE0151F150F16F01507126000E01403A57E16E0A26C14076C15C0A26CEC0F
+806CEC1F00D8FBC0131ED8F9F0137C39F0FE01F839E07FFFF0010F13C0D8C00190C7FC24
+3D7BBA2F>83 D<EA03F812FFA3120F1203B0EC0FF0EC3FFE91B5FC9039FBF03FC09039FF
+800FE091380003F001FC80150149806F7EA28282A21780A91700A316FEA25E15016D5C6D
+495A6D495A9039E7800FC09039E3E03F8001C0B5C7FC9038807FFCC7EA0FE0293B7EB92F
+>98 D<EB03FE90381FFFC0017F13F09038FE01F83901F8007C484813FE3807E001EA0FC0
+121FEC00FC484813781530007F140090C8FCA25AA97EA27F123F15076C7E150E6C7E0007
+141C6C6C133CD801FC13783900FF01F090387FFFC0011F1380903803FC0020277DA526>
+I<ED0FE0EC03FFA3EC003F150FB0EB03F8EB1FFF017F13CF9038FE03EF3901F800FF4848
+133F4848131F485A001F140F5B123FA248C7FCA35AA97EA27F123FA26C6C131F120F6D13
+3F0007147F3A03F801EFF83B01FE07CFFF8039007FFF8F90381FFE0FD907F8EBE000293B
+7DB92F>I<EB03FCEB1FFF017F13C09038FE0FE03901F803F03903E001F800076D7E4848
+137E121F49137F003F80A248C7FC1680A25A90B6FCA390C9FCA57EA27F123FED03806C7E
+ED07006C7E0007140ED803F85B6C6C5B3900FF80F090383FFFE0010F1380D901FEC7FC21
+277EA526>I<ED03E090390FF00FF090393FFC1FF890B5EA3C7C3A01F81FF0FC3A03E007
+C07C3A07C003E038000FECF000001F80EB8001003F80A7001F5CEBC003000F5C00075C6C
+6C485A9038F81F800006B5C7FCEB3FFC380E0FF0000CC9FC121EA3121F6C7E90B512C015
+F86C14FE6CECFF8016C04815E0391F80007F48C7EA0FF0007E140316F8481401A5007EEC
+03F0A26CEC07E06C6CEB0FC0D80FE0EB3F803A07FC01FF000001B512FC6C6C13F0010790
+C7FC26387EA52A>103 D<EA03F812FFA3120F1203B0EC07F8EC1FFEEC7FFF9138F03F80
+9039F9C00FC0D9FB807F140001FE6D7EA25BA25BB3A4486C497EB500E1B512C0A32A3A7E
+B92F>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA48
+7EB512E0A313387EB718>I<EA03F812FFA3120F1203B1913801FFFEA36E13E06FC7FC15
+7E15785D4A5A4A5A4AC8FC141E5C147C14FCEBF9FEEBFBFF9038FF3F8013FE496C7E496C
+7E1407816E7E6E7EA26E7E157F81826F7E82486CEB3FF8B500E0B51280A3293A7EB92D>
+107 D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<3903F807F800FF
+EB1FFEEC7FFF9138F03F803A0FF9C00FC02603FB807F140001FE6D7EA25BA25BB3A4486C
+497EB500E1B512C0A32A257EA42F>110 D<EB03FE90380FFF80013F13E09038FE03F839
+01F800FC4848137E48487F4848EB1F80001F15C049130F003F15E0A248C7EA07F0A44815
+F8A96C15F0A26D130F003F15E0A26C6CEB1FC0000F15806D133F6C6CEB7F006C6C13FE39
+00FE03F890387FFFF0011F13C0D903FEC7FC25277EA52A>I<3803F03F00FFEB7F809038
+F1FFE014C7390FF38FF03803F70F13F69038FE07E09038FC03C0EC018091C7FCA25BB3A3
+487EB512F8A31C257EA421>114 D<EBFF83000313E7000F13FFEA1F80383E003F487F00
+787FA200F87FA37E6C90C7FC6C7EEA7FF8EBFF806C13E06C13F86C7F6C7F00017F6C7E01
+031380EB003F0060EB1FC000E0130FA26C1307A37E15806C130F1500B4131EEBC07C38F3
+FFF800E15B38C07F801A277DA521>I<131CA5133CA3137CA213FC120112031207121FB6
+FCA3D801FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB03F01A347FB2
+20>I<D803F8EB07F000FFEB01FFA3000FEB001F00031407B3A4150FA3151F120115376C
+6CEB77FC903A7F01E7FFC090383FFFC76D1307D903FCEBF0002A267EA42F>I<B53A8FFF
+F03FFFA3260FF8009038800FFC000791397F0003F0EF01E000036E14C0A26C6C91388003
+80A36C6C9138C00700157FA2017F9038FFE00E15E70280141ED93F81EBF01C15C302C1EB
+F83CD91FC31438158102E3EBFC7890260FE7001370A2D907F76D5A02FE137EA20103EC7F
+C04A133FA201015D4A131FA2010092C7FC4A7F0270130E38257EA33D>119
+D<011E131E013F133F496C487E496C487EA46D486C5A6D486CC7FC011E131E90CAFCA8D8
+03F8EB07F000FFEB01FFA3000FEB001F00031407B3A4150FA3151F120115376C6CEB77FC
+903A7F01E7FFC090383FFFC76D1307D903FCEBF0002A387EB62F>252
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fb ecrm1000w1010 10 19
+/Fb 19 253 df<DA07FE137E913A3FFF83FF8091B500CF13C0903B03FC03FFC7E090260F
+E001EB07F0903A1FC003FE0F90383F8007D97F0013FC017EED07E001FE903903F803C049
+92C7FC1201ACB812F8A32801FC0003F8C7FCB3AB486C497E267FFFF0B512F8A3343B7FBA
+31>27 D<B812FCA30001903880001F6C90C71201EE00FE177E173E171EA2170EA4170F17
+07A2ED01C0A21700A41503A21507151F91B5FCA3EC001F15071503A21501A692C8FCAD48
+13C0B612E0A330397DB837>70 D<D90FF013C090387FFE0190B512813903F80FC33907C0
+01E7390F80007748C7123F151F003E140FA2481407A200FC1403A415017EA27E6C91C7FC
+7F7FEA3FF813FF6C13F06C13FF15E06C80000114FC6C80013F7F1307D9007F1380020713
+C01400ED3FE0151F150F16F01507126000E01403A57E16E0A26C14076C15C0A26CEC0F80
+6CEC1F00D8FBC0131ED8F9F0137C39F0FE01F839E07FFFF0010F13C0D8C00190C7FC243D
+7BBA2F>83 D<EB03FC90381FFF80017F13E09038FE01F03901F800F83903F001FC3807E0
+03EA0FC0121F90388001F8003FEB00F01560007F140090C8FCA25AA97EA27FA2003F140E
+7F001F141C6C7E000714387F6C6C13F03900FF03E090387FFFC0011F1300EB07F81F277D
+A525>99 D<ED0FE0EC03FFA3EC003F150FB0EB03F8EB1FFF017F13CF9038FE03EF3901F8
+00FF4848133F4848131F485A001F140F5B123FA248C7FCA35AA97EA27F123FA26C6C131F
+120F6D133F0007147F3A03F801EFF83B01FE07CFFF8039007FFF8F90381FFE0FD907F8EB
+E000293B7DB92F>I<EB07F8EB1FFF017F13809038FC0FC03901F003E03903E001F00007
+14F8390FC000FC121F4913FE003F147EA248C7127FA35A90B6FCA390C8FCA57EA27F123F
+15076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F090383FFFC06D13809038
+03FC0020277EA525>I<ED03E090390FF00FF090393FFC1FF890B5EA3C7C3A01F81FF0FC
+3A03E007C07C3A07C003E038000FECF000001F80EB8001003F80A7001F5CEBC003000F5C
+00075C6C6C485A9038F81F800006B5C7FCEB3FFC380E0FF0000CC9FC121EA3121F6C7E90
+B512C015F86C14FE6CECFF8016C04815E0391F80007F48C7EA0FF0007E140316F8481401
+A5007EEC03F0A26CEC07E06C6CEB0FC0D80FE0EB3F803A07FC01FF000001B512FC6C6C13
+F0010790C7FC26387EA52A>103 D<EA03F812FFA3120F1203B0EC07F8EC1FFEEC7FFF91
+38F03F809039F9C00FC0D9FB807F140001FE6D7EA25BA25BB3A4486C497EB500E1B512C0
+A32A3A7EB92F>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA3120712
+03B3AA487EB512E0A313387EB718>I<EA03F812FFA3120F1203B1913803FFFCA3020013
+C0EDFE005D15F04A5A4A5A4A5A4AC7FC141E5C5C14FCEBF9FE13FBEBFF7F496C7EEBFC1F
+01F87F6E7E6E7EA26E7E6E7EA26E7E157FA2ED3F8016C0486CEB7FF0B500E1B5FCA3283A
+7EB92C>107 D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<3903F807
+F800FFEB1FFEEC7FFF9138F03F803A0FF9C00FC02603FB807F140001FE6D7EA25BA25BB3
+A4486C497EB500E1B512C0A32A257EA42F>110 D<EB03FE90380FFF80013F13E09038FE
+03F83901F800FC4848137E48487F4848EB1F80001F15C049130F003F15E0A248C7EA07F0
+A44815F8A96C15F0A26D130F003F15E0A26C6CEB1FC0000F15806D133F6C6CEB7F006C6C
+13FE3900FE03F890387FFFF0011F13C0D903FEC7FC25277EA52A>I<3803F03F00FFEB7F
+809038F1FFE014C7390FF38FF03803F70F13F69038FE07E09038FC03C0EC018091C7FCA2
+5BB3A3487EB512F8A31C257EA421>114 D<EBFF83000313E7000F13FFEA1F80383E003F
+487F00787FA200F87FA37E6C90C7FC6C7EEA7FF8EBFF806C13E06C13F86C7F6C7F00017F
+6C7E01031380EB003F0060EB1FC000E0130FA26C1307A37E15806C130F1500B4131EEBC0
+7C38F3FFF800E15B38C07F801A277DA521>I<131CA5133CA3137CA213FC120112031207
+121FB6FCA3D801FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB03F01A
+347FB220>I<D803F8EB07F000FFEB01FFA3000FEB001F00031407B3A4150FA3151F1201
+15376C6CEB77FC903A7F01E7FFC090383FFFC76D1307D903FCEBF0002A267EA42F>I<B5
+3A8FFFF03FFFA3260FF8009038800FFC000791397F0003F0000317E0EF01C0816C6C9138
+800380A36C6C9138C00700157F6D5D6DECE00E15E70280141ED93F81EBF01C15C302C114
+3CD91FC3EBF8381581D90FE36D5A14E71500D907F76D5A02FE137EA20103EC7FC04A133F
+A201015D4A131FA2010092C7FC4A7F0270130E38257EA33D>119
+D<011E131E013F133F496C487E496C487EA46D486C5A6D486CC7FC011E131E90CAFCA8D8
+03F8EB07F000FFEB01FFA3000FEB001F00031407B3A4150FA3151F120115376C6CEB77FC
+903A7F01E7FFC090383FFFC76D1307D903FCEBF0002A387EB62F>252
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fc ecrm1000w0990 10 20
+/Fc 20 253 df<DA07FC13FC91393FFF07FF49B5009F1380903B03FC07FF8FC0903B0FE0
+03FE0FE0903A1FC007FC1F90383F800FD97F0013F8017EED0FC001FE903907F007804992
+C7FC1201ACB812F0A32801FC0007F0C7FCB3AB486C497E267FFFE0B512F0A3333B7FBA30
+>27 D<B812F8A30001903880001F6C90C71203EE01FC1600177C173CA2171CA4171E170E
+A2ED0380A21700A41507A2150F153F91B5FCA3EC003F150F1507A21503A692C8FCAD4813
+C0B612E0A32F397DB836>70 D<90390FF0018090387FFC0348B5FC3903F01FC73907C003
+EF390F8000FF48C7127F153F003E141FA248140FA200FC1407A415037EA36C91C7FC6C7E
+7FEA3FF013FF6C13F014FF6C14C06C14F06C80C6806D7F010F7F1300020F138014019138
+007FC0153F151F16E0150F126000E01407A57E16C0A26C140F16807E6CEC1F006C141E01
+C0133ED8FBF05B39F0FE01F839E07FFFE0011F5B26C001FEC7FC233D7BBA2E>83
+D<EB3FE03801FFF8000713FE380F807F391F001F80486C6C7E01C07F6E7EA26C486C7EEA
+0F001206C7FCA4EB01FF131FEB7FF33801FE03EA07F8EA0FF0EA1FC0123FEA7F80A2D8FF
+001438A41407A2387F800F140D3A3FC018FC703A1FE070FFF03A0FFFE07FE0000301C013
+C03A007F001F0025277DA529>97 D<EB03FC90381FFF80017F13E09038FE01F03901F800
+F83903F001FC3807E003EA0FC0121F90388001F8003FEB00F01560007F140090C8FCA25A
+A97EA27FA2003F140E7F001F141C6C7E000714386C7ED801FC13F03900FF03E090387FFF
+C0011F1300EB07F81F277DA525>99 D<ED1FC0EC07FFA3EC007F151FB0EB07F8EB1FFE90
+387FFF9F9038FE07DF3901F800FFD807F0137F49133F4848131F121F485AA2127F90C7FC
+A35AA97EA27F123FA2121F6C6C133F157F6C6C13FF3A03F001DFF03A01FC079FFF39007F
+FF1FEB3FFED907F013C0283B7DB92E>I<EB07F8EB1FFF017F13809038FC0FC03901F003
+E03903E001F0000714F8390FC000FC121F4913FE003F147EA248C7127FA35A90B6FCA390
+C8FCA57EA27F123F15076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F09038
+3FFFC06D1380903803FC0020277EA525>I<ED03C090390FE01FF090387FFC3F9039FFFE
+78F83901F83FE13903E00F803A07C007C070000FECE00048486C7EA2003F80A7001F5CA2
+6C6C485A00075C6C6C485AD9F83FC7FC3806FFFE380E7FFCEB0FE0000CC9FC121C121EA2
+121F6C7E90B57E15F06C14FC6C14FF16804815C0381F800048C7EA1FE0007E140716F048
+1403A5007EEC07E0A26CEC0FC06C6CEB1F80D80FE0EB7F003907FC03FE0001B512F86C6C
+13E0D907FEC7FC25387EA529>103 D<EA03F812FFA3120F1203B0EC07F0EC1FFCEC7FFF
+9138F07F809038F9C01FD9FB807F9038FF000F49805BA35BB3A4486C497EB500E1B51280
+A3293A7EB92E>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA3120712
+03B3AA487EB512E0A313387EB718>I<EA03F812FFA3120F1203B1913807FFF8A3020113
+80EDFE00EC00F8EC01E05D4A5A4AC7FC140E5C5C1478EBF9FC13FBEBFFFE147F13FE496C
+7E496C7EA26E7E6E7EA26E7E1401816E7E157E157F1680486CEBFFE0B500E313FEA3273A
+7EB92B>107 D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<3903F807
+F000FFEB1FFCEC7FFF9138F07F80390FF9C01F2603FB807F9038FF000F49805BA35BB3A4
+486C497EB500E1B51280A329257EA42E>110 D<EB03FC90381FFF80017F13E09038FE07
+F03901F801F848486C7E4848137E48487F4848EB1F80A2003F15C090C7120F4815E0A348
+15F0AA6C15E0A26D131F003F15C0A2001F15806C6CEB3F006D5B6C6C13FE6C6C485A3900
+FE07F090387FFFE0011F1380D903FCC7FC24277EA529>I<3903F80FE000FFEB7FFC4A7E
+9039FBE07F803A07FF801FC03A03FE000FE049EB07F0A249EB03F816FC150116FEA3ED00
+FFA916FE1501A316FC150316F86DEB07F0ED0FE06D14C09039FF803F809039FBE07F0090
+38F9FFFE9038F87FF8EC1FC091C8FCAB487EB512E0A328357EA42E>I<EBFF06000313CE
+000F13FEEA1F80383C003E007C131E1278A200F8130EA37E6C90C7FC7EEA7FF0EBFF806C
+13E06C7F6C7F6C7F00017F6C6C7E1303EB007F0060EB3F8000E0131FA26C130FA37E1500
+6C5B141E6C133E38FF80FC38F3FFF800E113E038C07F8019277DA520>115
+D<131CA5133CA3137CA213FC120112031207121FB6FCA3D801FCC7FCB2EC01C0A93900FE
+0380A2017E13006D5AEB1FFE6D5AEB03F01A347FB220>I<D803F8EB0FE000FFEB03FFA3
+000FEB003F0003140FB3A5151FA2153F1201156F6C6CEBEFF8903A7E03CFFF8090383FFF
+8F6D130FD903FCEBE00029267EA42E>I<B53A1FFFE0FFFCA3260FF8019038001FF06C48
+6C48EB0FC06DED078000031700157E6D017F5B0001160EA26DEC801E000002FF131CA26D
+ECC03C90267F01CF1338A20281EBE07890263F83871370A202C3EBF0F090261FC7035BA2
+02E713F990260FEE015BA202FE13FF6D486C5BA2010392C7FC4A7FA20101147E4A133EA2
+0100143C4A131C36257EA33B>119 D<011C131C017F137F496C487EA214C1A21480A26D
+486CC7FC011C131C90CAFCA8D803F8EB0FE000FFEB03FFA3000FEB003F0003140FB3A515
+1FA2153F1201156F6C6CEBEFF8903A7E03CFFF8090383FFF8F6D130FD903FCEBE0002938
+7EB62E>252 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fd ecrm1000w0980 10 23
+/Fd 23 253 df<913907F801F891397FFE0FFE49B5EA3FFF903B07F80FFF1F8090270FE0
+07FC13C0903A1F800FF83F90383F001F4914F001FEED1F8092390FE00F004992C7FC1201
+ACB812F0A32801FC000FE0C7FCB3AB486C497E267FFFE1B512E0A3323B7FBA2F>27
+D<B812F0A30001903880003F6C90C71207EE03F8160116001778A21738A4173C171CA215
+07A21700A45DA25D157F91B5FCA3EC007F151F81A281A692C8FCAD4813C0B612C0A32E39
+7DB835>70 D<90390FF0018090387FFE0390B512833903F80FC73907C001EF390F8000FF
+48C7127F153F003E141FA248140FA200FC1407A415037EA27E6C91C7FC7F7FEA3FF8EBFF
+806C13F06C13FF15E06C80000114FC6C80013F7F1307D9007F1380020713C01400ED3FE0
+151F150F16F01507126000E01403A57E16E0A26C14076C15C0A26CEC0F806CEC1F00D8FB
+C0131ED8F9F0137C39F0FE01F839E07FFFF0010F13C0D8C00190C7FC243D7CBA2D>83
+D<EB3FE03801FFF84813FE3807C07F390F801F80486C6C7E01E07F6E7EA26C486C7EEA07
+80EA0300C7FCA4EB01FF131FEB7FF33801FE03EA07F8EA0FF0EA1FC0123FEA7F80A2D8FF
+001438A41407A2387F800F140D3A3FC018FC703A1FE070FFF03A0FFFE07FE0000301C013
+C03A007F001F0025277DA529>97 D<EB07FCEB1FFF017F13C09038FC03E03901F001F039
+03E003F800071307EA0FC0121F90388003F0003FEB01E0EC00C0007F140090C8FCA25AAA
+7E7FA2003F141C7F001F1438120F6D13706C7E3903F801E03901FE07C039007FFF809038
+3FFE00EB07F81E277DA524>99 D<ED3F80EC0FFFA31400153FB0EB07F0EB1FFEEB7FFF39
+01FE07BF3903F801FF3807E000000F147F49133F121F485AA2127F90C7FCA25AAA7EA36C
+7EA2121F6D137F000F14FF6C7E2603F00313E03A01FC0FBFFE3900FFFE3FEB3FFCD90FE0
+1380273B7DB92D>I<EB07F0EB3FFE497E3901FC1FC03903F007E03907E003F013C0000F
+EB01F8EA1F80003F14FC1400A248C712FEA35A90B5FCA390C8FCA57EA27F123F150E121F
+6D131C120F6C6C13386C7ED801FC13F03900FF03E090387FFF80011F1300EB03F81F277E
+A524>I<ED03C090390FE01FF090387FFC3F9039FFFE78F83901F83FE13903E00F803A07
+C007C070000FECE00048486C7EA2003F80A7001F5CA26C6C485A00075C6C6C485AD9F83F
+C7FC3806FFFE380E7FFCEB0FE0000CC9FC121C121EA2121F6C7E90B57E15F06C14FC6C14
+FF16804815C0381F800048C7EA1FE0007E140716F0481403A5007EEC07E0A26CEC0FC06C
+6CEB1F80D80FE0EB7F003907FC03FE0001B512F86C6C13E0D907FEC7FC25387EA529>
+103 D<EA03F812FFA3120F1203B0EC0FE0EC3FF8EC7FFEECF07F9038F9C03FD9FB001380
+01FF131F4914C05BA35BB3A4486CEB3FE0B500E1B5FCA3283A7EB92D>I<EA03C0487E48
+7E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A313387EB718
+>I<EA03F812FFA3120F1203B1913807FFF8A302011380EDFE00EC00F8EC01E05D4A5A4A
+C7FC140E5C5C1478EBF9FC13FBEBFFFE147F13FE496C7E496C7EA26E7E6E7EA26E7E1401
+816E7E157E157F1680486CEBFFE0B500E313FEA3273A7EB92B>107
+D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<2703F807F0EB1FC000
+FFD91FFCEB7FF0913A7FFF01FFFC913AF07F83C1FE3C0FF9C01F87007E2603FB8001CE13
+7F9027FF000FDC7F4902F81480495CA3495CB3A4486C496CEB7FC0B500E1B53887FFFEA3
+3F257EA444>I<3903F80FE000FFEB3FF8EC7FFEECF07F390FF9C03F2603FB00138001FF
+131F4914C05BA35BB3A4486CEB3FE0B500E1B5FCA328257EA42D>I<EB03FC90381FFF80
+017F13E09038FE07F03901F801F848486C7E4848137E48487F4848EB1F80A2003F15C090
+C7120F4815E0A34815F0AA6C15E0A26D131F003F15C0A2001F15806C6CEB3F006D5B6C6C
+13FE6C6C485A3900FE07F090387FFFE0011F1380D903FCC7FC24277EA529>I<3803F07E
+00FF13FF01F113C0EBF38F390FF71FE0EA03F613FE9038FC0FC0EC0780EC030091C7FC5B
+B3A4487EB512F8A31B257EA420>114 D<EBFF06000313CE000F13FEEA1F80383C003E00
+7C131E1278A200F8130EA37E6C90C7FC7EEA7FF0EBFF806C13E06C7F6C7F6C7F00017F6C
+6C7E1303EB007F0060EB3F8000E0131FA26C130FA37E15006C5B141E6C133E38FF80FC38
+F3FFF800E113E038C07F8019277DA520>I<131CA5133CA3137CA213FC12011203120712
+1FB6FCA3D801FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB03F01A34
+7FB220>I<D803F8EB1FC000FFEB07FFA3000FEB007F0003141FB3A5153FA30001147F15
+FF3A00FC01DFF090397E039FFF90383FFF1FEB1FFED907F813C028267EA42D>I<B538C0
+FFFCA33A0FFC001FE06C48EB0FC00003158016006C6C130EA26D131E0000141CA26D133C
+6D1338A26D6C5AA36D6C5AA214E1010F5BA214F301075BA26DB4C7FCA36D5AA36D5AA314
+78A226257EA32B>I<B53A1FFFE0FFFCA3260FF8019038003FF06C486C48EB0FC06DED07
+8000031700157E6D017F5B0001160EA26DEC801E000002FF131CA26DECC03C6D48143815
+CFD93F816D5A14831587D91FC36D5A14C71503D90FE7EBF9C0ECEE01A2D907FEEBFF804A
+7EA2010392C7FC4A7FA20101147E4A133EA20100143C4A131C36257EA33B>I<B538C1FF
+FEA300039038007FE06C4814000000143E017F1338EC8078013F5B6D6C5A14E190380FE3
+C0903807F78002FFC7FC7F6D5A130080804A7E815B903803CFE0EC8FF0EB0707496C7E01
+1E7FEB1C0190383C00FE497F01F87F00011580D80FFCEBFFE0B5000313FFA328247FA32B
+>I<013C133C017E137E01FF13FF4801811380A46C01001300017E137E013C133C90C9FC
+A8D803F8EB1FC000FFEB07FFA3000FEB007F0003141FB3A5153FA30001147F15FF3A00FC
+01DFF090397E039FFF90383FFF1FEB1FFED907F813C028387EB62D>252
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fe ecrm1000w1030 10 29
+/Fe 29 253 df<DA03FE133F913A3FFFC1FFC091B500E713E0903B03FC01FFE3F0902607
+F000EB83F890261FC001130749485AD97F0013FE017EED03F001FE903901FC01E04992C7
+FC1201ACB812FCA32801FC0001FCC7FCB3AB486C497E3B7FFFF07FFFFCA3353B7FBA32>
+27 D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA07
+00A2120E5A123C123812100B1A7AB917>39 D<121E123FEA7F80EAFFC0A213E0A2127F12
+3F121E1200A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A7A8917>44
+D<B512FCA616067F941C>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A7A8917>
+I<B812FEA30001903880000F6C90C71201EE007F838383A383A318801703A216E0A294C7
+FCA41501A21503150F91B5FCA3EC000F15031501A21500A693C8FCAD4813C0B612E0A331
+397DB838>70 D<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81E>73
+D<D907F81360D93FFF13E090B512C03901F807E13903E000F3D80780133B48C7121F4814
+0F003E1407A2481403A2150112FCA315007EA27E6C150013C07FEA3FFCEBFFC06C13F86C
+EBFF806C14F06C14FC6C806C6C7F011F1480010314C0D9003F13E014039138007FF0ED1F
+F81507A2ED03FC1501126012E01500A47E16F87E15016C15F016E06C14036C6CEB07C0D8
+FBC0EB0F80D8F9F0EB1F00D8F0FF137E39E03FFFFC010F13F048C61380263D7CBA2F>83
+D<EB1FF0EBFFFE00036D7E3907C01FC048486C7E391FC003F001E07F6E7EA2380FC0006C
+487F6CC7FCC8FCA4147FEB0FFFEB7FF83801FF00EA07FCEA0FF0485A485A5B127F48C713
+0EA41401A2397F80037E14073A3FC00E3F1C261FF03C13FC3A07FFF81FF86C01E013F03A
+007F8007C027277DA52B>97 D<EA03F812FFA3120F1203B0EC0FF0EC3FFE91B5FC9039FB
+F03FC09039FF800FE091380003F001FC80150149806F7EA28282A21780A91700A316FEA2
+5E15016D5C6D495A6D495A9039E7800FC09039E3E03F8001C0B5C7FC9038807FFCC7EA0F
+E0293B7EB92F>I<EB03FE90381FFFC0017F13F09038FE01F83901F8007C484813FE3807
+E001EA0FC0121FEC00FC484813781530007F140090C8FCA25AA97EA27F123F15076C7E15
+0E6C7E0007141C6C6C133CD801FC13783900FF01F090387FFFC0011F1380903803FC0020
+277DA526>I<ED0FE0EC03FFA3EC003F150FB0EB03F8EB1FFF017F13CF9038FE03EF3901
+F800FF4848133F4848131F485A001F140F5B123FA248C7FCA35AA97EA27F123FA26C6C13
+1F120F6D133F0007147FD803F8EBEFF83B01FE07CFFF8039007FFF8F90381FFE0FD907F8
+EBE000293B7DB92F>I<EB03FCEB1FFF017F13C09038FE0FE03901F803F03903E001F800
+076D7E4848137E121F49137F003F80A248C7FC1680A25A90B6FCA390C9FCA57EA27F123F
+ED03806C7EED07006C7E0007140ED803F85B6C6C5B3900FF80F090383FFFE0010F1380D9
+01FEC7FC21277EA526>I<ED01F0903907F007F890393FFE0FFC90B5EA9E3E3A01F80FF8
+7E3A03E003E03E0007ECF01C3A0FC001F800001F80EB8000003F80A7001F5CEBC001000F
+5C6C6C485A00035C9038F80FC00006B55AD93FFEC7FC380E07F090C9FCA2121EA27E7F90
+B512C06C14FC15FF6C15C016E04815F0391F80003F48C7EA07F8007E140116FC481400A5
+007EEC01F8A26CEC03F06C6CEB07E0D80FE0EB1FC0D807FCEBFF800001B5EAFE00D8003F
+13F00107138027387EA52B>103 D<EA03F812FFA3120F1203B0EC07F8EC1FFEEC7FFF91
+38F03F809039F9C00FC0D9FB807F140001FE6D7EA25BA25BB3A4486C497EB500E1B512C0
+A32A3A7EB92F>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA3120712
+03B3AA487EB512E0A313387EB718>I<EB01E0EB03F0EB07F8EB0FFCA4EB07F8EB03F0EB
+01E090C7FCA9EB01FC13FFA313071301B3B3A2123C127E00FF13F8130314F0A2387E07E0
+387C0FC0383FFF00EA0FFEEA03F8164984B719>I<EA03F812FFA3120F1203B1913801FF
+FEA36E13E06FC7FC157E15785D4A5A4A5A4AC8FC141E5C147C14FCEBF9FEEBFBFF9038FF
+3F8013FE496C7E496C7E1407816E7E6E7EA26E7E157F81826F7E82486CEB3FF8B500E0B5
+1280A3293A7EB92D>I<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<27
+03F803F8EB03F800FFD91FFFEB1FFF4A6D487F913BF81FC0F81FC03D0FF9C00FE1C00FE0
+3D03FB8007F38007F00200140001FED903FE6D7EA2495CA2495CB3A4486C496C497EB500
+E0B500E0B512E0A343257EA448>I<3903F807F800FFEB1FFEEC7FFF9138F03F803A0FF9
+C00FC02603FB807F140001FE6D7EA25BA25BB3A4486C497EB500E1B512C0A32A257EA42F
+>I<EB01FE90380FFFC0013F13F09038FF03FC3901F8007E48487F4848EB1F804848EB0F
+C0A24848EB07E0003F15F0A248C7EA03F8A44815FCA96C15F8A26D1307003F15F0A26C6C
+EB0FE0000F15C06C6CEB1F806C6CEB3F006C6C137E3900FF03FC90383FFFF0010F13C0D9
+01FEC7FC26277EA52B>I<3803F03F00FFEB7F809038F1FFE014C7390FF38FF03803F70F
+13F69038FE07E09038FC03C0EC018091C7FCA25BB3A3487EB512F8A31C257EA421>114
+D<90387F81803803FFF3000F13FF381F807F383E001F003C130F481307A200F81303A37E
+6C90C7FC6C7EEA7FF8EBFFC06C13F06C13FC6C7F6C7F00011480EA003F010113C0EB003F
+0060EB0FE000E01307A26C1303A37E15C06C13076C14806CEB0F00EBC07E38F3FFFC00E0
+5B38C03FC01B277DA522>I<131CA5133CA3137CA213FC120112031207121FB6FCA3D801
+FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB03F01A347FB220>I<D8
+03F8EB07F000FFEB01FFA3000FEB001F00031407B3A5150FA2151F120115376C6CEB77FC
+903A7F01E7FFC090383FFFC76D1307D903FCEBF0002A267EA42F>I<B538C03FFFA33A0F
+FC000FF8D803F8EB03E016C07F00011580A26C6CEB0700A26D5B6D130EA26D6C5AA2ECC0
+3C011F1338A26D6C5AA2ECF0F001075BA214F901035B14FD6DB45AA36D90C7FCA2147EA3
+143CA228257EA32D>I<B53B8FFFF81FFF80A33D0FFC007FC007FE006C4890393F8001F8
+00035F715A151F6C6C6E485A153FA26C6C6E485A15776D15076D02F090C7FC15E302805C
+D93F81EBF80E15C102C1EBFC1ED91FC3141C1580D90FE36D5A14E7ED007ED907F7EB7F70
+02FE133FA201035D4A131FA201015D4A130FA201005D4A1307027091C8FC39257EA33E>
+I<011E131E013F133F496C487E496C487EA46D486C5A6D486CC7FC011E131E90CAFCA8D8
+03F8EB07F000FFEB01FFA3000FEB001F00031407B3A5150FA2151F120115376C6CEB77FC
+903A7F01E7FFC090383FFFC76D1307D903FCEBF0002A387EB62F>252
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Ff ecrm1000w0970 10 28
+/Ff 28 253 df<913907F801F891397FFE0FFE49B5EA3FFF903B07F80FFF1F8090270FE0
+07FC13C0903A1F800FF83F90383F001F4914F001FEED1F8092390FE00F004992C7FC1201
+ACB812E0A32801FC000FE0C7FCB3AB486C497E267FFFE1B512E0A3323B7FBA2F>27
+D<B812F0A30001903880003F6C90C71207EE03F8160116001778A21738A4173C171CA215
+07A21700A45DA25D157F91B5FCA3EC007F151F81A281A692C8FCAD4813C0B612E0A32E39
+7DB835>70 D<90381FE00390387FFC073801FFFE3903F01F8F3907C003DF48486CB4FC48
+C7FC001E80003E80127E007C80A200FC80A4817EA36C91C7FC6C7E7F13F0EA3FFE381FFF
+E014FE6C6D7E6C14E06C806C806C6C7F010F7F1300EC0FFF14016E1380157F153FED1FC0
+A2126000E0140FA57E1680A26C141F16007E6C143E6C143C6D137CD8FBE05B39F0FC03F0
+39E07FFFE0011F138026C003FEC7FC223D7BBA2D>83 D<003FB81280A39039E007FE0090
+260003FC131F007EEE0FC0007C160700781603A300701601A400F017E0481600A4C71600
+B3B0EC0FFF013FB612C0A333397DB83A>I<007FB590B512F0A3C601F890383FFE00D97F
+E0EB0FF0013FEC07C05F6D6C91C7FC010F5C6E130E6D6C131E5E6D6C1338010114786E13
+706DEB80F0ED81E091387FC1C0EC3FC3EDE380DA1FF7C8FC15FF6E5A14075D6E7EA26E7E
+804A7F825CEDBFE0EC071F020F7F91380E0FF8141E91381C07FCEC380302787F91387001
+FF14F049486C7F4A137F0103814A6D7E130749C76C7E010E140F011E81496E7E137E01FF
+8100076DEB1FFFB500F090B512FEA337397EB83C>88 D<EB7FC03801FFF800077F380F80
+7E48487E486C6C7E6D6C7E81A26C486C7EEA0F001206C7FCA4EB01FF131FEBFFE73803FE
+07EA07F8EA0FE0EA1FC0123FEA7F80A2D8FF001470A4140FA2EA7F80141B3A3FC031F8E0
+391FE0E1FF260FFFC013C000034913803A00FE003E0024277DA528>97
+D<EA03F812FFA3120F1203B0EC1FE0EC7FF89038F9FFFE9038FBE07F9039FF801F809039
+FE000FC049EB07E016F049130316F8A2ED01FCA316FEAA16FCA2150316F8A2ED07F06D14
+E0150F6D14C001E7EB3F809039E3C0FF009038C1FFFC9038807FF0C7EA1FC0273B7EB92D
+>I<EB07FCEB1FFF017F13C09038FC03E03901F001F03903E003F800071307EA0FC0121F
+90388003F0003FEB01E0EC00C0007F140090C8FCA25AAA7E7FA2003F141C7F001F143812
+0F6D13706C7E3903F801E03901FE07C039007FFF8090383FFE00EB07F81E277DA524>I<
+ED3F80EC0FFFA31400153FB0EB07F0EB3FFEEB7FFF3901FE07BF3903F801FF3807E00000
+0F147F49133F121F485AA2127F90C7FCA25AAA7EA36C7EA2121F6D137F000F14FF6C6C5A
+6C6C4813E03A01FC0FBFFE3900FFFE3FEB3FFCD90FE01380273B7DB92D>I<EB07F0EB3F
+FE497E3901FC1FC03903F007E03907E003F013C0000FEB01F8EA1F80003F14FC1400A248
+C712FEA35A90B5FCA390C8FCA57EA27F123F150E121F6D131C120F6C6C13386C7ED801FC
+13F03900FF03E090387FFF80011F1300EB03F81F277EA524>I<147F903801FF80010713
+C090380FC7E090381F87F0EB3F0F137F137E9038FE07E09038FC03C0000190C7FCADB512
+FCA3D801FCC7FCB3AB487E387FFFFCA31C3B7FBA19>I<ED078090391FE03FE090387FF8
+7F9039FFFCF1F03903F03FC33907E01F813A0FC00FC0E0160048486C7EA2003F80A7001F
+5CA26C6C485AA26C6C485A6C6C48C7FC3806FFFC380E7FF8380C1FE090C9FC121C121EA3
+EA1F806CB5FC15F06C806C14FE81000F1580381F800048C7EA3FC0007E140F16E0481407
+A5007EEC0FC0A26CEC1F806C6CEB3F00D80FE013FE3907F803FC0001B512F06C6C13C0D9
+0FFEC7FC24387EA528>I<EA03F812FFA3120F1203B0EC0FE0EC3FF8EC7FFEECF07F9038
+F9C03FD9FB00138001FF131F4914C05BA35BB3A4486CEB3FE0B500E1B5FCA3283A7EB92D
+>I<EA03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB5
+12E0A313387EB718>I<EA03F812FFA3120F1203B191380FFFF0A302031300EC01FC15F0
+5D4A5A4A5A4AC7FC141E5C5C14F813F9EBFBFC13FF80EBFE7F497E01F87F6E7E140F8114
+07816E7E1401816E7EA281486C14C0B500E313FCA3263A7EB92A>107
+D<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<2703F807F0EB1FC000
+FFD91FFCEB7FF0913A7FFF01FFFC913AF07F83C1FE3C0FF9C01F87007E2603FB8001CE13
+7F9027FF000FDC7F4902F81480495CA3495CB3A4486C496CEB7FC0B500E1B53887FFFEA3
+3F257EA444>I<3903F80FE000FFEB3FF8EC7FFEECF07F390FF9C03F2603FB00138001FF
+131F4914C05BA35BB3A4486CEB3FE0B500E1B5FCA328257EA42D>I<EB03F8EB1FFF017F
+13C09038FE0FE03903F803F8EBE0004848137C000F147E48487FA2003F158090C7121F48
+15C0A34815E0AA6C15C0A36C6CEB3F80A2001F15006C6C137EA26C6C5B3903F803F83901
+FE0FF039007FFFC0011F90C7FCEB07FC23277EA528>I<3903F81FE000FFEB7FF89038F9
+FFFE9038FBE07F3A07FF803F803A03FE001FC049EB0FE016F049130716F8150316FCA215
+0116FEAAED03FCA316F8150716F06DEB0FE0A26DEB1FC06DEB3F809039FBC0FF009038F9
+FFFC9038F87FF0EC1FC091C8FCAB487EB512E0A327357EA42D>I<3803F07E00FF13FF01
+F113C0EBF38F390FF71FE0EA03F613FE9038FC0FC0EC0780EC030091C7FC5BB3A4487EB5
+12F8A31B257EA420>114 D<EBFF06000313CE000F13FEEA1F80383C003E007C131E1278
+A200F8130EA37E6C90C7FC7EEA7FF0EBFF806C13E06C7F6C7F6C7F00017F6C6C7E1303EB
+007F0060EB3F8000E0131FA26C130FA37E15006C5B141E6C133E38FF80FC38F3FFF800E1
+13E038C07F8019277DA520>I<131CA5133CA3137CA213FC120112031207121FB6FCA3D8
+01FCC7FCB2EC01C0A93900FE0380A2017E13006D5AEB1FFE6D5AEB03F01A347FB220>I<
+D803F8EB1FC000FFEB07FFA3000FEB007F0003141FB3A5153FA30001147F15FF3A00FC01
+DFF090397E039FFF90383FFF1FEB1FFED907F813C028267EA42D>I<B53880FFF8A33A0F
+FC003FC06C48EB1F8000031500150E6D131E0001141CA26C6C5BA3017F5BA36D6C5AA214
+C1011F5BA214E3010F5BA214F7010790C7FCA2EB03FEA36D5AA36D5AA3147025257EA32A
+>I<B53A1FFFE1FFF8A3260FF8019038003FE02707F000FCEB1F80EF0F006C6C6D130E15
+7EA26C6C01FF5BA36C6C6E5AEC01DFA2017F6E5AEC038FA2D93F836D5AEC8707A2D91FC7
+EBF1C0ECCE03A2D90FEEEBFB80ECFC01A216FF6D486C90C7FCA301035C4A137EA2010114
+7C4A133C0100143835257EA33A>I<B538C1FFF8A33A0FFC003FC06C48EB1F8000031500
+151E6C6C131CA36C6C5BA26D13786D1370A2EC80F0013F5BA290381FC1C0A390380FE380
+A214F7010790C7FCA214FF6D5AA26D5AA36D5AA31470A214F05CA2495AA3387C038012FE
+49C8FCA2130EEAFC1EEA787CEA3FF86C5AEA0FC025357EA32A>121
+D<013C133C017E137E01FF13FF4801811380A46C01001300017E137E013C133C90C9FCA8
+D803F8EB1FC000FFEB07FFA3000FEB007F0003141FB3A5153FA30001147F15FF3A00FC01
+DFF090397E039FFF90383FFF1FEB1FFED907F813C028387EB62D>252
+D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fg ecbx1200w1030 12 16
+/Fg 16 121 df<DA7FF013030107B55B011FECE00F017FECF81F90B66C5A00039039C00F
+FE7F4848C7B5FCD80FF8143F49140F001F8148488082484880A28312FF83A27F837FA213
+FC6D92C7FC387FFFC014FCECFFE06C14FEEDFFE06C15FC6C15FF6C8217E00001826C826D
+816D81130F010181D9001F15801401DA000F14C01500161F040713E08282127800F881A2
+177FA27EA218C07EA26CEEFF80A26D160001E05C6D4A5A01FC4A5AD9FF80495A4801FCEB
+7FF0D8FC3FB65AD8F80F5DD8F00392C7FC48C66C13FC48010713C033467AC440>83
+D<B76C023FB512C0A5D8003F0180C9001FC7FC626D6D163E1A7E6D187C6F16FC6D608119
+016D6D5E19036D6D5E19076D606F150F027F5F81191F6E6D92C8FC616E6D143E197E6E6D
+147C19FC6E5E8218016E6D5C18036E6D5C18076E6D5C180F037F5D70131FA26F018090C9
+FC606FEBC03E187E6FEBE07C18FC6F5C17F16F5C17F917FB6FEBFFE0A26F5CA2705BA270
+90CAFCA3705AA2705AA2705AA2705AA252457EC357>86 D<903801FFF8011FEBFF80017F
+14E048B612F83A03FE003FFED807F8EB0FFF486C01037F6D6D7F486C818183A2707E6C5A
+6C5A6C5A6C5AC9FCA34AB5FC147F0107B6FC013FEBFC7F90B512004813F0000713C04890
+C7FC485A485A485AA2485AA416FFA26C6C5BA26C6C903807BFFE6C6C90390F3FFFF03A0F
+FFC07E1F6CEBFFFC0001ECF0076C6CEBC001D907FEC9FC342F7DAD38>97
+D<EB3FE0B5FCA512037EB1ED07FF037F13E002E1B512FC02E780913AFFF00FFF80DB8001
+7F4AC77F02F86E7E4A6E7E5C717EA284A2717EA41980AA1900A44D5AA260A26E4A5A4D5A
+6E5D02FE4A5A91263F80035B9027FE0FE01F90C7FC496CB55AD9F80114F8496C6C13C0C8
+D80FFEC8FC39467EC440>I<EC1FFC49B512C0010714F0011F14FC90397FF803FE9039FF
+E000FF48D98001138048495A484A13C0485AA2485AA2003F6E13806F130048486D5A167C
+93C7FCA212FFAA127FA27FA2123FEE03E06C7EEE07C06C7E6CED0F806C7F6C6DEB1F006C
+01F0137E90397FFE01FC011FB55A6D14E0010114809026001FF8C7FC2B2F7CAD33>I<EC
+1FFC49B512C0010714F0011F14FC90397FF80FFE9039FFE003FF48D9800113804890C713
+C048ED7FE04848143F4915F0121F161F003F16F85B127F17FC160F12FFA290B7FCA401F8
+C9FCA4127FA46C7EA2001F167C7F120F6C6C15F86E13016CED03F06C01E0EB07E06C6DEB
+1FC0D93FFEEBFF80010FB5EAFE0001035C010014E0020F90C7FC2E2F7DAD35>101
+D<DAFFF8133F01079039FF01FFC0013F02E313E04991B512F02701FFE03F13C148903900
+07FE1F4848EB03FF000FEE8FE0497F001FEEC380EFC000003F82A7001F5EA2000F5E6D5B
+000793C7FC6C6C495A6C9038E03FFC91B512F0485D018791C8FCD8078013F891CAFC120F
+A27FA27F7F90B612E016FF6C16C017F06C16FC6C82837E00031780000F17C0D81FF0C712
+1F484814034848020013E049157F00FF163FA56C6CED7FC0A26C6CEDFF806C6C4A13006C
+6C4A5A6CB4EC1FFC6C01E0EBFFF8C690B612E0013F1580010702FCC7FCD9007F13C03442
+7DAC3A>103 D<EB3FE0B5FCA512037EB1923801FFC0030F13F8033F13FE4B7F9126E1FC
+0F7F9126E3E0037F9138E78001DAEF008014FE4A7F4A81A25CA35CB3A7B6D8C07FEBFFE0
+A53B457DC440>I<137C48B4FC487F487FA2487FA56C5BA26C5B6C90C7FCEA007C90C8FC
+AAEB3FE0EA7FFFA512037EB3AFB61280A519467DC51F>I<903A7FC001FFC0B5010F13F8
+033F13FE4B7F9126C1FC0F7F9126C3E0037F00039038C780016CD9CF008014DE02DC7F02
+F881A25CA35CB3A7B6D8C07FEBFFE0A53B2D7DAC40>110 D<EC0FFE91B512E0010714FC
+011F14FF90263FFC077F9026FFE00013E0480180EB3FF04890C76C7E48486E7E000F8249
+1407001F82A2003F17804980007F17C0A400FF17E0AA007F17C0A46C6C4A1380A2001F17
+00A26C6C4A5A6C6C4A5A6C5E6C01C0EB7FF06C6D495A90267FFC075B011FB6C7FC010714
+FC010114F0D9001F90C8FC332F7DAD3A>I<90397FC03F80B5EBFFE002C113F802C313FC
+9138C7C7FEECCF0700039038CE0FFF6C13DE14FC14F8ED07FEA29138F003FCED00F01600
+A25CB3A6B612E0A5282D7EAC2E>114 D<D90FFF13E0017F13E30003B6FC5A380FF80139
+1FC0003F4848131F150F48C71207A2481403A27FA201E090C7FC13F8EBFFC06C13FEECFF
+C06C14F8816C806C80000315806C15C06C6C14E0011F14F0130014079138007FF8007814
+3F00F8140FA26C1407A36C15F07EA26DEB0FE06DEB1FC001F0133F01FCEBFF8048B61200
+D8F87F13FCD8F01F13F0D8E0031380252F7CAD2E>I<EB03E0A61307A3130FA3131FA213
+3F137F13FF5A5A001F90B51280B7FCA4000101E0C7FCB3A3ED03E0AA6CEC07C014F0017F
+1480ECF80F90393FFC1F0090381FFFFE6D5B010313F09038007FC023407EBE2C>I<B600
+0FB539E00FFFFCA500019027E0001FFCC7EA3E00A26E177E6C6F6C147C6E17FC017F6F5C
+A26E491401013F04805B6E491403011F04C05B804C14076D027C01E05BDB80FC140F6D91
+26F87FF05B03C1151FA26D9126F03FF890C7FC03E35D6D9139E01FFC3E03F7157E6D9139
+C00FFE7CA203FF15FC6E496C6C5AA26E496C5BA36E486D5BA26E486D5BA36E486E5AA26E
+486EC8FCA24E2C7EAB53>119 D<B690383FFFFCA5C601F8903803F8006D6C495A6D6C5C
+6D6C495A6D6D485A163F6D6D48C7FC6DEBE0FE6DEBF1FC6DEBFBF8EDFFF06E5B6E5B6E5B
+806E7FA26E7F82824A7F4A7F5C91383F9FFFDA7F0F7FDAFE077F49486C7F14F849486C7F
+49486C7F010F6E7E49486D7E49488049C77EB500F090B6FCA5382C7EAB3D>I
+E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fh ectt1200 12 11
+/Fh 11 122 df<1238127C12FEA27E7E7F123FA27F121F7F120F7F12077F1203A27F1201
+7F12007F7F80133FA280131F80130F801307801303A28013018013008080A281143F8114
+1F81140F811407A28114038114018114008181A21680153F16C0151F16E0150F16F01507
+A216F8150316FC1501A2ED00F81670264D7AC433>92 D<ECFFF0010713FE497F013F1480
+4914C090B612E04815F048EBC01F3807FE00EA0FF849EB0FE04848EB07C04848EB038092
+C7FC5B127F90C9FCA25A5AA87EA27E7FA26C6CEB01F06DEB03F8121F01F813076C6C14F0
+6CB4130F6C9038E03FE06C90B512C07E6D14806DEBFE006D5B010713F0010013C0252E79
+AC33>99 D<147F903803FFF0011F13FC497F90B6FC4815804815C0028013E03907FE003F
+D80FF8EB0FF04848EB07F85B4848EB03FC5B007F1401A290C713FE15005A90B6FCA516FC
+A248C9FC7E7EA27F123F6D147C6C7E6D14FE6C7E01FE13016C6CEB07FC6C9038E01FF86C
+90B5FC6C15F06D14E06D14C0010F1400010313FC9038003FC0272E7BAC33>101
+D<D901FEEB3FC0903A0FFFC1FFF04901E713F84990B512FC5B90B7FC5A480103EBE1F826
+07FC00EB80F049017F130048486D7E49131F001F8149130FA76D131F000F5D6D133F6C6C
+495A6D13FF2603FF0390C7FCECFFFE485C5D485C01DF5B01CF5BD9C1FEC8FC01C0C9FCA3
+7FEA07F290B512FC6CECFFC016F04815FC48814881273FE00007138001809038007FC048
+C8EA1FE0007E150F160700FE16F0481503A56C1507007E16E0D87F80141FD83FE0EC7FC0
+D81FF8903801FF809038FF801F6C90B612006C5D000115F86C5D013F14C0010F91C7FC01
+0013F02E447DAB33>103 D<EA3FFC127F487EA3127F123F1200AA4AB4FC020F13C04A7F
+027F7F91B57E90B67E82ECFE07ECF0014A6C7E5C4A7FA291C7FCA35BB3A33B3FFFF80FFF
+FC486D4813FEB56C4813FFA36C496C13FE6C496C13FC303D7FBC33>I<02FC137E3A7FC3
+FE01FF27FFCFFF077F90B5008F7F03DF7F92B57EA26C010F13873B07FC07FE03F801F813
+FC02031301A201F013F8A301E013F0B3A43C7FFE0FFF07FF80B5028713C04A138FA36E13
+87D87FFE02071380322C80AB33>109 D<4AB4FC263FFC0F13C0007F497F26FFFE7F7F91
+B57E90B67E6C816CEBFE07C6EBF0014A6C7E5C4A7FA291C7FCA35BB3A33B3FFFF80FFFFC
+486D4813FEB56C4813FFA36C496C13FE6C496C13FC302C7FAB33>I<ED03FE3B7FFF801F
+FF80B5017F13C002C1B512E002C314F014C714CF6C9038DFFE0F3B001FFFF007E09238C0
+03C092C8FC5C5C5CA25CA25CA45CB0007FB512FEB6FC81A35D7E2C2C7DAB33>114
+D<90381FFE0790B5EA8F80000314FF5A5A5A5A387FF007EBC00048C7127FA248143FA400
+7FEC1F0001C090C7FCEA3FF8381FFFC06C13FE6CEBFFC06C14F0C614FC011F7F01017FD9
+00071380020013C0ED3FE0003C140F007E15F000FE1407A27EA27F150F6DEB1FE001F013
+3F9039FC01FFC090B6FC1680160000FD5CD8FC7F13F8486C13E0D8700790C7FC242E79AC
+33>I<EB03C01307497EAA003FB612FC5AB77EA36C5DA226000FE0C8FCB3161FA2EE3F80
+A46E137F170001075C6E485AECFE076DB55A5E6D5C6D5C6E1380021F90C7FCEC07F82938
+7EB633>I<3B7FFF801FFFE0B56C4813F06E4813F8A34A6C13F06C496C13E03B01F80001
+FC006D5CA2000014036D5C137E1507017F5C7FA26E485A131FA26D6C485AA214E0010749
+C7FCA214F01303157EEB01F8A25D130014FC5D147C147DEC3FF0A36E5AA36E5AA2141F5D
+A2143F92C8FCA3147EA2001F13FE486C5AEA7FC1EBC3F81307EB1FF013FF6C5B5C6C5B91
+C9FCEA0FFCEA03F02D427DAA33>121 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fi ecrm1000 10 38
+/Fi 38 253 df<BD12C0A35203809753>22 D<DA07FC13FC91393FFF07FF49B5009F1380
+903B03FC07FF8FC0903B0FE003FE0FE0903A1FC007FC1F90383F800FD97F0013F8017EED
+0FC001FE903907F007804992C7FC1201ACB812F8A32801FC0007F0C7FCB3AB486C497E26
+7FFFE0B512F0A3333B7FBA30>27 D<121E123FEA7F80EAFFC0A213E0A2127F123F121E12
+00A4EA01C0A3EA0380A2EA0700A2120E5A123C123812100B1A7AB917>39
+D<121E123FEA7F80EAFFC0A213E0A2127F123F121E1200A4EA01C0A3EA0380A2EA0700A2
+120E5A123C123812100B1A7A8917>44 D<B512FCA616067F941C>I<121E123FEA7F80EA
+FFC0A4EA7F80EA3F00121E0A0A7A8917>I<1538157CA315FEA34A7EA34A7FA34A7F153F
+A2020F7FEC0E1FA2021E7FEC1C0FA2023C7FEC3807A202787FEC7003A202F07FECE001A2
+0101804A7EA20103814A137FA201078191C7123F91B6FC4981A2010EC7121F011E81011C
+140FA2013C8101381407A201788101701403A201F08116011201486C81D80FFE02071380
+B500C090B512FEA3373C7DBB3E>65 D<B812FEA30001903880000F6C90C71201EE007F83
+8383A383A31880170316E0A394C7FCA31501A21503150F91B5FCA3EC000F15031501A215
+00A218E0A31701040013C0A41703A3EF0780A2170FA2171F173F17FF486D010F1300B9FC
+A333397EB838>69 D<B812F8A30001903880001F6C90C71203EE01FC1600177C173CA217
+1CA4171E170EA2ED0380A21700A41507A2150F153F91B5FCA3EC003F150F1507A21503A6
+92C8FCAD4813C0B612C0A32F397DB836>I<B612C0A3C6EBC0006D5AB3B3AD497EB612C0
+A31A397EB81E>73 D<D90FF813C090383FFE0190B512813901F80FE33907E001F7390F80
+007F90C7123F48141F003E140FA2481407A200FC1403A415017EA27E6C91C7FC7F13E0EA
+3FF8EBFF806C13F86CEBFF806C14E06C14F86C806C80013F7F01071480D9007F13C00207
+13E0EC007FED1FF0150F150716F81503126012E01501A47E16F0A26C14036C15E0A26CEC
+07C06CEC0F80D8FBC0EB1F00D8F9F0133ED8F0FF13FC39E03FFFF8010F13E0D8C00190C7
+FC253D7CBA2E>83 D<003FB812E0A3D9E003EB003F90260001FE1307007EEE03F0007C16
+0100781600A300701770A400F01778481738A4C71600B3B0913807FF80011FB612E0A335
+397DB83C>I<007FB590387FFFFCA3C601F8010F1380D97FE0D903FCC7FC013FEC01F06D
+6C5C5F6D6C13036D6C495A94C8FC6D6C5B161E6D6C131C6DEB803C5E91387FC07091383F
+E0F0EDE1E091381FF1C0EC0FF3EDFB806EB4C9FCA26E5A6E7EA26E7F6F7E15FF825C9138
+03DFF0ED8FF8140791380F07FC91380E03FE141E91381C01FF4A7E02788002706D7E14F0
+49486D7E4A6D7E130349486D7E91C76C7E5B011E6E7E1601013E8101FF8200076D01077F
+B500F0013FEBFF80A339397EB83E>88 D<EB3FE0EBFFFC000313FF3907C03F80390F800F
+C0486C6C7E01E07F6E7EA2380FC001D807807FEA0300C7FCA414FF130FEB7FF13801FF01
+EA07FCEA0FF0EA1FE0EA3FC0EA7F80A2D8FF00141CA41403A2387F800714063A3FC01C7E
+383A1FF0787FF83A0FFFF03FF0000301E013E03A007F000F8026277DA52A>97
+D<EA03F812FFA3120F1203B0EC0FE0EC7FFC9038F9FFFE9039FBE03F809039FF800FC090
+39FE0007E049EB03F0A249EB01F816FCA216FE1500A216FFA916FEA3150116FCA2ED03F8
+6D14F0ED07E06DEB0FC09039E7801F809039E3E07F009038C1FFFE9038807FF8C7EA1FC0
+283B7EB92E>I<EB03FC90381FFF80017F13E09038FE01F03901F800F83903F001FC3807
+E003EA0FC0121F90388001F8003FEB00F01560007F140090C8FCA25AA97EA27FA2003F14
+0E7F001F141C6C7E000714386C7ED801FC13F03900FF03E090387FFFC0011F1300EB07F8
+1F277DA525>I<ED1FC0EC07FFA3EC007F151FB0EB07F8EB1FFE90387FFF9F9038FE07DF
+3901F800FF4848137F4848133F4848131F121F485AA2127F90C7FCA35AA97EA27F123FA2
+121F6C6C133F157F6C6C13FF3A03F001DFF03A01FC079FFF39007FFF1FEB3FFED907F013
+C0283B7DB92E>I<EB07F8EB1FFF017F13809038FC0FC03901F003E03903E001F0000714
+F8390FC000FC121F4913FE003F147EA248C7127FA35A90B6FCA390C8FCA57EA27F123F15
+076C7E150E6C7E0007141C6C6C133CD801FC13783900FF01F090383FFFC06D1380903803
+FC0020277EA525>I<147E903803FF80010F13C090381FC7E090383F07F0EB7E0F13FE13
+FC0001EB07E09038F803C0000390C7FCADB512FCA3D803F8C7FCB3AB487EB512F8A31C3B
+7FBA19>I<ED03E090390FF00FF090393FFC1FF890B5EA3C7C3A01F81FF0FC3A03E007C0
+7C3A07C003E038000FECF000001F80EB8001003F80A7001F5CEBC003000F5C00075C6C6C
+485A9038F81F800006B5C7FCEB3FFC380E0FF090C9FC121EA3121F6C7E90B512C015F86C
+14FE6CECFF8016C04815E0391F80007F48C7EA0FF0007E140316F8481401A5007EEC03F0
+A26CEC07E06C6CEB0FC0D80FE0EB3F803A07FC01FF000001B512FC6C6C13F0010790C7FC
+26387EA52A>I<EA03F812FFA3120F1203B0EC07F0EC1FFCEC7FFF9138F07F809038F9C0
+1FD9FB807F9038FF000F49805BA35BB3A4486C497EB500E1B51280A3293A7EB92E>I<EA
+03C0487E487E487EA46C5A6C5A6C5AC8FCA9EA01F812FFA312071203B3AA487EB512E0A3
+13387EB718>I<EB01E0EB03F0EB07F8EB0FFCA4EB07F8EB03F0EB01E090C7FCA9EB01FC
+13FFA313071301B3B3A2123C127E00FF13F8130314F0A2387E07E0387C0FC0383FFF00EA
+0FFEEA03F8164984B719>I<EA03F812FFA3120F1203B1913803FFFCA36E13C0913800FE
+005D15F04A5A4A5A4A5A4AC7FC141E5C5C14FCEBF9FE13FBEBFF7F496C7EEBFC1F01F87F
+6E7E6E7EA26E7E6E7EA26E7E157FA2ED3F8016C0486CEB7FF0B500E1B5FCA3283A7EB92C
+>I<EA03F812FFA3120F1203B3B3AD487EB512E0A3133A7EB918>I<2703F807F8EB0FF000
+FFD91FFEEB3FFCDA7FFFEBFFFE913AF03F81E07F3D0FF9C00FC3801F802603FB80D9E700
+7F020013E601FED907FC6D7EA2495CA2495CB3A4486C496C497EB500E1B500C3B51280A3
+41257EA446>I<3903F807F000FFEB1FFCEC7FFF9138F07F80390FF9C01F2603FB807F90
+38FF000F49805BA35BB3A4486C497EB500E1B51280A329257EA42E>I<EB03FE90380FFF
+80013F13E09038FE03F83901F800FC4848137E48487F4848EB1F80001F15C049130F003F
+15E0A248C7EA07F0A44815F8A96C15F0A26D130F003F15E0A26C6CEB1FC0000F15806D13
+3F6C6CEB7F006C6C13FE3900FE03F890387FFFF0011F13C0D903FEC7FC25277EA52A>I<
+3903F80FE000FFEB7FFC9038F9FFFE9039FBE07F803A07FF801FC03A03FE000FE049EB07
+F0A249EB03F816FC150116FEA3ED00FFA916FE1501A316FC150316F86DEB07F0ED0FE06D
+14C09039FF803F809039FBE07F009038F9FFFE9038F87FF8EC1FC091C8FCAB487EB512E0
+A328357EA42E>I<3803F03F00FFEB7F809038F1FFE014C7390FF38FF03803F70F13F690
+38FE07E09038FC03C0EC018091C7FCA25BB3A3487EB512F8A31C257EA421>114
+D<EBFF83000313E7000F13FFEA1F80383E003F487F00787FA200F87FA37E6C90C7FC6C7E
+EA7FF8EBFF806C13E06C13F86C7F6C7F00017F6C7E01031380EB003F0060EB1FC000E013
+0FA26C1307A37E15806C130F1500B4131EEBC07C38F3FFF800E15B38C07F801A277DA521
+>I<131CA5133CA3137CA213FC120112031207121FB6FCA3D801FCC7FCB2EC01C0A93900
+FE0380A2017E13006D5AEB1FFE6D5AEB03F01A347FB220>I<D803F8EB0FE000FFEB03FF
+A3000FEB003F0003140FB3A5151FA2153F1201156F6C6CEBEFF8903A7E03CFFF8090383F
+FF8F6D130FD903FCEBE00029267EA42E>I<B538C07FFEA33A0FFC001FF0D803F8EB07C0
+16807F00011500A26D5B0000140EA2017F5BA2EC803C013F1338A26D6C5AA214E0010F5B
+A214F101075BA2903803FB80A214FF6D90C7FCA36D5AA2147CA3143827257EA32C>I<B5
+3A8FFFF07FFEA3260FF8009038800FF8000791397F0007E0EF03C000031780816DEC8007
+0001027F1400A26D6E5A000002FF130E15EF6DECE01ED97F01141C15C70281EBF03CD93F
+8314381583D91FC36D5AECC701A2D90FE76D5AECEE00A2D907FEEBFFC04A137FA201035D
+4A133FA2010192C7FC4A7FA20100141E4A130E37257EA33C>I<B500C0B5FCA300039038
+007FF06C48EB3F806C6C013EC7FC6D133CEB3F806E5A011F5B6D6C5A14F1903807FBC06D
+B45A6D90C8FCA26D5A147F818114FF497FECCFF0EB03C790380783F890380F03FCEB0E01
+90381E00FE497F496D7E01F8133F000181D80FFC497EB548B51280A329247FA32C>I<B5
+38C07FFEA33A07FC001FF06C48EB07C016807F00011500A26C6C130EA26D131E6D131CA2
+6D6C5AA2ECC078011F1370A2ECE0F0010F5B14F0903807F1C0A214FB01035BA26DB4C7FC
+A36D5AA2147CA31438A214781470A25CA21301007C5BEAFE035C130749C8FCEAFC1EEA78
+3CEA3FF86C5AEA0FC027357EA32C>I<011E133C017F137F6E5A01FF8014C1A21480017F
+91C7FC4A7E011E133C90CAFCA8D803F8EB0FE000FFEB03FFA3000FEB003F0003140FB3A5
+151FA2153F1201156F6C6CEBEFF8903A7E03CFFF8090383FFF8F6D130FD903FCEBE00029
+387EB62E>252 D E
+%EndDVIPSBitmapFont
+%DVIPSBitmapFont: Fj ecbx1200 12 17
+/Fj 17 120 df<923807FFC092B512FE0207ECFFC0021F15F091267FFE0013FC902601FF
+F0EB1FFF010701C0010713C04990C700017F49486E7F49486F7E49486F7E49486F7E4884
+48496F13804A814819C04A814819E0A24890C96C13F0A24819F8A348487013FCA500FF19
+FEAD007F19FCA26D5EA26C19F8A36C6D4B13F0A36C6D4B13E0A26C6D4B13C06C19806E5D
+6C19006C6D4B5A6D6C4B5A6D6C4B5A6D6C6C01035B6D6D495B6D01F0011F5B010101FE90
+B5C7FC6D90B65A023F15F8020715C002004AC8FC030713C047467AC454>79
+D<003FBA12E0A59026FE000FEBC003D87FF09338007FF049173F0180170F190790C7FC00
+7E1803A3007C1801A400FC19F8481800A5C81700B3B3A20107B87EA545437CC24E>84
+D<903801FFF0011F13FF017F14C048B612F04848C66C7ED807F8EB1FFC486C6D7E6D6D7E
+486C81818381836C5A6C5A6C5A6C5AC8FCA30203B5FC91B6FC1307013F13F19038FFFE01
+000313F0481380481300485A485A485AA2485AA45DA26C6C5BA26C6C010E13F86C6C013C
+EBFFC03A0FFF80F87F6CEBFFF06CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97
+D<4CB4FC0307B5FCA5ED001F82B1EC3FF0903803FFFE010FEBFF8F013F14EF90267FF807
+B5FC3901FFC00148496C7E4890C77E49140F120F485AA2123FA2485AA412FFAA127FA412
+3F7F121FA2000F5D7F6C6C147F6C92B512806CD9C00314FE6C9038F01FEF013FB512CF6D
+140F010713FC9026007FC0EBF80037467CC43E>100 D<EC3FF849B5FC010F14C0013F14
+F090397FF01FF89039FFC007FC48496C7E48496C7E48481580000F80484815C0167F003F
+16E0A25B127FEE3FF0A212FFA290B7FCA401F8C9FCA5127FA36C7EA2001FED01F0A26C7E
+EE03E06C6C14076C6DEB0FC06C6DEB1F806C01F0EB3F0090397FFE01FE011FB55A010714
+F0010014C0DA1FFCC7FC2C2F7DAD33>I<913801FF80021F13E0027F13F849B512FC0107
+138790390FFE0FFED91FFC13FF49485A137F14F013FF14E048EC0FFEED07FCED03F8ED00
+E01600AAB612F8A5000101E0C7FCB3B0B612E0A528467DC522>I<DAFFE013FC010F9038
+FE03FF013FD9FF8F138090B812C048D9C07F1307489039001FF87F4848EB0FFC000F9238
+FE3F80491307001F9238FF0E0094C7FC003F82A7001F93C7FCA2000F5D6D130F00075D6C
+6C495A6C9038C07FF091B55A481580D8078F49C8FC018013E0000F90CAFCA47FA213F090
+B612C016FC6CEDFF80836C16F0836C826C821203000F82D81FF0C77ED83FC01407007F6F
+1380498000FF81A56C6C4A1300A26C6C4A5A6D14076C6C4A5AD80FFEEC3FF83B03FFE003
+FFE06C90B65A6C6C92C7FC010F14F8D9007F90C8FC32427DAC38>I<EB3FE0B5FCA51203
+7EB1ED03FF031F13E04B13F892B57E9139E1F81FFE9139E3C00FFF9138E78007DAEE0080
+02FE7F4A815CA25CA35CB3A7B600C1B61280A539457DC43E>I<137C48B4FC487F487FA2
+487FA56C5BA26C5B6C90C7FCEA007C90C8FCAAEB3FE0EA7FFFA512037EB3AFB61280A519
+467DC51F>I<EB3FE0B5FCA512037EB3B3B3A3B612C0A51A457DC41F>108
+D<90397FC003FFB5011F13E04B13F892B57E9139C1F81FFE9139C3C00FFF00039038C780
+076CD9CE008002DE7F02DC8114F8A25CA35CB3A7B600C1B61280A5392D7DAC3E>110
+D<EC1FFC49B512C0010714F0011F14FC90397FF80FFF9026FFC0017F48496C7F4890C76C
+7E48486E7E000F8249141F001F82A248486E7EA2007F82A400FF1780AA007F1700A46C6C
+4A5AA2001F5EA26C6C4A5A00075E6D147F6C6D495A6CD9E0035B27007FF80F90C7FC6DB5
+5A010F14F8010114C09026001FFCC8FC312F7DAD38>I<90397FC03F80B5EBFFE002C113
+F802C313FC9138C7C7FEECCF0700039038CE0FFF6C13DE14FC14F8ED07FEA29138F003FC
+ED00F01600A25CB3A6B612F0A5282D7EAC2E>114 D<90391FFC038090B5128F000314FF
+5A380FF003381FC0004848133F48C7FC151FA248140FA27FA26D90C7FC13F0EBFF806C13
+FCECFF806C14E015F86C806C806C8012016C1580011F14C01301D9000F13E014010078EB
+007F00F8143FA26C141FA36C15C0A27E6DEB3F807F6DEBFF009038FC03FE90B55A00F814
+F0D8F03F5B26E007FEC7FC232F7CAD2C>I<EB03E0A61307A3130FA3131FA2133F137F13
+FF5A5A001F90B51280B7FCA4000101E0C7FCB3A3ED03E0AA6CEC07C014F0017F1480ECF8
+0F90393FFC1F0090381FFFFE6D5B010313F09038007FC023407EBE2C>I<D93FE0EC7FC0
+B549B5FCA50003EC00076C81B3A85EA35E7E5E043B7F6D6C017BEBFF8090393FFC03F36D
+B512E36D1483010314039026003FF849C7FC392E7DAC3E>I<B6000FB539C03FFFF0A500
+019027E0007FF0C7EAF800707E6E16016C6F6C5C80017F4D5A836E013F1407013F6F5C80
+4C140F011F04805B6E90B5131F6D02F901C090C7FC158003815D6D02F0EBE03E03C3157E
+6D9139E07FF07C15E303E715FC6D4A6C6C5A03FF14F96D9139801FFDF0A218FF6E496C5B
+A26E486D5BA36E486D5BA26E486D90C8FCA36E486D5AA26E48147C4C2C7EAB51>119
+D E
+%EndDVIPSBitmapFont
+end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 0 523 a Fj(Original)0 691 y Fi(This)61 b(is)g(a)h(test)g
+(paragraph)e(for)i(T)1282 709 y(E)1328 691 y(X's)g(paragraph-)0
+791 y(breaking)56 b(algorithm.)126 b(It)59 b(is)e(a)h(fairly)e(complex)
+g(al-)0 890 y(gorithm,)74 b(nev)n(ertheless)64 b(impro)n(v)n(emen)n(ts)
+e(seem)j(p)r(ossi-)0 990 y(ble.)81 b(As)43 b(y)n(ou)e(will)f(note,)46
+b(I)d(stu\033ed)g(this)f(paragraph\026)0 1089 y(longnon)n(breakingw)n
+(ord\026wi)o(th)22 b(long)j(non)n(breaking)g(w)n(ords)0
+1189 y(just)43 b(to)f(mak)n(e)e(the)j(algorithm)38 b(w)n(ork)j(harder)g
+(and)h(to\026)0 1289 y(longnon)n(breakingw)n(ord\026sho)m(w)12
+b(some)17 b(impro)n(v)n(emen)n(ts)d(that)0 1388 y(can)19
+b(b)r(e)g(had)g(b)n(y)f(allo)n(wing)d(fon)n(t\026longnon)n(breakingw)n
+(or)o(d\026)0 1488 y(width)27 b(v)-5 b(ariations.)0 1762
+y Fj(Original)38 b(with)g Fh(\\emergencystretch)0 1930
+y Fi(This)61 b(is)g(a)h(test)g(paragraph)e(for)i(T)1282
+1948 y(E)1328 1930 y(X's)g(paragraph-)0 2030 y(breaking)56
+b(algorithm.)126 b(It)59 b(is)e(a)h(fairly)e(complex)g(al-)0
+2129 y(gorithm,)74 b(nev)n(ertheless)64 b(impro)n(v)n(emen)n(ts)e(seem)
+j(p)r(ossi-)0 2229 y(ble.)81 b(As)43 b(y)n(ou)e(will)f(note,)46
+b(I)d(stu\033ed)g(this)f(paragraph\026)0 2329 y(longnon)n(breakingw)n
+(ord\026wi)o(th)141 b(long)j(non)n(breaking)0 2428 y(w)n(ords)58
+b(just)j(to)e(mak)n(e)f(the)i(algorithm)55 b(w)n(ork)k(harder)0
+2528 y(and)93 b(to\026longnon)n(breakingw)n(ord\026sho)m(w)88
+b(some)j(im-)0 2628 y(pro)n(v)n(emen)n(ts)52 b(that)k(can)f(b)r(e)h
+(had)f(b)n(y)g(allo)n(wing)50 b(fon)n(t\026)0 2727 y(longnon)n
+(breakingw)n(ord\026wi)o(dth)22 b(v)-5 b(ariations.)0
+3001 y Fg(V)c(arian)m(ts)0 3169 y Ff(Th)p Fe(i)p Ff(s)23
+b Fe(i)p Ff(s)g(a)h Fe(t)p Ff(es)p Fe(t)g Ff(paragraph)g(for)g(T)1029
+3187 y Fi(E)1076 3169 y Ff(X)p Fe(')p Ff(s)g(paragraph)p
+Fe(-)p Ff(break)p Fe(i)p Ff(ng)0 3269 y Fd(a)p Fe(l)p
+Fd(go)p Ff(r)p Fe(it)p Ff(h)p Fd(m)p Fe(.)34 b(It)28
+b(i)p Ff(s)e(a)i(fa)p Fe(i)p Ff(r)p Fe(l)p Ff(y)e(c)p
+Fc(o)p Fd(m)p Fc(p)p Fe(l)p Ff(e)p Fd(x)g Fc(a)p Fe(l)p
+Ff(g)p Fc(o)p Ff(r)p Fe(it)p Ff(h)p Fd(m)p Fe(,)g Ff(n)p
+Fc(e)p Fd(v)n(er)p Fe(t)p Ff(h)p Fc(e)p Fe(-)0 3369 y(l)p
+Fi(ess)g Fe(i)p Fi(mpro)n(v)n(emen)n Fe(t)p Fi(s)d(seem)j(p)r(oss)p
+Fe(i)p Fi(b)p Fe(l)p Fi(e)p Fe(.)35 b Fi(As)27 b(y)n(ou)g(w)p
+Fe(ill)e Fi(n)p Fc(o)p Fe(t)p Fb(e)p Fe(,)j(I)0 3468
+y Fi(s)p Fe(t)p Fi(u\033ed)g Fe(t)p Fi(h)p Fe(i)p Fb(s)f
+Fi(pa)p Fb(r)p Fi(ag)p Fa(r)p Fi(aph\026)p Fe(l)p Fb(o)p
+Fi(n)p Fb(g)p Fi(non)n(b)p Fa(r)p Fi(eak)p Fe(i)p Fb(n)p
+Fi(gw)n(o)o Fb(r)p Fi(d\026)p Fb(w)o Fe(i)o(t)p Fi(h)0
+3568 y Fe(long)g Fa(no)p Fe(n)n Fa(b)p Fe(rea)p Fa(k)p
+Fe(ing)g(w)n Fa(o)p Fe(rds)h(just)h(to)f(mak)n(e)e(the)j(algorithm)0
+3667 y(w)n(ork)40 b(harder)i(and)f(to)p Fi(\026)p Fe(longnon)n
+(breakingw)n(ord)p Fi(\026)p Fe(sho)n(w)0 3767 y Ff(some)19
+b Fe(i)p Ff(mpro)n(v)n(emen)n Fe(t)p Ff(s)d Fe(t)p Ff(ha)p
+Fe(t)21 b Ff(can)f(b)r(e)g(had)g(b)n(y)g(a)p Fe(ll)p
+Ff(o)n(w)p Fe(i)p Ff(ng)e(fon)n Fe(t)p Fi(\026)0 3867
+y Fe(longnon)n(breakingw)n(ord)p Fi(\026)p Fe(width)27
+b(v)-5 b(ariations.)0 4141 y Fg(V)c(arian)m(ts)37 b(with)h
+Fh(\\emergencystretch)0 4309 y Ff(Th)p Fe(i)p Ff(s)23
+b Fe(i)p Ff(s)g(a)h Fe(t)p Ff(es)p Fe(t)g Ff(paragraph)g(for)g(T)1029
+4327 y Fi(E)1076 4309 y Ff(X)p Fe(')p Ff(s)g(paragraph)p
+Fe(-)p Ff(break)p Fe(i)p Ff(ng)0 4408 y Fd(a)p Fe(l)p
+Fd(go)p Ff(r)p Fe(it)p Ff(h)p Fd(m)p Fe(.)34 b(It)28
+b(i)p Ff(s)e(a)i(fa)p Fe(i)p Ff(r)p Fe(l)p Ff(y)e(c)p
+Fc(o)p Fd(m)p Fc(p)p Fe(l)p Ff(e)p Fd(x)g Fc(a)p Fe(l)p
+Ff(g)p Fc(o)p Ff(r)p Fe(it)p Ff(h)p Fd(m)p Fe(,)g Ff(n)p
+Fc(e)p Fd(v)n(er)p Fe(t)p Ff(h)p Fc(e)p Fe(-)0 4508 y(l)p
+Fi(ess)g Fe(i)p Fi(mpro)n(v)n(emen)n Fe(t)p Fi(s)d(seem)j(p)r(oss)p
+Fe(i)p Fi(b)p Fe(l)p Fi(e)p Fe(.)35 b Fi(As)27 b(y)n(ou)g(w)p
+Fe(ill)e Fi(n)p Fc(o)p Fe(t)p Fb(e)p Fe(,)j(I)0 4608
+y Fi(s)p Fe(t)p Fi(u\033ed)g Fe(t)p Fi(h)p Fe(i)p Fb(s)f
+Fi(pa)p Fb(r)p Fi(ag)p Fa(r)p Fi(aph\026)p Fe(l)p Fb(o)p
+Fi(n)p Fb(g)p Fi(non)n(b)p Fa(r)p Fi(eak)p Fe(i)p Fb(n)p
+Fi(gw)n(o)o Fb(r)p Fi(d\026)p Fb(w)o Fe(i)o(t)p Fi(h)0
+4707 y Fe(long)g Fa(no)p Fe(n)n Fa(b)p Fe(rea)p Fa(k)p
+Fe(ing)g(w)n Fa(o)p Fe(rds)h(just)h(to)f(mak)n(e)e(the)j(algorithm)0
+4807 y(w)n(ork)40 b(harder)i(and)f(to)p Fi(\026)p Fe(longnon)n
+(breakingw)n(ord)p Fi(\026)p Fe(sho)n(w)0 4907 y Ff(some)19
+b Fe(i)p Ff(mpro)n(v)n(emen)n Fe(t)p Ff(s)d Fe(t)p Ff(ha)p
+Fe(t)21 b Ff(can)f(b)r(e)g(had)g(b)n(y)g(a)p Fe(ll)p
+Ff(o)n(w)p Fe(i)p Ff(ng)e(fon)n Fe(t)p Fi(\026)0 5006
+y Fe(longnon)n(breakingw)n(ord)p Fi(\026)p Fe(width)27
+b(v)-5 b(ariations.)1988 523 y Fg(Setting)37 b(b)s(o)m(xes)f(with)h
+(stretc)m(h)1988 676 y Ff(F)p Fe(l)p Ff(\374ss)p Fe(i)p
+Ff(gk)n(e)p Fe(it)p Ff(sg)p Fe(l)p Ff(e)p Fe(i)p Ff(c)n(hgew)p
+Fe(i)o Ff(c)n(h)m Fe(t)13 b Ff(und)k(S)p Fe(t)p Ff(o)p
+Fi(\033)p Ff(w)n(ec)n(hse)p Fe(l)1988 776 y Ff(F)p Fe(l)p
+Ff(\374ss)p Fe(i)p Ff(gk)n(e)p Fe(it)p Ff(sg)p Fe(l)p
+Ff(e)p Fe(i)p Ff(c)n(hgew)p Fe(i)o Ff(c)n(h)m Fe(t)c
+Ff(und)k(S)p Fe(t)p Ff(o)p Fi(\033)p Ff(w)n(ec)n(hse)p
+Fe(l)1988 876 y Fd(F)p Fe(l)p Ff(\374s)p Fd(s)p Fe(i)p
+Ff(gk)n Fd(e)p Fe(it)p Ff(sg)p Fe(l)p Ff(e)p Fe(i)p Ff(c)n(hgew)p
+Fe(i)p Ff(c)n Fd(h)n Fe(t)k Ff(und)27 b Fd(S)p Fe(t)p
+Ff(o)p Fi(\033)p Fd(w)n Ff(e)p Fd(c)n(hse)p Fe(l)1988
+975 y Fd(F)p Fe(l)p Fd(\374ss)p Fe(i)p Fd(gk)n(e)p Fe(it)p
+Ff(sg)p Fe(l)p Fd(e)p Fe(i)p Ff(c)n Fd(h)p Fc(g)p Fd(ew)p
+Fe(i)p Fd(c)n(h)n Fe(t)22 b Ff(u)p Fc(n)p Fd(d)27 b(S)p
+Fe(t)p Ff(o)p Fi(\033)p Fd(w)n(e)p Fc(c)n Fd(hs)p Fc(e)p
+Fe(l)1988 1075 y Fc(F)p Fe(l)p Fd(\374)p Fc(ss)p Fe(i)p
+Fd(g)p Fc(k)n(e)p Fe(it)p Ff(s)p Fc(g)p Fe(l)p Fd(e)p
+Fe(i)p Fd(c)n Fc(hgew)p Fe(i)p Fd(c)n Fc(h)n Fe(t)21
+b Fd(u)p Fc(nd)27 b(S)p Fe(t)p Ff(o)p Fi(\033)p Fc(w)n(ec)n(hse)p
+Fe(l)1988 1174 y Fc(F)p Fe(l)p Fi(\374)p Fc(ss)p Fe(i)p
+Fc(g)p Fi(k)n Fc(e)p Fe(it)p Fc(sg)p Fe(l)p Fc(e)p Fe(i)p
+Fi(c)n Fc(hg)p Fi(e)p Fc(w)p Fe(i)p Fi(c)n Fc(h)m Fe(t)22
+b Fc(u)p Fi(n)p Fc(d)27 b Fi(S)p Fe(t)p Fc(o)p Fi(\033w)n
+Fc(ec)n Fi(h)p Fc(se)p Fe(l)1988 1274 y Fi(Fl\374ssigk)n(eitsgleic)m
+(hgewi)o(c)m(h)n(t)22 b(und)28 b(Sto\033w)n(ec)n(hsel)1988
+1374 y Fb(F)p Fe(l)p Fi(\374)p Fb(ss)p Fe(i)p Fb(g)p
+Fi(k)n Fb(e)p Fe(it)p Fb(sg)p Fe(l)p Fb(e)p Fe(i)p Fi(c)n
+Fb(hg)p Fi(e)p Fb(w)p Fe(i)o Fi(c)n Fb(h)m Fe(t)22 b
+Fb(u)p Fi(n)p Fb(d)27 b Fi(S)p Fe(t)p Fb(o)p Fi(\033w)n
+Fb(ec)n Fi(h)p Fb(se)p Fe(l)1988 1473 y Fb(F)p Fe(l)p
+Fa(\374)p Fb(ss)p Fe(i)p Fa(g)p Fb(k)n(e)p Fe(its)p Fb(g)p
+Fe(l)p Fa(e)p Fe(i)p Fa(c)n Fb(hgew)p Fe(i)o Fa(c)n Fb(h)m
+Fe(t)22 b Fa(u)p Fb(nd)27 b(S)p Fe(to)p Fi(\033)p Fb(w)n(ec)n(hse)p
+Fe(l)1988 1573 y Fa(F)p Fe(l)p Fa(\374ss)p Fe(i)p Fa(gk)n(e)p
+Fe(itsgl)p Fa(e)p Fe(ic)n Fa(h)p Fb(g)p Fa(ew)p Fe(i)p
+Fa(c)m(h)n Fe(t)22 b(u)p Fb(n)p Fa(d)28 b(S)p Fe(to)p
+Fi(\033)p Fa(w)n(e)p Fb(c)n Fa(hs)p Fb(e)p Fe(l)1988
+1673 y Fa(F)p Fe(l\374s)p Fa(s)p Fe(igk)n Fa(e)p Fe(itsgleic)n(hgewic)n
+Fa(h)n Fe(t)22 b(und)29 b Fa(S)p Fe(to)p Fi(\033)p Fa(w)n
+Fe(e)p Fa(c)n(hse)p Fe(l)1988 1772 y(Fl\374ssigk)n(eitsgleic)n(hgewi)o
+(c)n(h)n(t)37 b(und)44 b(Sto)p Fi(\033)p Fe(w)n(ec)n(hsel)1988
+1872 y(Fl\374ssigk)n(eitsgleic)n(hgewi)o(c)n(h)n(t)54
+b(und)60 b(Sto)p Fi(\033)p Fe(w)n(ec)n(hsel)1988 1988
+y Fj(The)38 b(used)g(fon)m(ts)1988 2141 y Ff(Fl\374ssigk)n(eitsgleic)n
+(hgewi)o(c)n(h)m(t)22 b(und)27 b(Sto\033w)n(ec)n(hsel)1988
+2241 y Fd(Fl\374ssigk)n(eitsgleic)n(hgewic)n(h)n(t)22
+b(und)28 b(Sto\033w)n(ec)n(hsel)1988 2341 y Fc(Fl\374ssigk)n(eitsgleic)
+n(hgewic)m(h)m(t)22 b(und)27 b(Sto\033w)n(ec)n(hsel)1988
+2440 y Fi(Fl\374ssigk)n(eitsgleic)m(hgewi)o(c)m(h)n(t)22
+b(und)28 b(Sto\033w)n(ec)n(hsel)1988 2540 y Fb(Fl\374ssigk)n(eitsgleic)
+n(hgewic)n(h)m(t)22 b(und)27 b(Sto\033w)n(ec)n(hsel)1988
+2639 y Fa(Fl\374ssigk)n(eitsgleic)n(hgewic)n(h)n(t)22
+b(und)28 b(Sto\033w)n(ec)n(hsel)1988 2739 y Fe(Fl\374ssigk)n(eitsgleic)
+n(hgewi)o(c)n(h)n(t)22 b(und)29 b(Sto\033w)n(ec)n(hsel)p
+eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/systems/tex-extensions/clasen/examples/example6/example6.tex b/systems/tex-extensions/clasen/examples/example6/example6.tex
new file mode 100644
index 0000000000..3e0ba79e6c
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/example6.tex
@@ -0,0 +1,68 @@
+\documentclass[twocolumn]{article}
+\pagestyle{empty}
+\usepackage[T1]{stretch,fontenc}
+\def\cs#1{\begingroup\normalfont\ttfamily\textbackslash#1\endgroup}
+
+\def\testpar{This is a test paragraph for \TeX's
+paragraph-breaking algorithm. It is a fairly complex algorithm,
+nevertheless improvements seem possible. As you will note, I
+stuffed this paragraph---\hbox to0pt{}longnonbreakingword---with long
+nonbreaking words just to make the algorithm work harder and
+to---\hbox to0pt{}longnonbreakingword---show some improvements that
+can be had by allowing font---\hbox to0pt{}longnonbreakingword---width
+variations.}
+
+\begin{document}
+
+\emergencystretch=0pt
+\disablestretch
+\subsection*{Original}
+\testpar\par
+
+\subsection*{Original with \cs{emergencystretch}}
+\testpar{\emergencystretch1em\par}
+
+\enablestretch
+\subsection*{Variants}
+\testpar\par
+
+\subsection*{Variants with \cs{emergencystretch}}
+\testpar{\emergencystretch1em\par}
+
+\subsection*{Setting boxes with stretch}
+\hbox spread-12pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-8pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-4pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-3pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-2pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread-1pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 0pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 1pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 2pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 3pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 4pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread 8pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+\hbox spread12pt{Fl\"ussigkeitsgleichgewicht und Stoffwechsel}
+
+\disablestretch
+\subsection*{The used fonts}
+\font\x=ecrm1000w0970
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent
+\font\x=ecrm1000w0980
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent
+\font\x=ecrm1000w0990
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent
+\font\x=ecrm1000
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent
+\font\x=ecrm1000w1010
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent
+\font\x=ecrm1000w1020
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par\noindent
+\font\x=ecrm1000w1030
+\x Fl\"ussigkeitsgleichgewicht und Stoffwechsel\par
+
+\end{document}
+
+
+
+
diff --git a/systems/tex-extensions/clasen/examples/example6/mktexmf b/systems/tex-extensions/clasen/examples/example6/mktexmf
new file mode 100755
index 0000000000..20bfeab9d9
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/mktexmf
@@ -0,0 +1,133 @@
+#!/bin/sh
+# original mktexmf -- make a new MF file, because one wasn't found.
+#
+# (If you change or delete the word `original' on the previous line,
+# installation won't write this script over yours.)
+#
+# te@informatik.uni-hannover.de, kb@mail.tug.org, and infovore@xs4all.nl.
+# Public domain.
+
+version='$Id: mktexmf,v 1.10 1998/02/01 15:19:42 olaf Exp $'
+progname=`echo $0 | sed 's@.*/@@'`
+usage="Usage: $progname FONT.
+
+Makes the Metafont source file for FONT, if possible. For example,
+\`ecr12' or \`cmr11'."
+
+# Common code for all scripts.
+mktex_opt=`kpsewhich --format='web2c files' mktex.opt`
+if test -z "$mktex_opt"; then
+ echo "$progname: Cannot find mktex.opt; check your installation." >&2
+ exit 1
+fi
+
+. "$mktex_opt"
+
+(
+# See comments in mktexpk.
+name="`echo $1 | sed 's%.*/%%; s%\.mf$%%'`"
+
+case "$name" in
+ *[0-9]w[0-9][0-9][0-9][0-9])
+ namestem=`echo "$name" | sed 's/w[0-9]*$//'`
+ extension=`echo "$name" | sed 's/^.*[0-9]w//'`;;
+ *) namestem="$name"
+ extension=1000;;
+esac
+
+rootname=`echo "$namestem" | sed 's/[0-9]*$//'`
+pointsize=`echo "$namestem" | sed "s/^$rootname//"`
+
+sauterroot=`kpsewhich b-$rootname.mf 2>/dev/null`
+if test -n "$sauterroot"; then
+ rootfile=$sauterroot
+else
+ case $rootname in
+ wn*)
+ lhname=`echo $name | sed 's/^wn/lh/'`
+ rootfile=`kpsewhich $lhname.mf 2>/dev/null`;;
+ *)
+ rootfile=`kpsewhich $rootname.mf 2>/dev/null`;;
+ esac
+fi
+{ test -z "$rootfile" || test ! -f "$rootfile"; } && exit 1
+
+OIFS=$IFS; IFS=$SEP
+set x `"$mktexnam" $namestem`; shift
+IFS=$OIFS
+
+destdir=`echo "$3" | sed 's%/[^/][^/]*$%%'`
+test -d "$destdir" || "$mktexdir" "$destdir" || exit 1
+cd "$destdir" >/dev/null 2>&1 || exit 1
+
+case "$pointsize" in
+ "") echo "$progname: no pointsize."; exit 1;;
+ 11) realsize=10.95444;; # \magstephalf
+ 14) realsize=14.4;; # \magstep2
+ 17) realsize=17.28;; # \magstep3
+ 20) realsize=20.74;; # \magstep4
+ 25) realsize=24.88;; # \magstep5
+ # The new convention is to have three or four letters for the
+ # font name and four digits for the pointsize. The number is
+ # pointsize * 100. We effectively divide by 100 by ignoring the
+ # last two digits.
+ ????|?????) realsize=`echo "$pointsize" | sed 's/\(..\)$/.\1/'`;;
+ *) realsize="$pointsize";;
+esac
+
+mfname="$name.mf"
+if test -r "$mfname"; then
+ echo "$progname: $destdir/$mfname already exists."
+ echo "$destdir/$mfname" >$STDOUT
+ "$mktexupd" "$destdir" "$mfname"
+ exit 0
+fi
+
+case "$name" in
+ ec*)
+ cat > "mf$$.tmp" <<END
+if unknown exbase: input exbase fi;
+font_stretch:=$extension/1000;
+input t1stretch;
+input stretch;
+gensize:=$realsize;
+generate $rootname;
+END
+ ;;
+ tc*)
+ cat > "mf$$.tmp" <<END
+if unknown exbase: input exbase fi;
+gensize:=$realsize;
+generate $rootname;
+END
+ ;;
+ dc*)
+ cat > "mf$$.tmp" <<END
+if unknown dxbase: input dxbase fi;
+gensize:=$realsize;
+generate $rootname;
+END
+ ;;
+ wn*)
+ cat > "mf$$.tmp" <<END
+wncoding:=1;
+input $lhname;
+END
+ ;;
+ *)
+ cat > "mf$$.tmp" <<END
+design_size := $realsize;
+input b-$rootname;
+END
+ ;;
+esac
+
+chmod `kpsestat -xst .` "mf$$.tmp"
+rm -f "$mfname"
+mv "mf$$.tmp" "$mfname"
+
+echo "$destdir/$mfname" >$STDOUT
+echo "$progname: $destdir/$mfname: successfully generated." >&2
+"$mktexupd" "$destdir" "$mfname"
+exit 0
+) 1>&2 </dev/null
diff --git a/systems/tex-extensions/clasen/examples/example6/mktexpk b/systems/tex-extensions/clasen/examples/example6/mktexpk
new file mode 100755
index 0000000000..ec4e15a088
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/mktexpk
@@ -0,0 +1,208 @@
+#!/bin/sh
+# original mktexpk -- make a new PK font, because one wasn't found.
+#
+# (If you change or delete the word `original' on the previous line,
+# installation won't write this script over yours.)
+#
+# te@informatik.uni-hannover.de, kb@mail.tug.org, and infovore@xs4all.nl.
+# Public domain.
+
+version='$Id: mktexpk,v 1.16 1998/01/29 20:43:16 olaf Exp $'
+progname=`echo $0 | sed 's@.*/@@'`
+usage="Usage: $progname NAME DPI BDPI MAG [MODE [DESTDIR [REDIRECT]]].
+
+Try to create a PK file for NAME at resolution DPI, with an assumed
+device base resolution of BDPI, and a Metafont \`mag' of MAG. Use MODE
+for the Metafont mode if supplied, unless MODE is \`default', in hich
+case guess as usual. (This is so you can specify DESTDIR without MODE.)
+Use DESTDIR for the root of where to install into, either the absolute
+irectory name to use (if it starts with a /) or relative to the default
+DESTDIR (if not). REDIRECT if supplied, is a string of the form '>&n',
+where n is the number of the file descriptor which is to receive,
+instead of stdout, the name of the newly created pk file."
+
+if test "x$7" != x; then
+ tail="`echo \"x$7\" | sed 's/^x>&//' | grep '^[0-9]*$'`"
+ if test -z "$tail"; then
+ echo "$progname: argument '$7' ignored - bad file number" >&2
+ elif test "$tail" != 1; then
+ eval 'exec 1>&$tail'
+ fi
+fi
+
+mt_min_args=4
+mt_max_args=7
+
+# Common code for all scripts.
+mktex_opt=`kpsewhich --format='web2c files' mktex.opt`
+if test -z "$mktex_opt"; then
+ echo "$progname: Cannot find mktex.opt; check your installation." >&2
+ exit 1
+fi
+
+. "$mktex_opt"
+
+# Since we want to pass the generated filename and only that filename
+# back to the caller on standard output, we do some redirections so
+# regular echo's will end up on stderr, and do an echo >$STDOUT at the end.
+# Then the contents of $STDOUT will be echoed to stdout by a trap.
+
+# start of redirection stdout -> stderr, stdin <- /dev/null
+(
+
+NAME=$1
+
+case "$NAME" in
+ *[0-9]w[0-9][0-9][0-9][0-9])
+ NAMESTEM=`echo "$NAME" | sed 's/w[0-9]*$//'`
+ EXTENSION=`echo "$NAME" | sed 's/^.*[0-9]w//'`;;
+ *) NAMESTEM="$NAME"
+ EXTENSION=1000;;
+esac
+
+DPI=$2
+BDPI=$3
+MAG=$4
+MODE=$5
+DEST="$6"
+
+# grep for the font in $PSMAPFILE. These are base font names, such as
+# rpplr (the original) or pplr0 (an interim step) or pplr8r (current).
+: ${PSMAPFILE=`kpsewhich psfonts.map`}
+pattern="^$NAMESTEM"'([ ]|$)'
+psline=`egrep "$pattern" $PSMAPFILE`
+if test -n "$psline"; then
+ MODE=modeless
+ # ps_to_pk is set in mktex.opt
+ case $ps_to_pk in
+ ps2pk)
+ set x `echo "$psline" | sed 's@[<["]@@g'`
+ shift; shift; shift;
+ encoding=; psname=; slant=; extend=
+ while test ! -z "$1"; do
+ case "$1" in
+ *.enc) encoding="-e $1";;
+ *.pf[ab]) psname="$1";;
+ *SlantFont) slant="-S $lastopt";;
+ *ExtendFont) extend="-E $lastopt";;
+ esac
+ lastopt="$1"
+ shift
+ done
+ test -n "$psname" ||
+ { pfa=`(kpsewhich $NAME.pfa 2>/dev/null)`; psname=$pfa; }
+ test -n "$psname" ||
+ { pfb=`(kpsewhich $NAME.pfb 2>/dev/null)`; psname=$pfb; }
+ ANAME=`echo $NAME | sed 's/8r$/8a/'`
+ test -n "$psname" ||
+ { pfa=`(kpsewhich $ANAME.pfa 2>/dev/null)`; psname=$pfa; }
+ test -n "$psname" ||
+ { pfb=`(kpsewhich $ANAME.pfb 2>/dev/null)`; psname=$pfb; }
+ if [ -z "$psname" ]; then
+ echo "$progname: cannot find $NAME.pfa or $NAME.pfb. Trying gsftopk." >&2
+ cmd="gsftopk $NAME $DPI"
+ else
+ cmd="ps2pk -v -X$DPI -R$BDPI $slant $extend $encoding $psname $NAME.${DPI}pk"
+ fi
+ ;;
+ *)
+ cmd="$ps_to_pk $NAME $DPI"
+ ;;
+ esac
+else
+ # Check that $BDPI and $MODE are consistent; if not, ignore the mode and
+ # hope we can correctly guess it from bdpi. (People like to specify the
+ # resolution on the command line, not the mode so much.)
+ if test -n "$MODE"; then
+ mf_bdpi=`mf \
+'\mode:='$MODE';mode_setup;message"BDPI= "&decimal round pixels_per_inch;end.'\
+ </dev/null \
+ | awk '/DPI=/ {print $2}'`
+ if test "$mf_bdpi" != $BDPI; then
+ echo "$progname: Mismatched mode $MODE and resolution $BDPI; ignoring mode." >&2
+ MODE=
+ fi
+ fi
+
+ # If an explicit mode is not supplied, try to guess. You can get a
+ # list of extant modes from ftp://ftp.tug.org/tex/modes.mf.
+ if test -z "$MODE" || test "$MODE" = default; then
+ case "$BDPI" in
+ 85) MODE=sun;;
+ 100) MODE=nextscrn;;
+ 180) MODE=toshiba;;
+ 300) MODE=cx;;
+ 400) MODE=nexthi;;
+ 600) MODE=ljfour;;
+ 1270) MODE=linoone;;
+ *) echo "$progname: Can't guess mode for $BDPI dpi devices." >&2
+ echo "$progname: Use a config file, or update me." >&2
+ exit 1
+ esac
+ fi
+
+ # Run Metafont. Always use plain Metafont, since reading cmbase.mf
+ # does not noticeably slow things down.
+ cmd="mf \mode:=$MODE; mag:=$MAG; nonstopmode; input $NAME"
+fi
+
+OIFS=$IFS; IFS=$SEP
+set x `"$mktexnam" $NAME $DPI $MODE $DEST`; shift
+IFS=$OIFS
+
+PKDEST="$1"
+PKDESTDIR=`echo "$PKDEST" | sed 's%/[^/][^/]*$%%'` # can't rely on dirname
+PKNAME=`basename "$PKDEST"`
+GFNAME=$NAME.${DPI}gf
+
+if test -r "$PKDESTDIR/$PKNAME"; then
+ echo "$progname: $PKDESTDIR/$PKNAME already exists." >&2
+ echo "$PKDESTDIR/$PKNAME" >$STDOUT
+ "$mktexupd" "$PKDESTDIR" $PKNAME
+ exit 0
+fi
+
+"$mktexdir" "$PKDESTDIR"
+if test ! -d "$PKDESTDIR"; then
+ echo "$progname: mktexdir $PKDESTDIR failed." >&2
+ exit 1
+fi
+
+echo "$progname: Running $cmd"
+$cmd </dev/null || {
+ # Don't abort if only "Strange path" errors occurr.
+ grep '^!' $NAME.log >$$.errs 2>/dev/null
+ grep '^! Strange path' $$.errs >$$.strange 2>/dev/null
+ if cmp $$.errs $$.strange >/dev/null 2>&1 \
+ && test -s $$.strange >/dev/null 2>&1; then
+ echo "$progname: warning: \`$cmd' caused strange path errors." >&2
+ else
+ echo "$progname: \`$cmd' failed." >&2
+ test -s $NAME.log && mv -f $NAME.log "$KPSE_DOT"
+ exit 1;
+ fi
+}
+
+test -r $GFNAME && { gftopk ./$GFNAME $PKNAME || exit 1; }
+test ! -f $PKNAME && test -f $NAME.${DPI}pk && mv $NAME.${DPI}pk $PKNAME
+if test ! -s $PKNAME; then
+ echo "$progname: \`$cmd' failed to make $PKNAME." >&2
+ exit 1
+fi
+
+# Install the PK file carefully, since others may be working simultaneously.
+# Use cp when mv fails, since DOS will fail mv for deeply-nested directories.
+mv $PKNAME "$PKDESTDIR/pk$$.tmp" 2>/dev/null \
+ || cp $PKNAME "$PKDESTDIR/pk$$.tmp" || exit 1
+cd $PKDESTDIR || exit 1
+test -r $PKNAME || mv pk$$.tmp $PKNAME || exit 1
+chmod `kpsestat -stx .` $PKNAME
+
+# Update ls-R if necessary.
+"$mktexupd" "$PKDESTDIR" $PKNAME
+
+# If this line (or an equivalent) is not present, dvipsk/xdvik/dviljk
+# will think mktexpk failed. Any other output to stdout will also lose.
+echo "$PKDESTDIR/$PKNAME" >$STDOUT
+echo "$progname: $PKDESTDIR/$PKNAME: successfully generated." >&2
+) 1>&2 </dev/null
diff --git a/systems/tex-extensions/clasen/examples/example6/mktextfm b/systems/tex-extensions/clasen/examples/example6/mktextfm
new file mode 100755
index 0000000000..fb4990e47c
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/mktextfm
@@ -0,0 +1,124 @@
+#!/bin/sh
+# original mktextfm -- make a new TFM file, because one wasn't found.
+#
+# (If you change or delete the word `original' on the previous line,
+# installation won't write this script over yours.)
+#
+# te@informatik.uni-hannover.de, kb@mail.tug.org, and infovore@xs4all.nl.
+# Public domain.
+
+version='$Id: mktextfm,v 1.14 1998/01/29 20:42:37 olaf Exp $'
+progname=`echo $0 | sed 's@.*/@@'`
+usage="Usage: $progname FONT [DESTDIR].
+
+Makes a TFM file for FONT, if possible. Use DESTDIR for the root of where
+to install into, either the absolute directory name to use (if it starts
+with a /) or relative to the default DESTDIR (if not)."
+
+mt_max_args=2
+
+# Common code for all scripts.
+mktex_opt=`kpsewhich --format='web2c files' mktex.opt`
+if test -z "$mktex_opt"; then
+ echo "$progname: Cannot find mktex.opt; check your installation." >&2
+ exit 1
+fi
+
+. "$mktex_opt"
+
+# start of redirection stdout -> stderr, stdin <- /dev/null
+(
+
+NAME=`basename "$1" .tfm`
+
+case "$NAME" in
+ *[0-9]w[0-9][0-9][0-9][0-9])
+ NAMESTEM=`echo "$NAME" | sed 's/w[0-9]*$//'`
+ EXTENSION=`echo "$NAME" | sed 's/^.*[0-9]w//'`;;
+ *) NAMESTEM="$NAME"
+ EXTENSION=1000;;
+esac
+
+MAG=1
+DEST="$2"
+DPI=$BDPI
+
+OIFS=$IFS; IFS=$SEP
+set x `"$mktexnam" $NAMESTEM $DPI $MODE $DEST`; shift
+IFS=$OIFS
+
+PKDEST="$1"
+TFMDEST="$2"
+PKDESTDIR=`echo "$PKDEST" | sed 's%/[^/][^/]*$%%'` # can't rely on dirname
+TFMDESTDIR=`echo "$TFMDEST" | sed 's%/[^/][^/]*$%%'`
+PKNAME=`basename "$PKDEST"`
+TFMNAME=$NAME.tfm
+GFNAME=$NAME.$DPI'gf'
+
+if test -r "$TFMDESTDIR/$TFMNAME"; then
+ echo "$progname: $TFMDESTDIR/$TFMNAME already exists." >&2
+ echo "$TFMDESTDIR/$TFMNAME" >$STDOUT
+ "$mktexupd" "$TFMDESTDIR" $TFMNAME
+ exit
+fi
+
+# Try to create the destdir first. Do not create fonts, if this fails.
+"$mktexdir" "$TFMDESTDIR"
+if test ! -d "$TFMDESTDIR"; then
+ echo "$progname: mktexdir $TFMDESTDIR failed."
+ exit 1
+fi
+
+cmd="mf \mode:=$MODE; mag:=$MAG; nonstopmode; input $NAME"
+echo "$progname: Running $cmd"
+
+$cmd </dev/null || {
+ grep '^!' $NAME.log >$$.errs 2>/dev/null
+ grep '^! Strange path' $$.errs >$$.strange 2>/dev/null
+ if cmp $$.errs $$.strange >/dev/null 2>&1 \
+ && test -s $$.strange >/dev/null 2>&1; then
+ echo "$progname: warning: \`$cmd' caused strange path errors." >&2
+ else
+ echo "$progname: \`$cmd' failed." >&2
+ test -s $NAME.log && mv -f $NAME.log "$KPSE_DOT"
+ exit 1;
+ fi
+}
+
+test -r $TFMNAME || { echo "$progname: \`$cmd' failed to make $TFMNAME."; exit 1; }
+
+# Install the TFM file carefully, since others may be working simultaneously.
+# Use cp when mv fails, since DOS will fail mv for deeply-nested directories.
+mv $TFMNAME "$TFMDESTDIR/tfm$$.tmp" 2>/dev/null \
+ || cp $TFMNAME "$TFMDESTDIR/tfm$$.tmp" || exit 1
+cd "$TFMDESTDIR" || exit 1
+test -r $TFMNAME || mv tfm$$.tmp $TFMNAME || exit 1
+chmod `kpsestat -xst .` $TFMNAME
+
+# OK, success with the TFM.
+"$mktexupd" "$TFMDESTDIR" $TFMNAME
+echo "$TFMDESTDIR/$TFMNAME" >$STDOUT
+echo "$progname: $TFMDESTDIR/$TFMNAME: successfully generated." >&2
+
+# Since we probably made a GF(->PK) file, too, may as well install it if
+# it's needed.
+cd $TEMPDIR
+if test -r $GFNAME && test ! -f "$PKDESTDIR/$PKNAME"; then
+ gftopk ./$GFNAME $PKNAME || exit 1
+ "$mktexdir" "$PKDESTDIR"
+ mv $PKNAME "$PKDESTDIR/pk$$.tmp" 2>/dev/null \
+ || cp $PKNAME "$PKDESTDIR/pk$$.tmp" || exit 1
+ cd "$PKDESTDIR" || exit 1
+ if test -f $PKNAME; then
+ rm -f pk$$.tmp
+ else
+ mv pk$$.tmp $PKNAME
+ chmod `kpsestat -xst .` $PKNAME
+ "$mktexupd" "$PKDESTDIR" $PKNAME
+ fi
+fi
+) 1>&2 </dev/null
+
+
+
+
diff --git a/systems/tex-extensions/clasen/examples/example6/stretch.mf b/systems/tex-extensions/clasen/examples/example6/stretch.mf
new file mode 100644
index 0000000000..03779b2215
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/stretch.mf
@@ -0,0 +1,18 @@
+if unknown font_stretch: font_stretch:=1; fi
+
+def subscr(expr n) =
+ if numeric n: n elseif string n: ASCII n fi
+enddef;
+
+let BEGINCHAR = beginchar;
+def beginchar(expr n, w, h, d) =
+ BEGINCHAR(n,(w)+(w)*(font_stretch-1)*char_stretch[subscr(n)],h,d)
+enddef;
+
+% this is for fonts based on exbase.mf which use
+% beginchar_twice instead of beginchar
+let BEGINCHAR_TWICE = beginchar_twice;
+def beginchar_twice(expr n, w, h, d) =
+ BEGINCHAR_TWICE(n,(w)+(w)*(font_stretch-1)*char_stretch[subscr(n)],h,d)
+enddef;
+
diff --git a/systems/tex-extensions/clasen/examples/example6/stretch.sty b/systems/tex-extensions/clasen/examples/example6/stretch.sty
new file mode 100644
index 0000000000..9ee89c501e
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/stretch.sty
@@ -0,0 +1,59 @@
+\ProvidesPackage{stretch}
+ [1998/04/18 experimental interface to experimental TeX^^J
+ extensions -- DO NOT USE!!!!]
+\DeclareOption{T1}{%
+
+% All fd files for ec fonts use \EC@family, thus we have a convenient
+% hook to add a sixth argument to the \DeclareFontShape call.
+\newcommand{\EC@family}[5]{%
+ \DeclareFontShape{#1}{#2}{#3}{#4}%
+ {<5><6><7><8><9><10><10.95><12><14.4>%
+ <17.28><20.74><24.88><29.86><35.83>genb*#5}%
+ {\addvariants{\fontname\font}{970,980,990,1010,1020,1030}}}
+
+% Make sure that LaTeX rereads the preloaded `t1cmr.fd'.
+\begingroup
+\nfss@catcodes
+\input{t1cmr.fd}
+\endgroup
+
+}% \DeclareOption{T1}
+
+\ProcessOptions
+
+%% #1 is an external font name (including an `at' or `scaled' suffix)
+%% like `cmr10' or `ecrm1000 at 8.9999pt'
+%% #2 is a comma-separated list of extension factors multiplied by 1000
+\def\enablestretch{\message{enabling\space font stretching...^^J}\hzstate=\@ne}
+\def\disablestretch{\message{disabling\space font stretching...^^J}\hzstate=\z@}
+
+%
+% This should be used in the sixth argument of \DeclareFontShape, eg
+%\DeclareFontFamily{OT1}{test}{}
+%\DeclareFontShape{OT1}{test}{m}{n}
+% {<10> [0.9]ecrm1000}
+% {\addvariants{\fontname\font}{970,980,990,1010,1020,1030}}
+\def\addvariants#1#2{\begingroup
+ \hzstate=\@ne% otherwise \fontvariant would be illegal
+ \expandafter\split@ext#1 \@@nil
+ \message{adding\space variants\space for\space <\f@stem><\f@ext>...^^J}%
+ \let\@tempb\@empty
+ \@tfor\@tempa:=#2,\do{%
+ \if,\@tempa
+ \font\x=\f@stem\ifnum\@tempb<1000 w0\@tempb\else w\@tempb\fi\f@ext
+ \fontvariant\font=\x
+ \message{\fontname\x^^J}%
+ \let\@tempb\@empty
+ \else
+ \edef\@tempc{\@tempb}%
+ \edef\@tempb{\@tempc\@tempa}%
+ \fi}%
+\endgroup}
+
+% Use like \split@ext<external fontname>\@@nil
+% This splits <external fontname> into a filename part and an `at'
+% or `scaled' part. The results are returned in \f@stem and \f@ext.
+\begingroup
+ \catcode`\ =10
+ \gdef\split@ext#1 #2\@@nil{\def\f@stem{#1}\def\f@ext{ #2}}
+\endgroup
diff --git a/systems/tex-extensions/clasen/examples/example6/t1stretch.mf b/systems/tex-extensions/clasen/examples/example6/t1stretch.mf
new file mode 100644
index 0000000000..f5d74b77c8
--- /dev/null
+++ b/systems/tex-extensions/clasen/examples/example6/t1stretch.mf
@@ -0,0 +1,262 @@
+% This is a rather sketchy first try at differentiating the
+% stretchability based on individual glyph shapes. The only glyphs
+% which are assigned nonzero stretchability are alphanumeric glyphs
+% with horizontal strokes.
+% It is essential that the first stretch is not zero, otherwise
+% sorting of the font variants will fail with the current implementation.
+char_stretch[oct"000"]:=0.1;
+char_stretch[oct"001"]:=0.0;
+char_stretch[oct"002"]:=0.0;
+char_stretch[oct"003"]:=0.0;
+char_stretch[oct"004"]:=0.0;
+char_stretch[oct"005"]:=0.0;
+char_stretch[oct"006"]:=0.0;
+char_stretch[oct"007"]:=0.0;
+char_stretch[oct"010"]:=0.0;
+char_stretch[oct"011"]:=0.0;
+char_stretch[oct"012"]:=0.0;
+char_stretch[oct"013"]:=0.0;
+char_stretch[oct"014"]:=0.0;
+char_stretch[oct"015"]:=0.0;
+char_stretch[oct"016"]:=0.0;
+char_stretch[oct"017"]:=0.0;
+char_stretch[oct"020"]:=0.0;
+char_stretch[oct"021"]:=0.0;
+char_stretch[oct"022"]:=0.0;
+char_stretch[oct"023"]:=0.0;
+char_stretch[oct"024"]:=0.0;
+char_stretch[oct"025"]:=1.0;
+char_stretch[oct"026"]:=1.0;
+char_stretch[oct"027"]:=0.0;
+char_stretch[oct"030"]:=0.0;
+char_stretch[oct"031"]:=0.0;
+char_stretch[oct"032"]:=0.0;
+char_stretch[oct"033"]:=1.0;
+char_stretch[oct"034"]:=1.0;
+char_stretch[oct"035"]:=1.0;
+char_stretch[oct"036"]:=1.0;
+char_stretch[oct"037"]:=1.0;
+char_stretch[oct"040"]:=0.0;
+char_stretch[oct"041"]:=0.0;
+char_stretch[oct"042"]:=0.0;
+char_stretch[oct"043"]:=0.0;
+char_stretch[oct"044"]:=0.0;
+char_stretch[oct"045"]:=0.0;
+char_stretch[oct"046"]:=0.0;
+char_stretch[oct"047"]:=0.0;
+char_stretch[oct"050"]:=0.0;
+char_stretch[oct"051"]:=0.0;
+char_stretch[oct"052"]:=0.0;
+char_stretch[oct"053"]:=0.0;
+char_stretch[oct"054"]:=0.0;
+char_stretch[oct"055"]:=0.0;
+char_stretch[oct"056"]:=0.0;
+char_stretch[oct"057"]:=0.0;
+char_stretch[oct"060"]:=1.0;
+char_stretch[oct"061"]:=0.0;
+char_stretch[oct"062"]:=1.0;
+char_stretch[oct"063"]:=1.0;
+char_stretch[oct"064"]:=1.0;
+char_stretch[oct"065"]:=1.0;
+char_stretch[oct"066"]:=1.0;
+char_stretch[oct"067"]:=1.0;
+char_stretch[oct"070"]:=1.0;
+char_stretch[oct"071"]:=1.0;
+char_stretch[oct"072"]:=0.0;
+char_stretch[oct"073"]:=0.0;
+char_stretch[oct"074"]:=0.0;
+char_stretch[oct"075"]:=0.0;
+char_stretch[oct"076"]:=0.0;
+char_stretch[oct"077"]:=0.0;
+char_stretch[oct"100"]:=0.0;
+char_stretch[oct"101"]:=1.0;
+char_stretch[oct"102"]:=1.0;
+char_stretch[oct"103"]:=1.0;
+char_stretch[oct"104"]:=1.0;
+char_stretch[oct"105"]:=1.0;
+char_stretch[oct"106"]:=1.0;
+char_stretch[oct"107"]:=1.0;
+char_stretch[oct"110"]:=1.0;
+char_stretch[oct"111"]:=0.0;
+char_stretch[oct"112"]:=0.5;
+char_stretch[oct"113"]:=1.0;
+char_stretch[oct"114"]:=1.0;
+char_stretch[oct"115"]:=1.0;
+char_stretch[oct"116"]:=1.0;
+char_stretch[oct"117"]:=1.0;
+char_stretch[oct"120"]:=1.0;
+char_stretch[oct"121"]:=1.0;
+char_stretch[oct"122"]:=1.0;
+char_stretch[oct"123"]:=1.0;
+char_stretch[oct"124"]:=1.0;
+char_stretch[oct"125"]:=1.0;
+char_stretch[oct"126"]:=1.0;
+char_stretch[oct"127"]:=1.0;
+char_stretch[oct"130"]:=1.0;
+char_stretch[oct"131"]:=1.0;
+char_stretch[oct"132"]:=1.0;
+char_stretch[oct"133"]:=0.0;
+char_stretch[oct"134"]:=0.0;
+char_stretch[oct"135"]:=0.0;
+char_stretch[oct"136"]:=0.0;
+char_stretch[oct"137"]:=0.0;
+char_stretch[oct"140"]:=0.0;
+char_stretch[oct"141"]:=1.0;
+char_stretch[oct"142"]:=1.0;
+char_stretch[oct"143"]:=1.0;
+char_stretch[oct"144"]:=1.0;
+char_stretch[oct"145"]:=1.0;
+char_stretch[oct"146"]:=0.5;
+char_stretch[oct"147"]:=1.0;
+char_stretch[oct"150"]:=1.0;
+char_stretch[oct"151"]:=0.0;
+char_stretch[oct"152"]:=0.0;
+char_stretch[oct"153"]:=1.0;
+char_stretch[oct"154"]:=0.0;
+char_stretch[oct"155"]:=1.0;
+char_stretch[oct"156"]:=1.0;
+char_stretch[oct"157"]:=1.0;
+char_stretch[oct"160"]:=1.0;
+char_stretch[oct"161"]:=1.0;
+char_stretch[oct"162"]:=0.5;
+char_stretch[oct"163"]:=1.0;
+char_stretch[oct"164"]:=0.0;
+char_stretch[oct"165"]:=1.0;
+char_stretch[oct"166"]:=1.0;
+char_stretch[oct"167"]:=1.0;
+char_stretch[oct"170"]:=1.0;
+char_stretch[oct"171"]:=1.0;
+char_stretch[oct"172"]:=1.0;
+char_stretch[oct"173"]:=0.0;
+char_stretch[oct"174"]:=0.0;
+char_stretch[oct"175"]:=0.0;
+char_stretch[oct"176"]:=0.0;
+char_stretch[oct"177"]:=0.0;
+char_stretch[oct"200"]:=1.0;
+char_stretch[oct"201"]:=1.0;
+char_stretch[oct"202"]:=1.0;
+char_stretch[oct"203"]:=1.0;
+char_stretch[oct"204"]:=1.0;
+char_stretch[oct"205"]:=1.0;
+char_stretch[oct"206"]:=1.0;
+char_stretch[oct"207"]:=1.0;
+char_stretch[oct"210"]:=1.0;
+char_stretch[oct"211"]:=1.0;
+char_stretch[oct"212"]:=1.0;
+char_stretch[oct"213"]:=1.0;
+char_stretch[oct"214"]:=1.0;
+char_stretch[oct"215"]:=1.0;
+char_stretch[oct"216"]:=1.0;
+char_stretch[oct"217"]:=1.0;
+char_stretch[oct"220"]:=1.0;
+char_stretch[oct"221"]:=1.0;
+char_stretch[oct"222"]:=1.0;
+char_stretch[oct"223"]:=1.0;
+char_stretch[oct"224"]:=1.0;
+char_stretch[oct"225"]:=1.0;
+char_stretch[oct"226"]:=1.0;
+char_stretch[oct"227"]:=1.0;
+char_stretch[oct"230"]:=1.0;
+char_stretch[oct"231"]:=1.0;
+char_stretch[oct"232"]:=1.0;
+char_stretch[oct"233"]:=1.0;
+char_stretch[oct"234"]:=1.0;
+char_stretch[oct"235"]:=0.0;
+char_stretch[oct"236"]:=1.0;
+char_stretch[oct"237"]:=0.0;
+char_stretch[oct"240"]:=1.0;
+char_stretch[oct"241"]:=1.0;
+char_stretch[oct"242"]:=1.0;
+char_stretch[oct"243"]:=1.0;
+char_stretch[oct"244"]:=1.0;
+char_stretch[oct"245"]:=1.0;
+char_stretch[oct"246"]:=1.0;
+char_stretch[oct"247"]:=1.0;
+char_stretch[oct"250"]:=0.0;
+char_stretch[oct"251"]:=0.0;
+char_stretch[oct"252"]:=0.0;
+char_stretch[oct"253"]:=1.0;
+char_stretch[oct"254"]:=1.0;
+char_stretch[oct"255"]:=1.0;
+char_stretch[oct"256"]:=1.0;
+char_stretch[oct"257"]:=0.5;
+char_stretch[oct"260"]:=0.5;
+char_stretch[oct"261"]:=1.0;
+char_stretch[oct"262"]:=1.0;
+char_stretch[oct"263"]:=1.0;
+char_stretch[oct"264"]:=0.5;
+char_stretch[oct"265"]:=0.5;
+char_stretch[oct"266"]:=1.0;
+char_stretch[oct"267"]:=1.0;
+char_stretch[oct"270"]:=1.0;
+char_stretch[oct"271"]:=1.0;
+char_stretch[oct"272"]:=1.0;
+char_stretch[oct"273"]:=1.0;
+char_stretch[oct"274"]:=1.0;
+char_stretch[oct"275"]:=0.0;
+char_stretch[oct"276"]:=0.0;
+char_stretch[oct"277"]:=0.0;
+char_stretch[oct"300"]:=1.0;
+char_stretch[oct"301"]:=1.0;
+char_stretch[oct"302"]:=1.0;
+char_stretch[oct"303"]:=1.0;
+char_stretch[oct"304"]:=1.0;
+char_stretch[oct"305"]:=1.0;
+char_stretch[oct"306"]:=1.0;
+char_stretch[oct"307"]:=1.0;
+char_stretch[oct"310"]:=1.0;
+char_stretch[oct"311"]:=1.0;
+char_stretch[oct"312"]:=1.0;
+char_stretch[oct"313"]:=1.0;
+char_stretch[oct"314"]:=0.0;
+char_stretch[oct"315"]:=0.0;
+char_stretch[oct"316"]:=0.0;
+char_stretch[oct"317"]:=0.0;
+char_stretch[oct"320"]:=1.0;
+char_stretch[oct"321"]:=1.0;
+char_stretch[oct"322"]:=1.0;
+char_stretch[oct"323"]:=1.0;
+char_stretch[oct"324"]:=1.0;
+char_stretch[oct"325"]:=1.0;
+char_stretch[oct"326"]:=1.0;
+char_stretch[oct"327"]:=1.0;
+char_stretch[oct"330"]:=1.0;
+char_stretch[oct"331"]:=1.0;
+char_stretch[oct"332"]:=1.0;
+char_stretch[oct"333"]:=1.0;
+char_stretch[oct"334"]:=1.0;
+char_stretch[oct"335"]:=1.0;
+char_stretch[oct"336"]:=1.0;
+char_stretch[oct"337"]:=1.0;
+char_stretch[oct"340"]:=1.0;
+char_stretch[oct"341"]:=1.0;
+char_stretch[oct"342"]:=1.0;
+char_stretch[oct"343"]:=1.0;
+char_stretch[oct"344"]:=1.0;
+char_stretch[oct"345"]:=1.0;
+char_stretch[oct"346"]:=1.0;
+char_stretch[oct"347"]:=1.0;
+char_stretch[oct"350"]:=1.0;
+char_stretch[oct"351"]:=1.0;
+char_stretch[oct"352"]:=1.0;
+char_stretch[oct"353"]:=1.0;
+char_stretch[oct"354"]:=0.0;
+char_stretch[oct"355"]:=0.0;
+char_stretch[oct"356"]:=0.0;
+char_stretch[oct"357"]:=0.0;
+char_stretch[oct"360"]:=1.0;
+char_stretch[oct"361"]:=1.0;
+char_stretch[oct"362"]:=1.0;
+char_stretch[oct"363"]:=1.0;
+char_stretch[oct"364"]:=1.0;
+char_stretch[oct"365"]:=1.0;
+char_stretch[oct"366"]:=1.0;
+char_stretch[oct"367"]:=1.0;
+char_stretch[oct"370"]:=1.0;
+char_stretch[oct"371"]:=1.0;
+char_stretch[oct"372"]:=1.0;
+char_stretch[oct"373"]:=1.0;
+char_stretch[oct"374"]:=1.0;
+char_stretch[oct"375"]:=1.0;
+char_stretch[oct"376"]:=1.0;
+char_stretch[oct"377"]:=1.0;
diff --git a/systems/tex-extensions/clasen/glue/etex.bib b/systems/tex-extensions/clasen/glue/etex.bib
new file mode 120000
index 0000000000..59519b0c14
--- /dev/null
+++ b/systems/tex-extensions/clasen/glue/etex.bib
@@ -0,0 +1 @@
+../etex.bib \ No newline at end of file
diff --git a/systems/tex-extensions/clasen/glue/glue-post-web2c.ch b/systems/tex-extensions/clasen/glue/glue-post-web2c.ch
new file mode 100644
index 0000000000..ffa0ca7899
--- /dev/null
+++ b/systems/tex-extensions/clasen/glue/glue-post-web2c.ch
@@ -0,0 +1,40 @@
+% This change file has to be applied after the web2c change file
+% to revert some changes which make assumtion on glue_ratio being
+% real. Apart from the following change, they are all related to
+% mltex.
+
+@x
+ { The Unix |pc| folks removed this restriction with a remark that
+ invalid bit patterns were vanishingly improbable, so we follow
+ their example without really understanding it.
+ |if abs(mem[p+glue_offset].int)<@'4000000 then print('?.?')|
+ |else| }
+ if fabs(g)>float_constant(20000) then
+ begin end;
+@y
+@z
+
+@x
+@!base_slant,@!accent_slant:real; {amount of slant}
+@y
+@!base_slant,@!accent_slant:scaled; {amount of slant}
+@z
+
+@x
+ base_slant:=slant(f)/float_constant(65536);
+@^real division@>
+@y
+ base_slant:=slant(f);
+@z
+
+@x
+ delta:=round((base_width-accent_width)/float_constant(2)+
+ base_height*base_slant-base_x_height*accent_slant);
+@^real multiplication@>
+@^real addition@>
+@y
+ delta:=x_over_n(base_width-accent_width,2)
+ +xn_over_d(base_height,base_slant,unity)
+ -xn_over_d(base_x_height,accent_slant,unity);
+@z
+
diff --git a/systems/tex-extensions/clasen/glue/glue.ch b/systems/tex-extensions/clasen/glue/glue.ch
new file mode 100644
index 0000000000..a847ca31f9
--- /dev/null
+++ b/systems/tex-extensions/clasen/glue/glue.ch
@@ -0,0 +1,677 @@
+@x
+@!interrupt:integer; {should \TeX\ pause for instructions?}
+@!OK_to_interrupt:boolean; {should interrupts be observed?}
+
+@ @<Set init...@>=
+interrupt:=0; OK_to_interrupt:=true;
+@y
+@!interrupt:integer; {should \TeX\ pause for instructions?}
+@!OK_to_interrupt:boolean; {should interrupts be observed?}
+@!two_to_the: array[0..30] of integer; {$|two_to_the|[k]=2^k$}
+
+@ @<Set init...@>=
+interrupt:=0; OK_to_interrupt:=true;
+two_to_the[0]:=1;
+for i:=1 to 30 do two_to_the[i]:=two_to_the[i-1]+two_to_the[i-1];
+@z
+
+@x
+@ When \TeX\ ``packages'' a list into a box, it needs to calculate the
+proportionality ratio by which the glue inside the box should stretch
+or shrink. This calculation does not affect \TeX's decision making,
+so the precise details of rounding, etc., in the glue calculation are not
+of critical importance for the consistency of results on different computers.
+
+We shall use the type |glue_ratio| for such proportionality ratios.
+A glue ratio should take the same amount of memory as an
+|integer| (usually 32 bits) if it is to blend smoothly with \TeX's
+other data structures. Thus |glue_ratio| should be equivalent to
+|short_real| in some implementations of \PASCAL. Alternatively,
+it is possible to deal with glue ratios using nothing but fixed-point
+arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
+routines cited there must be modified to allow negative glue ratios.)
+@^system dependencies@>
+
+@d set_glue_ratio_zero(#) == #:=0.0 {store the representation of zero ratio}
+@d set_glue_ratio_one(#) == #:=1.0 {store the representation of unit ratio}
+@d float(#) == # {convert from |glue_ratio| to type |real|}
+@d unfloat(#) == # {convert from |real| to type |glue_ratio|}
+@d float_constant(#) == #.0 {convert |integer| constant to |real|}
+@y
+@ When \TeX\ ``packages'' a list into a box, it needs to calculate the
+proportionality ratio by which the glue inside the box should stretch
+or shrink. This calculation does not affect \TeX's decision making,
+so the precise details of rounding, etc., in the glue calculation are not
+of critical importance for the consistency of results on different computers.
+
+We shall use the type |glue_ratio| for such proportionality ratios.
+A glue ratio should take the same amount of memory as an
+|integer| (usually 32 bits) if it is to blend smoothly with \TeX's
+other data structures. Thus |glue_ratio| should be equivalent to
+|short_real| in some implementations of \PASCAL. Alternatively,
+it is possible to deal with glue ratios using nothing but fixed-point
+arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
+routines cited there must be modified to allow negative glue ratios.)
+
+This is what we do here. Our implementation stores |a+16| in the
+low five bits, |b| in the next five bits and |c+@'100000| in the
+next 17 bits of the integer |glue_ratio|. The procedures
+|pack_glue_ratio| and |unpack_glue_ratio| are used to convert
+to and from this format. A more efficient implementation would
+inline these prodedures and use shifting.
+
+@d glue_ratio_zero == 33554480 {|pack_glue_ratio(16,1,0)=33554480|}
+@d glue_ratio_one == 33556528 {|pack_glue_ratio(16,1,2)=33556528|}
+@d set_glue_ratio_zero(#) == #:=glue_ratio_zero
+@d set_glue_ratio_one(#) == #:=glue_ratio_one
+@z
+
+@x
+@!glue_ratio=real; {one-word representation of a glue expansion factor}
+@y
+@!glue_ratio=real; {one-word representation of a glue expansion factor}
+@!glue_ratio=integer; {one-word representation of a glue expansion factor}
+
+@ Before we can state the glue-multiplication function |glue_mult|, we need
+routines for packing and unpacking |glue_ratio|s.
+
+@p @!debug procedure check_range(l,h:integer; s:str_number; var v:integer);
+begin
+ if v<l then begin
+ v:=l;
+ print_err(s); print(" too small");
+ end else if v>h then begin
+ v:=h;
+ print_err(s); print(" too large");
+ end;
+end;
+gubed
+
+function pack_glue_ratio(a,b,c:integer):glue_ratio;
+begin
+ c:=c+@'100000;
+ @!debug
+ check_range(1,31,"pack_glue_ratio: a",a);
+ check_range(0,30,"pack_glue_ratio: b",b);
+ check_range(0,@'200000,"pack_glue_ratio: c",c);
+ gubed
+ pack_glue_ratio:=a+@'40*b+@'2000*c;
+end;
+
+procedure unpack_glue_ratio(g:glue_ratio; var a,b,c:integer);
+begin
+ c:=(g mod @'1000000000) div @'2000;
+ b:=(g mod @'2000) div @'40;
+ a:=g mod @'40;
+ @!debug
+ check_range(1,31,"unpack_glue_ratio: a",a);
+ check_range(0,30,"unpack_glue_ratio: b",b);
+ check_range(0,@'200000,"unpack_glue_ratio: c",c);
+ gubed
+ c:=c-@'100000;
+end;
+
+function glue_mult(@!x:scaled;@!g:glue_ratio):integer;
+var a,b,c:integer;
+begin
+unpack_glue_ratio(g,a,b,c);
+if a>16 then x:=x div two_to_the[a-16] {right shift by |a| places}
+else x:=x*two_to_the[16-a]; {left shift by |-a| places}
+glue_mult:=(x*c) div two_to_the[b]; {right shift by |b| places}
+ end; {note that |b| may be as large as 30}
+
+@*Glue setting.
+The |glue_fix| function computes |a|, |b|, and |c| by the method
+explained in {\sl TUGboat \bf3},1 (March 1982), 10--27. This
+implementation differs from the one given there in that it treats negative
+values of |s| properly. To do so, we allow |c| to range from -@'100000 to
+@'100000 and store it shifted by @'100000.
+
+|glue_fix| returns a |glue_ratio| approximation of |t/s|.
+
+@p function glue_fix(@!s,@!t,@!y:scaled):glue_ratio;
+var @!a,@!b,@!c:integer; {components of the desired ratio}
+@!k,@!h:integer; {$30-\lfloor\lg s\rfloor$, $30-\lfloor\lg t\rfloor$}
+@!s0:integer; {original (unnormalized) value of |s|}
+@!q,@!r,@!s1:integer; {quotient, remainder, divisor}
+@!w:integer; {$2^l$, where $l=16-k$}
+@!negative:boolean;
+begin
+negative:=false;
+if s<0 then begin
+ negative:=true;
+ s:=-s;
+end;
+if y=0 then begin
+ print("glue_fix: y=0. Why?");
+ glue_fix:=pack_glue_ratio(a+16,b,c);
+end else begin
+@<Normalize |s|, |t|, and |y|, computing |a|, |k|, and |h|@>;
+if t<s then b:=15-a-k+h@+else b:=14-a-k+h;
+if (b<0) or (b>30) then
+ begin if b<0 then
+ begin
+ print_err("Excessive glue");
+@.Excessive glue@>
+ help2("I can't work with sizes bigger than about 19 feet.")@/
+ ("Proceed, with fingers crossed.");@/
+ error;
+ end;
+ b:=0; c:=0; {make |f(x)| identically zero}
+ end
+else begin if k>=16 then {easy case, $s_0<2^{15}$}
+ c:=(t div two_to_the[h-a-b]+s0-1) div s0 {here |1<=h-a-b<=k-14<=16|}
+ else @<Compute |c| by long division@>;
+ end;
+if negative then c:=-c;
+glue_fix:=pack_glue_ratio(a+16,b,c);
+end;
+end;
+
+@ @<Normalize |s|, |t|, and |y|, computing |a|, |k|, and |h|@>=
+begin a:=15; k:=0; h:=0; s0:=s;
+while y<@'10000000000 do {|y| is known to be positive}
+ begin decr(a); y:=y+y;
+ end;
+while s<@'10000000000 do {|s| is known to be positive}
+ begin incr(k); s:=s+s;
+ end;
+while t<@'10000000000 do {|t| is known to be positive}
+ begin incr(h); t:=t+t;
+ end;
+end {now $2^{30}\le t=2^ht_0<2^{31}$ and $2^{30}\le s=2^ks_0<2^{31}$,
+ hence $d=k-h$ if $t/s<1$}
+
+@ @<Compute |c| by long division@>=
+begin w:=two_to_the[16-k];
+s1:=s0 div w;
+q:=t div s1;
+r:=((t mod s1)*w)-((s0 mod w)*q);
+if r>0 then
+ begin incr(q); r:=r-s0;
+ end
+else while r<=-s0 do
+ begin decr(q); r:=r+s0;
+ end;
+if a+b+k-h=15 then c:=(q+1) div 2 @+else c:=(q+3) div 4;
+end
+@z
+
+@x
+@p @!debug procedure print_word(@!w:memory_word);
+ {prints |w| in all ways}
+begin print_int(w.int); print_char(" ");@/
+print_scaled(w.sc); print_char(" ");@/
+print_scaled(round(unity*float(w.gr))); print_ln;@/
+@^real multiplication@>
+print_int(w.hh.lh); print_char("="); print_int(w.hh.b0); print_char(":");
+print_int(w.hh.b1); print_char(";"); print_int(w.hh.rh); print_char(" ");@/
+print_int(w.qqqq.b0); print_char(":"); print_int(w.qqqq.b1); print_char(":");
+print_int(w.qqqq.b2); print_char(":"); print_int(w.qqqq.b3);
+end;
+gubed
+@y
+@p procedure print_gr(@!g:glue_ratio); {prints a glue multiplier}
+var @!j:-29..31; {the amount to shift |c|}
+ a,b,c:integer;
+begin
+unpack_glue_ratio(g,a,b,c);
+j:=32-a-b;
+while j>15 do
+ begin print("2x"); decr(j); {indicate multiples of 2 for BIG cases}
+ end;
+if j<0 then print_scaled(c div two_to_the[-j]) {shift right}
+else print_scaled(c*two_to_the[j]); {shift left}
+end;
+
+@!debug procedure print_word(@!w:memory_word);
+ {prints |w| in all ways}
+begin print_int(w.int); print_char(" ");@/
+print_scaled(w.sc); print_char(" ");@/
+print_gr(w.gr); print_ln;@/
+print_int(w.hh.lh); print_char("="); print_int(w.hh.b0); print_char(":");
+print_int(w.hh.b1); print_char(";"); print_int(w.hh.rh); print_char(" ");@/
+print_int(w.qqqq.b0); print_char(":"); print_int(w.qqqq.b1); print_char(":");
+print_int(w.qqqq.b2); print_char(":"); print_int(w.qqqq.b3);
+end;
+gubed
+@z
+
+@x
+@p procedure show_node_list(@!p:integer); {prints a node list symbolically}
+label exit;
+var n:integer; {the number of items already printed at this level}
+@!g:real; {a glue ratio, as a floating point number}
+@y
+@p procedure show_node_list(@!p:integer); {prints a node list symbolically}
+label exit;
+var n:integer; {the number of items already printed at this level}
+@!g:glue_ratio; {a glue ratio, as a floating point number}
+a,b,c,j:integer;
+@z
+
+@x
+@ The code will have to change in this place if |glue_ratio| is
+a structured type instead of an ordinary |real|. Note that this routine
+should avoid arithmetic errors even if the |glue_set| field holds an
+arbitrary random value. The following code assumes that a properly
+formed nonzero |real| number has absolute value $2^{20}$ or more when
+it is regarded as an integer; this precaution was adequate to prevent
+floating point underflow on the author's computer.
+@^system dependencies@>
+@^dirty \PASCAL@>
+
+@<Display the value of |glue_set(p)|@>=
+g:=float(glue_set(p));
+if (g<>float_constant(0))and(glue_sign(p)<>normal) then
+ begin print(", glue set ");
+ if glue_sign(p)=shrinking then print("- ");
+ if abs(mem[p+glue_offset].int)<@'4000000 then print("?.?")
+ else if abs(g)>float_constant(20000) then
+ begin if g>float_constant(0) then print_char(">")
+ else print("< -");
+ print_glue(20000*unity,glue_order(p),0);
+ end
+ else print_glue(round(unity*g),glue_order(p),0);
+@^real multiplication@>
+ end
+@y
+@ The code has been changed here, since |glue_ratio| is no longer |real|.
+Note that this routine should avoid arithmetic errors even if the |glue_set|
+field holds an arbitrary random value.
+
+@<Display the value of |glue_set(p)|@>=
+if (glue_ratio_zero<>glue_set(p))and(glue_sign(p)<>normal) then begin
+ print(", glue set ");
+ if glue_sign(p)=shrinking then print("- ");
+ if abs(mem[p+glue_offset].int)<@'4000000 then print("?.?")
+ else if abs(g)>float_constant(20000) then
+ begin end;
+ print_gr(glue_set(p));
+ case glue_order(p) of
+ normal: do_nothing;
+ fil: print("fil");
+ fill: print("fill");
+ filll: print("filll");
+ othercases print("foul")
+ endcases
+end;
+@z
+
+@x
+@!glue_temp:real; {glue value before rounding}
+@y
+@!glue_temp:scaled; {glue value before rounding}
+@z
+
+@x
+@ @d vet_glue(#)== glue_temp:=#;
+ if glue_temp>float_constant(1000000000) then
+ glue_temp:=float_constant(1000000000)
+ else if glue_temp<-float_constant(1000000000) then
+ glue_temp:=-float_constant(1000000000)
+@y
+@ @d vet_glue(#)== glue_temp:=#;
+ if glue_temp>1000000000 then glue_temp:=1000000000
+ else if glue_temp<-1000000000 then glue_temp:=-1000000000
+@z
+
+@x
+@<Move right or output leaders@>=
+begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ rule_wd:=rule_wd+round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*shrink(g));
+ rule_wd:=rule_wd-round(glue_temp);
+ end;
+ end;
+@y
+@<Move right or output leaders@>=
+begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin
+ vet_glue(glue_mult(stretch(g),glue_set(this_box)));
+ rule_wd:=rule_wd+glue_temp;
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin
+ vet_glue(glue_mult(shrink(g),glue_set(this_box)));
+ rule_wd:=rule_wd-glue_temp;
+ end;
+ end;
+@z
+
+@x
+@!glue_temp:real; {glue value before rounding}
+@y
+@!glue_temp:scaled; {glue value before rounding}
+@z
+
+@x
+@ @<Move down or output leaders@>=
+begin g:=glue_ptr(p); rule_ht:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ rule_ht:=rule_ht+round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*shrink(g));
+ rule_ht:=rule_ht-round(glue_temp);
+ end;
+ end;
+@y
+@ @<Move down or output leaders@>=
+begin g:=glue_ptr(p); rule_ht:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin
+ vet_glue(glue_mult(stretch(g),glue_set(this_box)));
+ rule_ht:=rule_ht+glue_temp;
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin
+ vet_glue(glue_mult(shrink(g),glue_set(this_box)));
+ rule_ht:=rule_ht-glue_temp;
+ end;
+ end;
+@z
+
+@x
+@!total_stretch, @!total_shrink: array[glue_ord] of scaled;
+ {glue found by |hpack| or |vpack|}
+@y
+@!total_stretch, @!total_shrink, @!max_stretch, @!max_shrink:
+ array[glue_ord] of scaled; {glue found by |hpack| or |vpack|}
+@z
+
+@x
+@ @<Clear dimensions to zero@>=
+d:=0; x:=0;
+total_stretch[normal]:=0; total_shrink[normal]:=0;
+total_stretch[fil]:=0; total_shrink[fil]:=0;
+total_stretch[fill]:=0; total_shrink[fill]:=0;
+total_stretch[filll]:=0; total_shrink[filll]:=0
+@y
+@ @<Clear dimensions to zero@>=
+d:=0; x:=0;
+total_stretch[normal]:=0; total_shrink[normal]:=0;
+total_stretch[fil]:=0; total_shrink[fil]:=0;
+total_stretch[fill]:=0; total_shrink[fill]:=0;
+total_stretch[filll]:=0; total_shrink[filll]:=0;
+max_stretch[normal]:=0; max_shrink[normal]:=0;
+max_stretch[fil]:=0; max_shrink[fil]:=0;
+max_stretch[fill]:=0; max_shrink[fill]:=0;
+max_stretch[filll]:=0; max_shrink[filll]:=0
+@z
+
+@x
+@ @<Incorporate glue into the horizontal totals@>=
+begin g:=glue_ptr(p); x:=x+width(g);@/
+o:=stretch_order(g); total_stretch[o]:=total_stretch[o]+stretch(g);
+o:=shrink_order(g); total_shrink[o]:=total_shrink[o]+shrink(g);
+@y
+@ @<Incorporate glue into the horizontal totals@>=
+begin g:=glue_ptr(p); x:=x+width(g);@/
+o:=stretch_order(g); total_stretch[o]:=total_stretch[o]+stretch(g);
+if abs(stretch(g))>max_stretch[o] then max_stretch[o]:=abs(stretch(g));
+o:=shrink_order(g); total_shrink[o]:=total_shrink[o]+shrink(g);
+if abs(shrink(g))>max_shrink[o] then max_shrink[o]:=abs(shrink(g));
+@z
+
+@x
+@ @<Determine horizontal glue stretch setting...@>=
+begin @<Determine the stretch order@>;
+glue_order(r):=o; glue_sign(r):=stretching;
+if total_stretch[o]<>0 then glue_set(r):=unfloat(x/total_stretch[o])
+@^real division@>
+else begin glue_sign(r):=normal;
+ set_glue_ratio_zero(glue_set(r)); {there's nothing to stretch}
+ end;
+@y
+@ @<Determine horizontal glue stretch setting...@>=
+begin @<Determine the stretch order@>;
+glue_order(r):=o; glue_sign(r):=stretching;
+if total_stretch[o]<>0 then
+ glue_set(r):=glue_fix(total_stretch[o],x,max_stretch[o])
+else begin glue_sign(r):=normal;
+ glue_set(r):=glue_ratio_zero; {there's nothing to stretch}
+ end;
+@z
+
+@x
+@ @<Determine horizontal glue shrink setting...@>=
+begin @<Determine the shrink order@>;
+glue_order(r):=o; glue_sign(r):=shrinking;
+if total_shrink[o]<>0 then glue_set(r):=unfloat((-x)/total_shrink[o])
+@^real division@>
+@y
+@ @<Determine horizontal glue shrink setting...@>=
+begin @<Determine the shrink order@>;
+glue_order(r):=o; glue_sign(r):=shrinking;
+if total_shrink[o]<>0 then
+ glue_set(r):=glue_fix(total_shrink[o],-x,max_shrink[o])
+@z
+
+@x
+@ @<Incorporate glue into the vertical totals@>=
+begin x:=x+d; d:=0;@/
+g:=glue_ptr(p); x:=x+width(g);@/
+o:=stretch_order(g); total_stretch[o]:=total_stretch[o]+stretch(g);
+o:=shrink_order(g); total_shrink[o]:=total_shrink[o]+shrink(g);
+@y
+@ @<Incorporate glue into the vertical totals@>=
+begin x:=x+d; d:=0;@/
+g:=glue_ptr(p); x:=x+width(g);@/
+o:=stretch_order(g); total_stretch[o]:=total_stretch[o]+stretch(g);
+if abs(stretch(g))>max_stretch[o] then max_stretch[o]:=abs(stretch(g));
+o:=shrink_order(g); total_shrink[o]:=total_shrink[o]+shrink(g);
+if abs(shrink(g))>max_shrink[o] then max_shrink[o]:=abs(shrink(g));
+@z
+
+@x
+@ @<Determine vertical glue stretch setting...@>=
+begin @<Determine the stretch order@>;
+glue_order(r):=o; glue_sign(r):=stretching;
+if total_stretch[o]<>0 then glue_set(r):=unfloat(x/total_stretch[o])
+@^real division@>
+@y
+@ @<Determine vertical glue stretch setting...@>=
+begin @<Determine the stretch order@>;
+glue_order(r):=o; glue_sign(r):=stretching;
+if total_stretch[o]<>0 then
+ glue_set(r):=glue_fix(total_stretch[o],x,max_stretch[o])
+@z
+
+@x
+@ @<Determine vertical glue shrink setting...@>=
+begin @<Determine the shrink order@>;
+glue_order(r):=o; glue_sign(r):=shrinking;
+if total_shrink[o]<>0 then glue_set(r):=unfloat((-x)/total_shrink[o])
+@^real division@>
+@y
+@ @<Determine vertical glue shrink setting...@>=
+begin @<Determine the shrink order@>;
+glue_order(r):=o; glue_sign(r):=shrinking;
+if total_shrink[o]<>0 then
+ glue_set(r):=glue_fix(total_shrink[o],-x,max_shrink[o])
+@z
+
+@x
+@ @<Append tabskip glue and an empty box to list |u|...@>=
+s:=link(s); v:=glue_ptr(s); link(u):=new_glue(v); u:=link(u);
+subtype(u):=tab_skip_code+1; t:=t+width(v);
+if glue_sign(p)=stretching then
+ begin if stretch_order(v)=glue_order(p) then
+ t:=t+round(float(glue_set(p))*stretch(v));
+@^real multiplication@>
+ end
+else if glue_sign(p)=shrinking then
+ begin if shrink_order(v)=glue_order(p) then
+ t:=t-round(float(glue_set(p))*shrink(v));
+ end;
+@y
+@ @<Append tabskip glue and an empty box to list |u|...@>=
+s:=link(s); v:=glue_ptr(s); link(u):=new_glue(v); u:=link(u);
+subtype(u):=tab_skip_code+1; t:=t+width(v);
+if glue_sign(p)=stretching then
+ begin if stretch_order(v)=glue_order(p) then
+ t:=t+glue_mult(stretch(v),glue_set(p));
+ end
+else if glue_sign(p)=shrinking then
+ begin if shrink_order(v)=glue_order(p) then
+ t:=t-glue_mult(shrink(v),glue_set(p));
+ end;
+@z
+
+@x
+@ @<Make the unset node |r| into an |hlist_node| of width |w|...@>=
+begin height(r):=height(q); depth(r):=depth(q);
+if t=width(r) then
+ begin glue_sign(r):=normal; glue_order(r):=normal;
+ set_glue_ratio_zero(glue_set(r));
+ end
+else if t>width(r) then
+ begin glue_sign(r):=stretching;
+ if glue_stretch(r)=0 then set_glue_ratio_zero(glue_set(r))
+ else glue_set(r):=unfloat((t-width(r))/glue_stretch(r));
+@^real division@>
+ end
+else begin glue_order(r):=glue_sign(r); glue_sign(r):=shrinking;
+ if glue_shrink(r)=0 then set_glue_ratio_zero(glue_set(r))
+ else if (glue_order(r)=normal)and(width(r)-t>glue_shrink(r)) then
+ set_glue_ratio_one(glue_set(r))
+ else glue_set(r):=unfloat((width(r)-t)/glue_shrink(r));
+ end;
+width(r):=w; type(r):=hlist_node;
+end
+@y
+@ @<Make the unset node |r| into an |hlist_node| of width |w|...@>=
+begin height(r):=height(q); depth(r):=depth(q);
+if t=width(r) then
+ begin glue_sign(r):=normal; glue_order(r):=normal;
+ glue_set(r):=glue_ratio_zero;
+ end
+else if t>width(r) then
+ begin glue_sign(r):=stretching;
+ if glue_stretch(r)=0 then glue_set(r):=glue_ratio_zero
+ else
+ glue_set(r):=glue_fix(glue_stretch(r),t-width(r),abs(glue_stretch(r)/2));
+ end
+else begin glue_order(r):=glue_sign(r); glue_sign(r):=shrinking;
+ if glue_shrink(r)=0 then glue_set(r):=glue_ratio_zero
+ else if (glue_order(r)=normal)and(width(r)-t>glue_shrink(r)) then
+ glue_set(r):=glue_ratio_one
+ else
+ glue_set(r):=glue_fix(glue_shrink(r),width(r)-t,abs(glue_shrink(r)/2));
+ end;
+width(r):=w; type(r):=hlist_node;
+end
+@z
+
+@x
+@ @<Make the unset node |r| into a |vlist_node| of height |w|...@>=
+begin width(r):=width(q);
+if t=height(r) then
+ begin glue_sign(r):=normal; glue_order(r):=normal;
+ set_glue_ratio_zero(glue_set(r));
+ end
+else if t>height(r) then
+ begin glue_sign(r):=stretching;
+ if glue_stretch(r)=0 then set_glue_ratio_zero(glue_set(r))
+ else glue_set(r):=unfloat((t-height(r))/glue_stretch(r));
+@^real division@>
+ end
+else begin glue_order(r):=glue_sign(r); glue_sign(r):=shrinking;
+ if glue_shrink(r)=0 then set_glue_ratio_zero(glue_set(r))
+ else if (glue_order(r)=normal)and(height(r)-t>glue_shrink(r)) then
+ set_glue_ratio_one(glue_set(r))
+ else glue_set(r):=unfloat((height(r)-t)/glue_shrink(r));
+ end;
+height(r):=w; type(r):=vlist_node;
+end
+@y
+@ @<Make the unset node |r| into a |vlist_node| of height |w|...@>=
+begin width(r):=width(q);
+if t=height(r) then
+ begin glue_sign(r):=normal; glue_order(r):=normal;
+ glue_set(r):=glue_ratio_zero;
+ end
+else if t>height(r) then
+ begin glue_sign(r):=stretching;
+ if glue_stretch(r)=0 then glue_set(r):=glue_ratio_zero
+ else
+ glue_set(r):=glue_fix(glue_stretch(r),t-height(r),abs(glue_stretch(r)/2));
+ end
+else begin glue_order(r):=glue_sign(r); glue_sign(r):=shrinking;
+ if glue_shrink(r)=0 then glue_set(r):=glue_ratio_zero
+ else if (glue_order(r)=normal)and(height(r)-t>glue_shrink(r)) then
+ glue_set(r):=glue_ratio_one
+ else
+ glue_set(r):=glue_fix(glue_shrink(r),height(r)-t,abs(glue_shrink(r)/2));
+ end;
+height(r):=w; type(r):=vlist_node;
+end
+@z
+
+@x
+procedure make_accent;
+var s,@!t: real; {amount of slant}
+@!p,@!q,@!r:pointer; {character, box, and kern nodes}
+@!f:internal_font_number; {relevant font}
+@!a,@!h,@!x,@!w,@!delta:scaled; {heights and widths, as explained above}
+@!i:four_quarters; {character information}
+begin scan_char_num; f:=cur_font; p:=new_character(f,cur_val);
+if p<>null then
+ begin x:=x_height(f); s:=slant(f)/float_constant(65536);
+@^real division@>
+@y
+procedure make_accent;
+var @!s,@!t:scaled; {amount of slant}
+@!p,@!q,@!r:pointer; {character, box, and kern nodes}
+@!f:internal_font_number; {relevant font}
+@!a,@!h,@!x,@!w,@!delta:scaled; {heights and widths, as explained above}
+@!i:four_quarters; {character information}
+begin scan_char_num; f:=cur_font; p:=new_character(f,cur_val);
+if p<>null then
+ begin x:=x_height(f); s:=slant(f);
+@z
+
+@x
+@<Append the accent with appropriate kerns...@>=
+begin t:=slant(f)/float_constant(65536);
+@^real division@>
+i:=char_info(f)(character(q));
+w:=char_width(f)(i); h:=char_height(f)(height_depth(i));
+if h<>x then {the accent must be shifted up or down}
+ begin p:=hpack(p,natural); shift_amount(p):=x-h;
+ end;
+delta:=round((w-a)/float_constant(2)+h*t-x*s);
+@^real multiplication@>
+@^real addition@>
+@y
+@<Append the accent with appropriate kerns...@>=
+begin t:=slant(f);
+i:=char_info(f)(character(q));
+w:=char_width(f)(i); h:=char_height(f)(height_depth(i));
+if h<>x then {the accent must be shifted up or down}
+ begin p:=hpack(p,natural); shift_amount(p):=x-h;
+ end;
+delta:=x_over_n(w-a,2)+xn_over_d(h,t,unity)-xn_over_d(x,s,unity);
+@z
+
diff --git a/systems/tex-extensions/clasen/glue/glue.tex b/systems/tex-extensions/clasen/glue/glue.tex
new file mode 100644
index 0000000000..d124bf32b0
--- /dev/null
+++ b/systems/tex-extensions/clasen/glue/glue.tex
@@ -0,0 +1,75 @@
+\documentclass[preprint]{ltugboat}
+\usepackage{shortvrb}
+\usepackage{url}
+
+\providecommand{\meta}[1]{\ensuremath{\langle\textit{#1}\rangle}}
+\makeatletter
+\providecommand{\eTeX}{$\m@th\varepsilon$-\TeX}
+\makeatother
+\hyphenation{pa-ra-me-ter}
+
+\emergencystretch=4mm
+\title{Purging \TeX\ from floating-point arithmetic}
+\author{Matthias Clasen}
+%\address{}
+\netaddress{maclas@gmx.de}
+\setcounter{page}{1}
+
+\begin{document}
+\maketitle
+\MakeShortVerb{\|}
+
+\section{Introduction}
+
+\TeX\ uses machine-dependent floating-point arithmetic for its
+internal glue computations. This is the reason why a (undoubtly very useful)
+general |\lastnode| command cannot be added to \TeX\ without risking
+the portability of documents.
+
+A long time ago, Knuth demonstrated how to implement \TeX's glue computations
+in fixed-point arithmetic\cite{Knuth:82,Knuth:91}. Knuth mentions that his
+code would have to be slightly generalized before it can be used in \TeX. To
+my knowledge, this has not been done before.
+
+After applying my change file, |tex.web| no longer contains any
+variables of type |real|, proving that I was successful in removing all
+floating-point arithmetic from \TeX. I have not implemented the (now possible)
+|\lastnode| primitive.
+
+\section{Implementation}
+
+The changes to \TeX{} the program sketched above are realized in the
+change file |glue.ch|, which is a rewrite of Knuth's |glue.web|.
+
+\section{Installation}
+
+ The change files are written for \TeX~3.1459. But it should need only
+ cosmetic changes to get them to work with other versions of \TeX3.
+
+ To make the change files for \TeX{} work, you have to apply the change file
+ |pre.ch| first. I have only tried these files with |web2c|, and
+ for that you need to surround the |web2c| change file with |pre-web2c.ch| and
+ |post-web2c.ch|. You also need the additional change file
+ |glue-post-web2c.ch| and the patch file |glueratio.patch|.
+ The patch file is necessary, since |web2c| fixes the type |glueratio|
+ to be |double| in a file which is not subject to the |web| translation
+ process. The patch file changes this to the new type |glueratio| if
+ the |cpp| macro |HAVE_GLUERATIO_TYPE| is defined.
+
+ All this boils down to the command line
+
+\begin{verbatim}
+mv tex.ch tex.ch.orig
+tie -c tex.ch tex.web pre.ch glue.ch \
+ pre-web2c.ch tex.ch.orig \
+ post-web2c.ch glue-post-web2c.ch
+patch < glueratio.ch
+export XCFLAGS=-DHAVE_GLUERATIO_TYPE
+\end{verbatim}
+
+ \makesignature
+
+ \bibliographystyle{plain}
+ \bibliography{etex}
+
+\end{document}
diff --git a/systems/tex-extensions/clasen/glue/glueratio.patch b/systems/tex-extensions/clasen/glue/glueratio.patch
new file mode 100644
index 0000000000..d8064e18a7
--- /dev/null
+++ b/systems/tex-extensions/clasen/glue/glueratio.patch
@@ -0,0 +1,15 @@
+--- texmfmp.h.orig Thu Jul 23 18:36:40 1998
++++ texmfmp.h Thu Jul 23 18:37:21 1998
+@@ -86,10 +86,12 @@
+
+ This type is set automatically to `float' by configure if a small TeX
+ is built. */
++#ifndef HAVE_GLUERATIO_TYPE
+ #ifndef GLUERATIO_TYPE
+ #define GLUERATIO_TYPE double
+ #endif
+ typedef GLUERATIO_TYPE glueratio;
++#endif
+
+ extern void setupcharset P1H(void);
+
diff --git a/systems/tex-extensions/clasen/hyphenation/classes.ch b/systems/tex-extensions/clasen/hyphenation/classes.ch
new file mode 100644
index 0000000000..27bbda3178
--- /dev/null
+++ b/systems/tex-extensions/clasen/hyphenation/classes.ch
@@ -0,0 +1,679 @@
+@x
+else begin print_err("I can't go on meeting you like this");
+@y
+else begin print_err("I can't go on meeting you like this (");
+ print(s); print_char(")");
+@z
+
+@x
+@d disc_node=7 {|type| of a discretionary node}
+@y
+With extended hyphenation, discretionaries have an additional property,
+the |hyphen_class| (which is an integer $0\leq\mathit{hyphen_class}\leq 9$).
+The penalty charged for a break depends on the |hyphen_class|.
+
+@d disc_node=7 {|type| of a discretionary node}
+@d disc_node_size=3 {number of words to allocate for a discretionary}
+@d hyphen_class(#)==mem[#+2].int {the class of this hyphen}
+@z
+
+@x
+@p function new_disc:pointer; {creates an empty |disc_node|}
+var p:pointer; {the new node}
+begin p:=get_node(small_node_size); type(p):=disc_node;
+replace_count(p):=0; pre_break(p):=null; post_break(p):=null;
+new_disc:=p;
+end;
+@y
+@p function new_disc(c:integer):pointer; {creates an empty |disc_node|}
+var p:pointer; {the new node}
+begin p:=get_node(disc_node_size); type(p):=disc_node;
+replace_count(p):=0; pre_break(p):=null; post_break(p):=null;
+hyphen_class(p):=c; new_disc:=p;
+end;
+@z
+
+@x
+disc_node: begin short_display(pre_break(p));
+ short_display(post_break(p));@/
+@y
+disc_node: begin short_display(pre_break(p));
+ if hyphen_classes_en and(hyphen_class(p)<>1) then print_int(hyphen_class(p));
+ short_display(post_break(p));@/
+@z
+
+@x
+ disc_node: begin flush_node_list(pre_break(p));
+ flush_node_list(post_break(p));
+ end;
+@y
+ disc_node: begin flush_node_list(pre_break(p));
+ flush_node_list(post_break(p));
+ free_node(p,disc_node_size); goto done;
+ end;
+@z
+
+@x
+disc_node: begin r:=get_node(small_node_size);
+ pre_break(r):=copy_node_list(pre_break(p));
+ post_break(r):=copy_node_list(post_break(p));
+ end;
+@y
+disc_node: begin r:=new_disc(hyphen_class(p));
+ pre_break(r):=copy_node_list(pre_break(p));
+ post_break(r):=copy_node_list(post_break(p));
+ end;
+@z
+
+@x
+@d hyph_data=99 {hyphenation data ( \.{\\hyphenation}, \.{\\patterns} )}
+@y
+@d hyph_data=99 {hyphenation data ( \.{\\hyphenation}, \.{\\patterns},
+ \.{\\hyphenpenalties} )}
+@z
+
+@x
+ if m=hmode then if nest[p].pg_field <> @'40600000 then
+ begin print(" (language"); print_int(nest[p].pg_field mod @'200000);
+ print(":hyphenmin"); print_int(nest[p].pg_field div @'20000000);
+ print_char(","); print_int((nest[p].pg_field div @'200000) mod @'100);
+ print_char(")");
+ end;
+@y
+ if m=hmode then if nest[p].pg_field <> @'40601000 then begin
+ print(" (language"); print_int(nest[p].pg_field mod @'400);
+ print(":hyphenmin"); print_int(nest[p].pg_field div @'20000000);
+ print_char(","); print_int((nest[p].pg_field div @'200000) mod @'100);
+ if hyphen_classes_en then begin
+ print(":hyphenclasses");
+ print_int((nest[p].pg_field div @'400) mod @'20);
+ end;
+ print_char(")");
+ end;
+@z
+
+@x
+@d hyphen_penalty_code=3 {penalty for break after discretionary hyphen}
+@d ex_hyphen_penalty_code=4 {penalty for break after explicit hyphen}
+@y
+@d hyphen_classes_code=3 {number of hyphenation classes}
+@d ex_hyphen_class_code=4 {hyphenation class of automatically
+ inserted empty discretionaries}
+@z
+
+@x
+{hyphen classes int_pars go here}
+@y
+@d hyphen_classes_state_code=58
+@d hyphen_penalty_base=59 {10 penalties for breaks after discretionary hyphens,
+ numbered from 0 to 9}
+@z
+
+@x
+@d hyphen_penalty==int_par(hyphen_penalty_code)
+@d ex_hyphen_penalty==int_par(ex_hyphen_penalty_code)
+@y
+@d hyphen_classes_state==int_par(hyphen_classes_state_code)
+@d hyphen_classes_en==(hyphen_classes_state>0)
+@d hyphen_penalties(#)==int_par(hyphen_penalty_base+#)
+@d default_hyphen_class=1
+@d hyphen_penalty==hyphen_penalties(default_hyphen_class)
+@d ex_hyphen_penalty==hyphen_penalties(ex_hyphen_class)
+@z
+
+@x
+hyphen_penalty_code:print_esc("hyphenpenalty");
+ex_hyphen_penalty_code:print_esc("exhyphenpenalty");
+@y
+hyphen_classes_code:print_esc("hyphenclasses");
+ex_hyphen_class_code:print_esc("exhyphenclass");
+@z
+
+@x
+error_context_lines_code:print_esc("errorcontextlines");
+@y
+error_context_lines_code:print_esc("errorcontextlines");
+hyphen_classes_state_code:print_esc("hyphenclassesstate");
+@z
+
+@x
+primitive("hyphenpenalty",assign_int,int_base+hyphen_penalty_code);@/
+@!@:hyphen_penalty_}{\.{\\hyphenpenalty} primitive@>
+primitive("exhyphenpenalty",assign_int,int_base+ex_hyphen_penalty_code);@/
+@!@:ex_hyphen_penalty_}{\.{\\exhyphenpenalty} primitive@>
+@y
+primitive("hyphenclasses",assign_int,int_base+hyphen_classes_code);@/
+@!@:hyphen_classes_}{\.{\\hyphenclasses} primitive@>
+primitive("exhyphenclass",assign_int,int_base+ex_hyphen_class_code);@/
+@!@:ex_hyphen_class_}{\.{\\exhyphenclass} primitive@>
+@z
+
+@x
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+@y
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+primitive("hyphenpenalty",assign_int,int_base+hyphen_penalty_base+1);@/
+@!@:hyphen_penalty_}{\.{\\hyphenpenalty} primitive@>
+primitive("exhyphenpenalty",assign_int,int_base+hyphen_penalty_base
+ +ex_hyphen_class);@/
+@!@:ex_hyphen_penalty_}{\.{\\exhyphenpenalty} primitive@>
+primitive("hyphenclassesstate",assign_int,int_base+hyphen_classes_state_code);@/
+@!@:hyphen_classes_state_}{\.{\\hyphenclassesstate} primitive@>
+@z
+
+@x
+escape_char:="\"; end_line_char:=carriage_return;
+@y
+escape_char:="\"; end_line_char:=carriage_return;
+hyphen_classes_state:=0;
+@z
+
+@x
+@ Here is a procedure that displays the contents of |eqtb[n]|
+symbolically.
+
+@p@t\4@>@<Declare the procedure called |print_cmd_chr|@>@;@/
+@y
+@ Here is a procedure that displays the contents of |eqtb[n]|
+symbolically.
+
+@p@t\4@>@<Declare the procedure called |print_cmd_chr|@>@;@/
+function is_enabled(@!b:boolean;@!j:quarterword;@!k:halfword):boolean;
+begin
+ if not b then begin
+ print_err("Improper "); print_cmd_chr(j,k);
+ help1("Sorry, this optional feature has been disabled."); error;
+ end;
+ is_enabled:=b;
+end;
+@z
+
+@x
+init_cur_lang:=prev_graf mod @'200000;
+@y
+init_cur_lang:=prev_graf mod @'400;
+init_hyf_class:=(prev_graf div @'400) mod @'20;
+@z
+
+@x
+@ The following code knows that discretionary texts contain
+only character nodes, kern nodes, box nodes, rule nodes, and ligature nodes.
+
+@<Try to break after a discretionary fragment...@>=
+begin s:=pre_break(cur_p); disc_width:=0;
+if s=null then try_break(ex_hyphen_penalty,hyphenated)
+else begin repeat @<Add the width of node |s| to |disc_width|@>;
+ s:=link(s);
+ until s=null;
+ act_width:=act_width+disc_width;
+ try_break(hyphen_penalty,hyphenated);
+ act_width:=act_width-disc_width;
+ end;
+@y
+@ The following code knows that discretionary texts contain
+only character nodes, kern nodes, box nodes, rule nodes, and ligature nodes.
+If |ex_hyphen_penalty=0|, we might encounter automatically inserted empty
+discretionary nodes of class~0. We never break at these discretionaries,
+nevertheless they are necessary to differentiate the output of
+\.{\\showhyphens} for automatically inserted hyphens of classes 0 and~1.
+
+@<Try to break after a discretionary fragment...@>=
+begin if hyphen_class(cur_p)>0 then begin
+ s:=pre_break(cur_p); disc_width:=0;
+ while s<>null do begin
+ @<Add the width of node |s| to |disc_width|@>;
+ s:=link(s);
+ end;
+ act_width:=act_width+disc_width;
+ try_break(hyphen_penalties(hyphen_class(cur_p)),hyphenated);
+ act_width:=act_width-disc_width;
+ end;
+@z
+
+@x
+begin t:=replace_count(q);
+@y
+begin t:=replace_count(q); hyphen_class(q):=1;
+@z
+
+@x
+cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf;
+@y
+cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf;
+hyf_class:=init_hyf_class;
+@z
+
+@x
+@!hyf_bchar:halfword; {boundary character after $c_n$}
+@y
+@!hyf_bchar:halfword; {boundary character after $c_n$}
+@!hyf_class,@!init_hyf_class:integer;
+@z
+
+@x
+@!hyf:array [0..64] of 0..9; {odd values indicate discretionary hyphens}
+@y
+@!hyf:array [0..64] of small_number;
+@z
+
+@x
+@<If no hyphens were found, |return|@>=
+for j:=l_hyf to hn-r_hyf do if odd(hyf[j]) then goto found1;
+return;
+found1:
+@y
+@<If no hyphens were found, |return|@>=
+for j:=l_hyf to hn-r_hyf do if hyf[j]>0 then goto found1;
+return;
+found1:
+@z
+
+@x
+@d set_cur_r==begin if j<n then cur_r:=qi(hu[j+1])@+else cur_r:=bchar;
+ if odd(hyf[j]) then cur_rh:=hchar@+else cur_rh:=non_char;
+@y
+@d set_cur_r==begin if j<n then cur_r:=qi(hu[j+1])@+else cur_r:=bchar;
+ if hyf[j]>0 then cur_rh:=hchar@+else cur_rh:=non_char;
+@z
+
+@x
+ else begin if hchar<non_char then if odd(hyf[j]) then
+@y
+ else begin if hchar<non_char then if hyf[j]>0 then
+@z
+
+@x
+ while link(s)>null do s:=link(s);
+ if odd(hyf[j-1]) then
+@y
+ while link(s)>null do s:=link(s);
+ if hyf[j-1]>0 then
+@z
+
+@x
+repeat r:=get_node(small_node_size);
+@y
+repeat r:=new_disc(hyf[hyphen_passed]);
+@z
+
+@x
+hyphen_passed:=j-1; link(hold_head):=null;
+until not odd(hyf[j-1])
+@y
+hyphen_passed:=j-1; link(hold_head):=null;
+until hyf[j-1]=0
+@z
+
+@x
+found: for j:=0 to l_hyf-1 do hyf[j]:=0;
+for j:=0 to r_hyf-1 do hyf[hn-j]:=0
+@y
+for j:=l_hyf to hn-r_hyf do hyf[j]:=hyf[j] mod hyf_class;
+found: for j:=0 to l_hyf-1 do hyf[j]:=0;
+for j:=0 to r_hyf-1 do hyf[hn-j]:=0
+@z
+
+@x
+The words in the table point to lists in |mem| that specify hyphen positions
+in their |info| fields. The list for $c_1\ldots c_n$ contains the number |k| if
+the word $c_1\ldots c_n$ has a discretionary hyphen between $c_k$ and
+$c_{k+1}$.
+@y
+The words in the table point to lists in |mem| that specify hyphen positions
+and classes in their |type| and |subtype| fields. The list for $c_1\ldots c_n$
+contains the pair |k|, |l| if the word $c_1\ldots c_n$ has a discretionary
+hyphen of class |l| between $c_k$ and $c_{k+1}$.
+
+@d hyphen_exception_pos==type
+@d hyphen_exception_class==subtype
+@z
+
+@x
+while s<>null do
+ begin hyf[info(s)]:=1; s:=link(s);
+ end
+@y
+while s<>null do
+ begin hyf[hyphen_exception_pos(s)]:=hyphen_exception_class(s); s:=link(s);
+ end
+@z
+
+@x
+var n:0..64; {length of current word; not always a |small_number|}
+@y
+var n:0..64; {length of current word; not always a |small_number|}
+ at_hyphen:boolean;
+@z
+
+@x
+@ @<Enter as many...@>=
+n:=0; p:=null;
+@y
+@ @<Enter as many...@>=
+n:=0; p:=null; at_hyphen:=false;
+@z
+
+@x
+ if cur_cmd=right_brace then return;
+ n:=0; p:=null;
+@y
+ if cur_cmd=right_brace then return;
+ n:=0; p:=null; at_hyphen:=false;
+@z
+
+@x
+if cur_chr="-" then @<Append the value |n| to list |p|@>
+@y
+if cur_chr="-" then begin
+ at_hyphen:=true;
+ @<Append the value |n| to list |p|@>;
+end else if hyphen_classes_en and at_hyphen and
+ ("0"<=cur_chr)and(cur_chr<="9") then begin
+ hyphen_exception_class(p):=cur_chr-"0";
+ at_hyphen:=false;
+end
+@z
+
+@x
+begin if n<63 then
+ begin q:=get_avail; link(q):=p; info(q):=n; p:=q;
+ end;
+end
+@y
+begin if n<63 then
+ begin q:=get_avail; link(q):=p;
+ hyphen_exception_pos(q):=n;
+ hyphen_exception_class(q):=1;
+ p:=q;
+ end;
+end
+@z
+
+@x
+@!digit_sensed:boolean; {should the next digit be treated as a letter?}
+@y
+@!digits_sensed:integer; {should the next digit be treated as a letter?}
+@z
+
+@x
+k:=0; hyf[0]:=0; digit_sensed:=false;
+loop@+ begin get_x_token;
+@y
+k:=0; hyf[0]:=0; digits_sensed:=0;
+loop@+ begin get_x_token;
+@z
+
+@x
+ if cur_cmd=right_brace then goto done;
+ k:=0; hyf[0]:=0; digit_sensed:=false;
+@y
+ if cur_cmd=right_brace then goto done;
+ k:=0; hyf[0]:=0; digits_sensed:=0;
+@z
+
+@x
+if digit_sensed or(cur_chr<"0")or(cur_chr>"9") then
+@y
+if (cur_chr<"0")or(cur_chr>"9")or
+ ((not hyphen_classes_en)and(digits_sensed>=1))or(digits_sensed>=2) then
+@z
+
+@x
+ begin incr(k); hc[k]:=cur_chr; hyf[k]:=0; digit_sensed:=false;
+@y
+ begin incr(k); hc[k]:=cur_chr; hyf[k]:=0; digits_sensed:=0;
+@z
+
+@x
+else if k<63 then
+ begin hyf[k]:=cur_chr-"0"; digit_sensed:=true;
+ end
+@y
+else if k<63 then begin
+ if 10*hyf[k]+cur_chr-"0"<=63 then begin
+ hyf[k]:=10*hyf[k]+cur_chr-"0"; incr(digits_sensed);
+ end else begin
+ print_err("Bad "); print_esc("patterns");
+@.Bad \\patterns@>
+ help1("(See Appendix H.)"); error;
+ end;
+end
+@z
+
+@x
+ if mode>0 then tail_append(new_disc);
+@y
+ if mode>0 then tail_append(new_disc(ex_hyphen_class));
+@z
+
+@x
+else norm_min:=h;
+end;
+@y
+else norm_min:=h;
+end;
+@#
+function hyphen_classes:small_number;
+var h:integer;
+begin
+ if not hyphen_classes_en then hyphen_classes:=2
+ else begin
+ h:=int_par(hyphen_classes_code);
+ if h<2 then hyphen_classes:=2@+else if h>10 then hyphen_classes:=10@+
+ else hyphen_classes:=h;
+ end;
+end;
+
+function ex_hyphen_class:small_number;
+var h:integer;
+begin
+ if not hyphen_classes_en then ex_hyphen_class:=2
+ else begin
+ h:=int_par(ex_hyphen_class_code);
+ if h<0 then ex_hyphen_class:=0@+else if h>9 then ex_hyphen_class:=9@+
+ else ex_hyphen_class:=h;
+ end;
+end;
+@z
+
+@x
+prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min))
+ *@'200000+cur_lang;
+@y
+prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min))
+ *@'200000+hyphen_classes*@'400+cur_lang;
+@z
+
+@x
+primitive("discretionary",discretionary,0);
+@!@:discretionary_}{\.{\\discretionary} primitive@>
+@y
+primitive("discretionary",discretionary,0);
+@!@:discretionary_}{\.{\\discretionary} primitive@>
+primitive("gendiscretionary",discretionary,2);
+@!@:gendiscretionary_}{\.{\\gendiscretionary} primitive@>
+@z
+
+@x
+discretionary: if chr_code=1 then
+ print_esc("-")@+else print_esc("discretionary");
+@y
+discretionary: if chr_code=1 then
+ print_esc("-")@+else if chr_code=0 then print_esc("discretionary")
+ else print_esc("gendiscretionary");
+@z
+
+@x
+@ The space factor does not change when we append a discretionary node,
+but it starts out as 1000 in the subsidiary lists.
+
+@<Declare act...@>=
+procedure append_discretionary;
+var c:integer; {hyphen character}
+begin tail_append(new_disc);
+if cur_chr=1 then
+ begin c:=hyphen_char[cur_font];
+ if c>=0 then if c<256 then pre_break(tail):=new_character(cur_font,c);
+ end
+@y
+@ The space factor does not change when we append a discretionary node,
+but it starts out as 1000 in the subsidiary lists. We temporarily assign
+hyphen class 0 to discretionaries generated by one of the original
+primitives. This is necessary to simulate \TeX's behaviour on discretionaries
+with empty pre-break text. They charge the \.{\\exhyphenpenalty}, so we
+have to assign them to hyphen class |ex_hyphen_class|. Using
+\.{\\gendiscretionary}, one can generate discretionaries with empty pre-break
+text in other hyphen classes.
+
+@<Declare act...@>=
+procedure append_discretionary;
+var c:integer; {hyphen character}
+ class:integer; {hyphen class}
+begin
+ class:=default_hyphen_class;
+ if cur_chr<2 then class:=0
+ else if is_enabled(hyphen_classes_en,cur_cmd,cur_chr) then begin
+ scan_int;
+ if (1<=cur_val)and(cur_val<=9) then class:=cur_val
+ else begin
+ print_err("No such "); print_esc("hyphen class");
+@.No such \\hyphenpenalties@>
+ help2("Only numbers 1..9 are valid here.")@/
+ ("Proceed; I'll take 1 instead.");
+ error;
+ end;
+ end;
+ tail_append(new_disc(class));
+ if cur_chr=1 then begin
+ c:=hyphen_char[cur_font];
+ if c>=0 then if c<256 then pre_break(tail):=new_character(cur_font,c);
+ if pre_break(tail)=null then hyphen_class(tail):=ex_hyphen_class
+ else hyphen_class(tail):=default_hyphen_class;
+ end
+@z
+
+@x
+@ The three discretionary lists are constructed somewhat as if they were
+hboxes. A~subroutine called |build_discretionary| handles the transitions.
+(This is sort of fun.)
+@y
+@ The three discretionary lists are constructed somewhat as if they were
+hboxes. A~subroutine called |build_discretionary| handles the transitions.
+(This is sort of fun.)
+
+When we enter this routine, |tail| is a discretionary node whose hyphen class
+is zero, if it comes from \.{\\discretionary}. In that case we decide about
+the proper hyphen class after reading the pre-break text.
+@z
+
+@x
+0:pre_break(tail):=p;
+@y
+0:begin pre_break(tail):=p;
+ if hyphen_class(tail)=0 then
+ if (p=null) then hyphen_class(tail):=ex_hyphen_class
+ else hyphen_class(tail):=default_hyphen_class;
+end;
+@z
+
+@x
+primitive("patterns",hyph_data,1);
+@!@:patterns_}{\.{\\patterns} primitive@>
+@y
+primitive("patterns",hyph_data,1);
+@!@:patterns_}{\.{\\patterns} primitive@>
+primitive("hyphenpenalties",hyph_data,2);
+@!@:hyphenpenalties_}{\.{\\hyphenpenalties} primitive@>
+@z
+
+@x
+hyph_data: if chr_code=1 then print_esc("patterns")
+ else print_esc("hyphenation");
+@y
+hyph_data: if chr_code=1 then print_esc("patterns")
+ else if chr_code=0 then print_esc("hyphenation")
+ else print_esc("hyphenpenalties");
+@z
+
+@x
+ else begin new_hyph_exceptions; goto done;
+ end;
+@y
+ else if cur_chr=0 then begin
+ new_hyph_exceptions;
+ goto done;
+ end else if is_enabled(hyphen_classes_en,cur_cmd,cur_chr) then begin
+ scan_int; p:=cur_val;
+ scan_optional_equals; scan_int;
+ if (1<=p)and(p<=9) then begin
+ word_define(int_base+hyphen_penalty_base+p,cur_val);
+ end else begin
+ print_err("No such "); print_esc("hyphenpenalties");
+@.No such \\hyphenpenalties@>
+ help2("Only numbers 1..9 are valid here.")@/
+ ("Proceed; I'll ignore the assignment I just read.");
+ error;
+ end;
+ end;
+@z
+
+@x
+@d what_lang(#)==link(#+1) {language number, in the range |0..255|}
+@d what_lhm(#)==type(#+1) {minimum left fragment, in the range |1..63|}
+@d what_rhm(#)==subtype(#+1) {minimum right fragment, in the range |1..63|}
+@y
+@d what_lhm(#)==mem[#+1].qqqq.b0 {minimum left fragment, in the range |1..63|}
+@d what_rhm(#)==mem[#+1].qqqq.b1 {minimum right fragment, in the range |1..63|}
+@d what_lang(#)==mem[#+1].qqqq.b2 {language number, in the range |0..255|}
+@d what_hyf(#)==mem[#+1].qqqq.b3 {number of hyphen classes, in the range |2..10|}
+@z
+
+@x
+ print_int(what_lhm(p)); print_char(",");
+ print_int(what_rhm(p)); print_char(")");
+@y
+ print_int(what_lhm(p)); print_char(",");
+ print_int(what_rhm(p)); print_char(")");
+ if hyphen_classes_en then begin
+ print("(hyphen classes "); print_int(what_hyf(p));
+ print_char(")");
+ end;
+@z
+
+@x
+@ @d adv_past(#)==@+if subtype(#)=language_node then
+ begin cur_lang:=what_lang(#); l_hyf:=what_lhm(#); r_hyf:=what_rhm(#);@+end
+@y
+@ @d adv_past(#)==@+if subtype(#)=language_node then
+ begin cur_lang:=what_lang(#); l_hyf:=what_lhm(#); r_hyf:=what_rhm(#);
+ hyf_class:=what_hyf(#);@+end
+@z
+
+@x
+if l<>clang then
+ begin new_whatsit(language_node,small_node_size);
+ what_lang(tail):=l; clang:=l;@/
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+@y
+if l<>clang then
+ begin new_whatsit(language_node,small_node_size);
+ what_lang(tail):=l; clang:=l;@/
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+ what_hyf(tail):=hyphen_classes;
+@z
+
+@x
+ what_lang(tail):=clang;
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+@y
+ what_lang(tail):=clang;
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+ what_hyf(tail):=hyphen_classes;
+@z
+
diff --git a/systems/tex-extensions/clasen/hyphenation/count.ch b/systems/tex-extensions/clasen/hyphenation/count.ch
new file mode 100644
index 0000000000..7e3a63c1d7
--- /dev/null
+++ b/systems/tex-extensions/clasen/hyphenation/count.ch
@@ -0,0 +1,240 @@
+@x
+{hyphen count int_pars go here}
+@y
+@d hyphen_count_state_code=69
+@d three_hyphen_demerits_code=70 {demerits for three consecutive hyphens}
+@d four_hyphen_demerits_code=71 {demerits for four consecutive hyphens}
+@d five_hyphen_demerits_code=72 {demerits for five or more consecutive hyphens}
+@z
+
+@x
+@d error_context_lines==int_par(error_context_lines_code)
+@y
+@d hyphen_count_state==int_par(hyphen_count_state_code)
+@d hyphen_count_en==(hyphen_count_state>0)
+@d error_context_lines==int_par(error_context_lines_code)
+@d three_hyphen_demerits==int_par(three_hyphen_demerits_code)
+@d four_hyphen_demerits==int_par(four_hyphen_demerits_code)
+@d five_hyphen_demerits==int_par(five_hyphen_demerits_code)
+@z
+
+@x
+error_context_lines_code:print_esc("errorcontextlines");
+@y
+error_context_lines_code:print_esc("errorcontextlines");
+hyphen_count_state_code:print_esc("hyphencountstate");
+three_hyphen_demerits_code:print_esc("threehyphendemerits");
+four_hyphen_demerits_code:print_esc("fourhyphendemerits");
+five_hyphen_demerits_code:print_esc("fivehyphendemerits");
+@z
+
+@x
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+@y
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+primitive("threehyphendemerits",assign_int,int_base+three_hyphen_demerits_code);@/
+@!@:three_hyphen_demerits_}{\.{\\threehyphendemerits} primitive@>
+primitive("fourhyphendemerits",assign_int,int_base+four_hyphen_demerits_code);@/
+@!@:four_hyphen_demerits_}{\.{\\fourhyphendemerits} primitive@>
+primitive("fivehyphendemerits",assign_int,int_base+five_hyphen_demerits_code);@/
+@!@:five_hyphen_demerits_}{\.{\\fivehyphendemerits} primitive@>
+primitive("hyphencountstate",assign_int,int_base+hyphen_count_state_code);@/
+@!@:hyphen_count_state_}{\.{\\hyphencountstate} primitive@>
+@z
+
+@x
+escape_char:="\"; end_line_char:=carriage_return;
+@y
+escape_char:="\"; end_line_char:=carriage_return;
+hyphen_count_state:=0;
+@z
+
+@x
+@d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their
+ shrinkability}
+@y
+@d hyphen_count_limit=6 {treat 6 consecutive hyphens like 5}
+@d fitness_classes=4 {number of different fitness classes}
+@d line_classes=24 {|hyphen_count_limit*fitness_classes|}
+@d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their
+ shrinkability}
+@z
+
+@x
+@d active_node_size=3 {number of words in active nodes}
+@d fitness==subtype {|very_loose_fit..tight_fit| on final line for this break}
+@y
+@d active_node_size=3 {number of words in active nodes}
+@d line_fitness==subtype {|very_loose_fit..tight_fit| on final line for
+ this break; also contains information about number of consecutive hyphens}
+@d fitness(#)==(line_fitness(#) mod fitness_classes)
+@d hyphen_count(#)==(line_fitness(#) div fitness_classes)
+@z
+
+@x
+type(last_active):=hyphenated; line_number(last_active):=max_halfword;
+subtype(last_active):=0; {the |subtype| is never examined by the algorithm}
+@y
+type(last_active):=hyphenated; line_number(last_active):=max_halfword;
+line_fitness(last_active):=0; {the |fitness| is never examined by the
+ algorithm}
+@z
+
+@x
+@!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line}
+@y
+@!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line}
+@!consec:0..5; {number of consecutive hyphens up to test line}
+@!line_class:small_number; {|fit_class+fitness_classes*consec|}
+@z
+
+% We have to insert active nodes not only for the four fitness classes,
+% but for each fitness class/consecutive hyphen count combination. Since
+% we have |fitness_classes| fitness classes and |hyphen_count_limit| different
+% numbers of consecutive hyphens, we end up with up to |line_classes| active
+% nodes. The following arrays are no longer indexed by fit_class, but by
+% fit_class+fitness_classes*consec, where consec (<hyphen_count_limit) is the
+% number of consecutive hyphens.
+
+@x
+@!minimal_demerits:array[very_loose_fit..tight_fit] of integer; {best total
+ demerits known for current line class and position, given the fitness}
+@!minimum_demerits:integer; {best total demerits known for current line class
+ and position}
+@!best_place:array[very_loose_fit..tight_fit] of pointer; {how to achieve
+ |minimal_demerits|}
+@!best_pl_line:array[very_loose_fit..tight_fit] of halfword; {corresponding
+ line number}
+@y
+@!minimal_demerits:array[0..line_classes] of integer; {best total
+ demerits known for current line class and position, given |fit_class+4*consec|}
+@!minimum_demerits:integer; {best total demerits known for current line class
+ and position}
+@!best_place:array[0..line_classes] of pointer; {how to achieve |minimal_demerits|}
+@!best_pl_line:array[0..line_classes] of halfword; {corresponding line number}
+@z
+
+@x
+minimal_demerits[tight_fit]:=awful_bad;
+minimal_demerits[decent_fit]:=awful_bad;
+minimal_demerits[loose_fit]:=awful_bad;
+minimal_demerits[very_loose_fit]:=awful_bad;
+@y
+for j:=0 to line_classes do minimal_demerits[j]:=awful_bad;
+@z
+
+@x
+for fit_class:=very_loose_fit to tight_fit do
+ begin if minimal_demerits[fit_class]<=minimum_demerits then
+ @<Insert a new active node
+ from |best_place[fit_class]| to |cur_p|@>;
+ minimal_demerits[fit_class]:=awful_bad;
+ end;
+@y
+for fit_class:=very_loose_fit to tight_fit do
+ for consec:=0 to hyphen_count_limit-1 do begin
+ line_class:=fit_class+fitness_classes*consec;
+ if minimal_demerits[line_class]<=minimum_demerits then
+ @<Insert a new active node from |best_place[line_class]| to |cur_p|@>;
+ minimal_demerits[line_class]:=awful_bad;
+ end;
+@z
+
+@x
+@<Insert a new active node from |best_place[fit_class]| to |cur_p|@>=
+begin q:=get_node(passive_node_size);
+link(q):=passive; passive:=q; cur_break(q):=cur_p;
+@!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/
+prev_break(q):=best_place[fit_class];@/
+q:=get_node(active_node_size); break_node(q):=passive;
+line_number(q):=best_pl_line[fit_class]+1;
+fitness(q):=fit_class; type(q):=break_type;
+total_demerits(q):=minimal_demerits[fit_class];
+link(q):=r; link(prev_r):=q; prev_r:=q;
+@!stat if tracing_paragraphs>0 then
+ @<Print a symbolic description of the new break node@>;
+tats@;@/
+end
+@y
+@<Insert a new active node from |best_place[line_class]| to |cur_p|@>=
+begin q:=get_node(passive_node_size);
+link(q):=passive; passive:=q; cur_break(q):=cur_p;
+@!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/
+prev_break(q):=best_place[line_class];@/
+q:=get_node(active_node_size); break_node(q):=passive;
+line_number(q):=best_pl_line[line_class]+1;
+line_fitness(q):=line_class; type(q):=break_type;
+total_demerits(q):=minimal_demerits[line_class];
+link(q):=r; link(prev_r):=q; prev_r:=q;
+@!stat if tracing_paragraphs>0 then
+ @<Print a symbolic description of the new break node@>;
+tats@;@/
+end
+@z
+
+@x
+if break_type=hyphenated then print_char("-");
+@y
+if break_type=hyphenated then begin print("-("); print_int(consec); print_char(")"); end;
+@z
+
+@x
+else @<Set the value of |b| to the badness for shrinking the line,
+ and compute the corresponding |fit_class|@>;
+@y
+else @<Set the value of |b| to the badness for shrinking the line,
+ and compute the corresponding |fit_class|@>;
+if break_type=unhyphenated then consec:=0
+else if hyphen_count(r)=hyphen_count_limit-1 then consec:=hyphen_count(r)
+else consec:=hyphen_count(r)+1;
+line_class:=fit_class+fitness_classes*consec;
+@z
+
+@x
+if d<=minimal_demerits[fit_class] then
+ begin minimal_demerits[fit_class]:=d;
+ best_place[fit_class]:=break_node(r); best_pl_line[fit_class]:=l;
+ if d<minimum_demerits then minimum_demerits:=d;
+ end
+@y
+if d<=minimal_demerits[line_class] then
+ begin minimal_demerits[line_class]:=d;
+ best_place[line_class]:=break_node(r); best_pl_line[line_class]:=l;
+ if d<minimum_demerits then minimum_demerits:=d;
+ end
+@z
+
+@x
+if (break_type=hyphenated)and(type(r)=hyphenated) then
+ if cur_p<>null then d:=d+double_hyphen_demerits
+ else d:=d+final_hyphen_demerits;
+@y
+if (break_type=hyphenated)and(hyphen_count(r)>0) then
+ if cur_p=null then d:=d+final_hyphen_demerits
+ else if not hyphen_count_en then d:=d+double_hyphen_demerits
+ else case hyphen_count(r) of
+ 1: d:=d+double_hyphen_demerits;
+ 2: d:=d+three_hyphen_demerits;
+ 3: d:=d+four_hyphen_demerits;
+ othercases d:=d+five_hyphen_demerits;
+ endcases;
+@z
+
+@x
+q:=get_node(active_node_size);
+type(q):=unhyphenated; fitness(q):=decent_fit;
+@y
+q:=get_node(active_node_size);
+type(q):=unhyphenated; line_fitness(q):=decent_fit+fitness_classes*0;
+@z
+
+
+
+
+
+
+
+
+
diff --git a/systems/tex-extensions/clasen/hyphenation/etex.bib b/systems/tex-extensions/clasen/hyphenation/etex.bib
new file mode 120000
index 0000000000..59519b0c14
--- /dev/null
+++ b/systems/tex-extensions/clasen/hyphenation/etex.bib
@@ -0,0 +1 @@
+../etex.bib \ No newline at end of file
diff --git a/systems/tex-extensions/clasen/hyphenation/hyphenation.ch b/systems/tex-extensions/clasen/hyphenation/hyphenation.ch
new file mode 100644
index 0000000000..70adb89221
--- /dev/null
+++ b/systems/tex-extensions/clasen/hyphenation/hyphenation.ch
@@ -0,0 +1,883 @@
+@x
+else begin print_err("I can't go on meeting you like this");
+@y
+else begin print_err("I can't go on meeting you like this (");
+ print(s); print_char(")");
+@z
+
+@x
+@d disc_node=7 {|type| of a discretionary node}
+@y
+With extended hyphenation, discretionaries have an additional property,
+the |hyphen_class| (which is an integer $0\leq\mathit{hyphen_class}\leq 9$).
+The penalty charged for a break depends on the |hyphen_class|.
+
+@d disc_node=7 {|type| of a discretionary node}
+@d disc_node_size=3 {number of words to allocate for a discretionary}
+@d hyphen_class(#)==mem[#+2].int {the class of this hyphen}
+@z
+
+@x
+@p function new_disc:pointer; {creates an empty |disc_node|}
+var p:pointer; {the new node}
+begin p:=get_node(small_node_size); type(p):=disc_node;
+replace_count(p):=0; pre_break(p):=null; post_break(p):=null;
+new_disc:=p;
+end;
+@y
+@p function new_disc(c:integer):pointer; {creates an empty |disc_node|}
+var p:pointer; {the new node}
+begin p:=get_node(disc_node_size); type(p):=disc_node;
+replace_count(p):=0; pre_break(p):=null; post_break(p):=null;
+hyphen_class(p):=c; new_disc:=p;
+end;
+@z
+
+@x
+disc_node: begin short_display(pre_break(p));
+ short_display(post_break(p));@/
+@y
+disc_node: begin short_display(pre_break(p));
+ if hyphen_classes_en and(hyphen_class(p)<>1) then print_int(hyphen_class(p));
+ short_display(post_break(p));@/
+@z
+
+@x
+ disc_node: begin flush_node_list(pre_break(p));
+ flush_node_list(post_break(p));
+ end;
+@y
+ disc_node: begin flush_node_list(pre_break(p));
+ flush_node_list(post_break(p));
+ free_node(p,disc_node_size); goto done;
+ end;
+@z
+
+@x
+disc_node: begin r:=get_node(small_node_size);
+ pre_break(r):=copy_node_list(pre_break(p));
+ post_break(r):=copy_node_list(post_break(p));
+ end;
+@y
+disc_node: begin r:=new_disc(hyphen_class(p));
+ pre_break(r):=copy_node_list(pre_break(p));
+ post_break(r):=copy_node_list(post_break(p));
+ end;
+@z
+
+@x
+@d hyph_data=99 {hyphenation data ( \.{\\hyphenation}, \.{\\patterns} )}
+@y
+@d hyph_data=99 {hyphenation data ( \.{\\hyphenation}, \.{\\patterns},
+ \.{\\hyphenpenalties} )}
+@z
+
+@x
+ if m=hmode then if nest[p].pg_field <> @'40600000 then
+ begin print(" (language"); print_int(nest[p].pg_field mod @'200000);
+ print(":hyphenmin"); print_int(nest[p].pg_field div @'20000000);
+ print_char(","); print_int((nest[p].pg_field div @'200000) mod @'100);
+ print_char(")");
+ end;
+@y
+ if m=hmode then if nest[p].pg_field <> @'40601000 then begin
+ print(" (language"); print_int(nest[p].pg_field mod @'400);
+ print(":hyphenmin"); print_int(nest[p].pg_field div @'20000000);
+ print_char(","); print_int((nest[p].pg_field div @'200000) mod @'100);
+ if hyphen_classes_en then begin
+ print(":hyphenclasses");
+ print_int((nest[p].pg_field div @'400) mod @'20);
+ end;
+ print_char(")");
+ end;
+@z
+
+@x
+@d hyphen_penalty_code=3 {penalty for break after discretionary hyphen}
+@d ex_hyphen_penalty_code=4 {penalty for break after explicit hyphen}
+@y
+@d hyphen_classes_code=3 {number of hyphenation classes}
+@d ex_hyphen_class_code=4 {hyphenation class of automatically
+ inserted empty discretionaries}
+@z
+
+@x
+{hyphen classes int_pars go here}
+@y
+@d hyphen_classes_state_code=58
+@d hyphen_penalty_base=59 {10 penalties for breaks after discretionary hyphens,
+ numbered from 0 to 9}
+@z
+
+@x
+{hyphen count int_pars go here}
+@y
+@d hyphen_count_state_code=69
+@d three_hyphen_demerits_code=70 {demerits for three consecutive hyphens}
+@d four_hyphen_demerits_code=71 {demerits for four consecutive hyphens}
+@d five_hyphen_demerits_code=72 {demerits for five or more consecutive hyphens}
+@z
+
+@x
+@d hyphen_penalty==int_par(hyphen_penalty_code)
+@d ex_hyphen_penalty==int_par(ex_hyphen_penalty_code)
+@y
+@d hyphen_classes_state==int_par(hyphen_classes_state_code)
+@d hyphen_classes_en==(hyphen_classes_state>0)
+@d hyphen_penalties(#)==int_par(hyphen_penalty_base+#)
+@d default_hyphen_class=1
+@d hyphen_penalty==hyphen_penalties(default_hyphen_class)
+@d ex_hyphen_penalty==hyphen_penalties(ex_hyphen_class)
+@z
+
+@x
+@d error_context_lines==int_par(error_context_lines_code)
+@y
+@d hyphen_count_state==int_par(hyphen_count_state_code)
+@d hyphen_count_en==(hyphen_count_state>0)
+@d error_context_lines==int_par(error_context_lines_code)
+@d three_hyphen_demerits==int_par(three_hyphen_demerits_code)
+@d four_hyphen_demerits==int_par(four_hyphen_demerits_code)
+@d five_hyphen_demerits==int_par(five_hyphen_demerits_code)
+@z
+
+@x
+hyphen_penalty_code:print_esc("hyphenpenalty");
+ex_hyphen_penalty_code:print_esc("exhyphenpenalty");
+@y
+hyphen_classes_code:print_esc("hyphenclasses");
+ex_hyphen_class_code:print_esc("exhyphenclass");
+@z
+
+@x
+error_context_lines_code:print_esc("errorcontextlines");
+@y
+error_context_lines_code:print_esc("errorcontextlines");
+hyphen_count_state_code:print_esc("hyphencountstate");
+three_hyphen_demerits_code:print_esc("threehyphendemerits");
+four_hyphen_demerits_code:print_esc("fourhyphendemerits");
+five_hyphen_demerits_code:print_esc("fivehyphendemerits");
+hyphen_classes_state_code:print_esc("hyphenclassesstate");
+@z
+
+@x
+primitive("hyphenpenalty",assign_int,int_base+hyphen_penalty_code);@/
+@!@:hyphen_penalty_}{\.{\\hyphenpenalty} primitive@>
+primitive("exhyphenpenalty",assign_int,int_base+ex_hyphen_penalty_code);@/
+@!@:ex_hyphen_penalty_}{\.{\\exhyphenpenalty} primitive@>
+@y
+primitive("hyphenclasses",assign_int,int_base+hyphen_classes_code);@/
+@!@:hyphen_classes_}{\.{\\hyphenclasses} primitive@>
+primitive("exhyphenclass",assign_int,int_base+ex_hyphen_class_code);@/
+@!@:ex_hyphen_class_}{\.{\\exhyphenclass} primitive@>
+@z
+
+@x
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+@y
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+primitive("threehyphendemerits",assign_int,int_base+three_hyphen_demerits_code);@/
+@!@:three_hyphen_demerits_}{\.{\\threehyphendemerits} primitive@>
+primitive("fourhyphendemerits",assign_int,int_base+four_hyphen_demerits_code);@/
+@!@:four_hyphen_demerits_}{\.{\\fourhyphendemerits} primitive@>
+primitive("fivehyphendemerits",assign_int,int_base+five_hyphen_demerits_code);@/
+@!@:five_hyphen_demerits_}{\.{\\fivehyphendemerits} primitive@>
+primitive("hyphencountstate",assign_int,int_base+hyphen_count_state_code);@/
+@!@:hyphen_count_state_}{\.{\\hyphencountstate} primitive@>
+primitive("hyphenpenalty",assign_int,int_base+hyphen_penalty_base+1);@/
+@!@:hyphen_penalty_}{\.{\\hyphenpenalty} primitive@>
+primitive("exhyphenpenalty",assign_int,int_base+hyphen_penalty_base
+ +ex_hyphen_class);@/
+@!@:ex_hyphen_penalty_}{\.{\\exhyphenpenalty} primitive@>
+primitive("hyphenclassesstate",assign_int,int_base+hyphen_classes_state_code);@/
+@!@:hyphen_classes_state_}{\.{\\hyphenclassesstate} primitive@>
+@z
+
+@x
+escape_char:="\"; end_line_char:=carriage_return;
+@y
+escape_char:="\"; end_line_char:=carriage_return;
+hyphen_count_state:=0;
+hyphen_classes_state:=0;
+@z
+
+@x
+@ Here is a procedure that displays the contents of |eqtb[n]|
+symbolically.
+
+@p@t\4@>@<Declare the procedure called |print_cmd_chr|@>@;@/
+@y
+@ Here is a procedure that displays the contents of |eqtb[n]|
+symbolically.
+
+@p@t\4@>@<Declare the procedure called |print_cmd_chr|@>@;@/
+function is_enabled(@!b:boolean;@!j:quarterword;@!k:halfword):boolean;
+begin
+ if not b then begin
+ print_err("Improper "); print_cmd_chr(j,k);
+ help1("Sorry, this optional feature has been disabled."); error;
+ end;
+ is_enabled:=b;
+end;
+@z
+
+@x
+init_cur_lang:=prev_graf mod @'200000;
+@y
+init_cur_lang:=prev_graf mod @'400;
+init_hyf_class:=(prev_graf div @'400) mod @'20;
+@z
+
+@x
+@d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their
+ shrinkability}
+@y
+@d hyphen_count_limit=6 {treat 6 consecutive hyphens like 5}
+@d fitness_classes=4 {number of different fitness classes}
+@d line_classes=24 {|hyphen_count_limit*fitness_classes|}
+@d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their
+ shrinkability}
+@z
+
+@x
+@d active_node_size=3 {number of words in active nodes}
+@d fitness==subtype {|very_loose_fit..tight_fit| on final line for this break}
+@y
+@d active_node_size=3 {number of words in active nodes}
+@d line_fitness==subtype {|very_loose_fit..tight_fit| on final line for
+ this break; also contains information about number of consecutive hyphens}
+@d fitness(#)==(line_fitness(#) mod fitness_classes)
+@d hyphen_count(#)==(line_fitness(#) div fitness_classes)
+@z
+
+@x
+type(last_active):=hyphenated; line_number(last_active):=max_halfword;
+subtype(last_active):=0; {the |subtype| is never examined by the algorithm}
+@y
+type(last_active):=hyphenated; line_number(last_active):=max_halfword;
+line_fitness(last_active):=0; {the |fitness| is never examined by the
+ algorithm}
+@z
+
+@x
+@!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line}
+@y
+@!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line}
+@!consec:0..5; {number of consecutive hyphens up to test line}
+@!line_class:small_number; {|fit_class+fitness_classes*consec|}
+@z
+
+@x
+@!minimal_demerits:array[very_loose_fit..tight_fit] of integer; {best total
+ demerits known for current line class and position, given the fitness}
+@!minimum_demerits:integer; {best total demerits known for current line class
+ and position}
+@!best_place:array[very_loose_fit..tight_fit] of pointer; {how to achieve
+ |minimal_demerits|}
+@!best_pl_line:array[very_loose_fit..tight_fit] of halfword; {corresponding
+ line number}
+@y
+@!minimal_demerits:array[0..line_classes] of integer; {best total
+ demerits known for current line class and position, given |fit_class+4*consec|}
+@!minimum_demerits:integer; {best total demerits known for current line class
+ and position}
+@!best_place:array[0..line_classes] of pointer; {how to achieve |minimal_demerits|}
+@!best_pl_line:array[0..line_classes] of halfword; {corresponding line number}
+@z
+
+@x
+minimal_demerits[tight_fit]:=awful_bad;
+minimal_demerits[decent_fit]:=awful_bad;
+minimal_demerits[loose_fit]:=awful_bad;
+minimal_demerits[very_loose_fit]:=awful_bad;
+@y
+for j:=0 to line_classes do minimal_demerits[j]:=awful_bad;
+@z
+
+@x
+for fit_class:=very_loose_fit to tight_fit do
+ begin if minimal_demerits[fit_class]<=minimum_demerits then
+ @<Insert a new active node
+ from |best_place[fit_class]| to |cur_p|@>;
+ minimal_demerits[fit_class]:=awful_bad;
+ end;
+@y
+for fit_class:=very_loose_fit to tight_fit do
+ for consec:=0 to hyphen_count_limit-1 do begin
+ line_class:=fit_class+fitness_classes*consec;
+ if minimal_demerits[line_class]<=minimum_demerits then
+ @<Insert a new active node from |best_place[line_class]| to |cur_p|@>;
+ minimal_demerits[line_class]:=awful_bad;
+ end;
+@z
+
+@x
+@<Insert a new active node from |best_place[fit_class]| to |cur_p|@>=
+begin q:=get_node(passive_node_size);
+link(q):=passive; passive:=q; cur_break(q):=cur_p;
+@!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/
+prev_break(q):=best_place[fit_class];@/
+q:=get_node(active_node_size); break_node(q):=passive;
+line_number(q):=best_pl_line[fit_class]+1;
+fitness(q):=fit_class; type(q):=break_type;
+total_demerits(q):=minimal_demerits[fit_class];
+link(q):=r; link(prev_r):=q; prev_r:=q;
+@!stat if tracing_paragraphs>0 then
+ @<Print a symbolic description of the new break node@>;
+tats@;@/
+end
+@y
+@<Insert a new active node from |best_place[line_class]| to |cur_p|@>=
+begin q:=get_node(passive_node_size);
+link(q):=passive; passive:=q; cur_break(q):=cur_p;
+@!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/
+prev_break(q):=best_place[line_class];@/
+q:=get_node(active_node_size); break_node(q):=passive;
+line_number(q):=best_pl_line[line_class]+1;
+line_fitness(q):=line_class; type(q):=break_type;
+total_demerits(q):=minimal_demerits[line_class];
+link(q):=r; link(prev_r):=q; prev_r:=q;
+@!stat if tracing_paragraphs>0 then
+ @<Print a symbolic description of the new break node@>;
+tats@;@/
+end
+@z
+
+@x
+if break_type=hyphenated then print_char("-");
+@y
+if break_type=hyphenated then begin print("-("); print_int(consec); print_char(")"); end;
+@z
+
+@x
+else @<Set the value of |b| to the badness for shrinking the line,
+ and compute the corresponding |fit_class|@>;
+@y
+else @<Set the value of |b| to the badness for shrinking the line,
+ and compute the corresponding |fit_class|@>;
+if break_type=unhyphenated then consec:=0
+else if hyphen_count(r)=hyphen_count_limit-1 then consec:=hyphen_count(r)
+else consec:=hyphen_count(r)+1;
+line_class:=fit_class+fitness_classes*consec;
+@z
+
+@x
+if d<=minimal_demerits[fit_class] then
+ begin minimal_demerits[fit_class]:=d;
+ best_place[fit_class]:=break_node(r); best_pl_line[fit_class]:=l;
+ if d<minimum_demerits then minimum_demerits:=d;
+ end
+@y
+if d<=minimal_demerits[line_class] then
+ begin minimal_demerits[line_class]:=d;
+ best_place[line_class]:=break_node(r); best_pl_line[line_class]:=l;
+ if d<minimum_demerits then minimum_demerits:=d;
+ end
+@z
+
+@x
+if (break_type=hyphenated)and(type(r)=hyphenated) then
+ if cur_p<>null then d:=d+double_hyphen_demerits
+ else d:=d+final_hyphen_demerits;
+@y
+if (break_type=hyphenated)and(hyphen_count(r)>0) then
+ if cur_p=null then d:=d+final_hyphen_demerits
+ else if not hyphen_count_en then d:=d+double_hyphen_demerits
+ else case hyphen_count(r) of
+ 1: d:=d+double_hyphen_demerits;
+ 2: d:=d+three_hyphen_demerits;
+ 3: d:=d+four_hyphen_demerits;
+ othercases d:=d+five_hyphen_demerits;
+ endcases;
+@z
+
+@x
+q:=get_node(active_node_size);
+type(q):=unhyphenated; fitness(q):=decent_fit;
+@y
+q:=get_node(active_node_size);
+type(q):=unhyphenated; line_fitness(q):=decent_fit+fitness_classes*0;
+@z
+
+@x
+@ The following code knows that discretionary texts contain
+only character nodes, kern nodes, box nodes, rule nodes, and ligature nodes.
+
+@<Try to break after a discretionary fragment...@>=
+begin s:=pre_break(cur_p); disc_width:=0;
+if s=null then try_break(ex_hyphen_penalty,hyphenated)
+else begin repeat @<Add the width of node |s| to |disc_width|@>;
+ s:=link(s);
+ until s=null;
+ act_width:=act_width+disc_width;
+ try_break(hyphen_penalty,hyphenated);
+ act_width:=act_width-disc_width;
+ end;
+@y
+@ The following code knows that discretionary texts contain
+only character nodes, kern nodes, box nodes, rule nodes, and ligature nodes.
+If |ex_hyphen_penalty=0|, we might encounter automatically inserted empty
+discretionary nodes of class~0. We never break at these discretionaries,
+nevertheless they are necessary to differentiate the output of
+\.{\\showhyphens} for automatically inserted hyphens of classes 0 and~1.
+
+@<Try to break after a discretionary fragment...@>=
+begin if hyphen_class(cur_p)>0 then begin
+ s:=pre_break(cur_p); disc_width:=0;
+ while s<>null do begin
+ @<Add the width of node |s| to |disc_width|@>;
+ s:=link(s);
+ end;
+ act_width:=act_width+disc_width;
+ try_break(hyphen_penalties(hyphen_class(cur_p)),hyphenated);
+ act_width:=act_width-disc_width;
+ end;
+@z
+
+@x
+begin t:=replace_count(q);
+@y
+begin t:=replace_count(q); hyphen_class(q):=1;
+@z
+
+@x
+cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf;
+@y
+cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf;
+hyf_class:=init_hyf_class;
+@z
+
+@x
+@!hyf_bchar:halfword; {boundary character after $c_n$}
+@y
+@!hyf_bchar:halfword; {boundary character after $c_n$}
+@!hyf_class,@!init_hyf_class:integer;
+@z
+
+@x
+@!hyf:array [0..64] of 0..9; {odd values indicate discretionary hyphens}
+@y
+@!hyf:array [0..64] of small_number;
+@z
+
+@x
+@<If no hyphens were found, |return|@>=
+for j:=l_hyf to hn-r_hyf do if odd(hyf[j]) then goto found1;
+return;
+found1:
+@y
+@<If no hyphens were found, |return|@>=
+for j:=l_hyf to hn-r_hyf do if hyf[j]>0 then goto found1;
+return;
+found1:
+@z
+
+@x
+@d set_cur_r==begin if j<n then cur_r:=qi(hu[j+1])@+else cur_r:=bchar;
+ if odd(hyf[j]) then cur_rh:=hchar@+else cur_rh:=non_char;
+@y
+@d set_cur_r==begin if j<n then cur_r:=qi(hu[j+1])@+else cur_r:=bchar;
+ if hyf[j]>0 then cur_rh:=hchar@+else cur_rh:=non_char;
+@z
+
+@x
+ else begin if hchar<non_char then if odd(hyf[j]) then
+@y
+ else begin if hchar<non_char then if hyf[j]>0 then
+@z
+
+@x
+ while link(s)>null do s:=link(s);
+ if odd(hyf[j-1]) then
+@y
+ while link(s)>null do s:=link(s);
+ if hyf[j-1]>0 then
+@z
+
+@x
+repeat r:=get_node(small_node_size);
+@y
+repeat r:=new_disc(hyf[hyphen_passed]);
+@z
+
+@x
+hyphen_passed:=j-1; link(hold_head):=null;
+until not odd(hyf[j-1])
+@y
+hyphen_passed:=j-1; link(hold_head):=null;
+until hyf[j-1]=0
+@z
+
+@x
+found: for j:=0 to l_hyf-1 do hyf[j]:=0;
+for j:=0 to r_hyf-1 do hyf[hn-j]:=0
+@y
+for j:=l_hyf to hn-r_hyf do hyf[j]:=hyf[j] mod hyf_class;
+found: for j:=0 to l_hyf-1 do hyf[j]:=0;
+for j:=0 to r_hyf-1 do hyf[hn-j]:=0
+@z
+
+@x
+The words in the table point to lists in |mem| that specify hyphen positions
+in their |info| fields. The list for $c_1\ldots c_n$ contains the number |k| if
+the word $c_1\ldots c_n$ has a discretionary hyphen between $c_k$ and
+$c_{k+1}$.
+@y
+The words in the table point to lists in |mem| that specify hyphen positions
+and classes in their |type| and |subtype| fields. The list for $c_1\ldots c_n$
+contains the pair |k|, |l| if the word $c_1\ldots c_n$ has a discretionary
+hyphen of class |l| between $c_k$ and $c_{k+1}$.
+
+@d hyphen_exception_pos==type
+@d hyphen_exception_class==subtype
+@z
+
+@x
+while s<>null do
+ begin hyf[info(s)]:=1; s:=link(s);
+ end
+@y
+while s<>null do
+ begin hyf[hyphen_exception_pos(s)]:=hyphen_exception_class(s); s:=link(s);
+ end
+@z
+
+@x
+var n:0..64; {length of current word; not always a |small_number|}
+@y
+var n:0..64; {length of current word; not always a |small_number|}
+ at_hyphen:boolean;
+@z
+
+@x
+@ @<Enter as many...@>=
+n:=0; p:=null;
+@y
+@ @<Enter as many...@>=
+n:=0; p:=null; at_hyphen:=false;
+@z
+
+@x
+ if cur_cmd=right_brace then return;
+ n:=0; p:=null;
+@y
+ if cur_cmd=right_brace then return;
+ n:=0; p:=null; at_hyphen:=false;
+@z
+
+@x
+if cur_chr="-" then @<Append the value |n| to list |p|@>
+@y
+if cur_chr="-" then begin
+ at_hyphen:=true;
+ @<Append the value |n| to list |p|@>;
+end else if hyphen_classes_en and at_hyphen and
+ ("0"<=cur_chr)and(cur_chr<="9") then begin
+ hyphen_exception_class(p):=cur_chr-"0";
+ at_hyphen:=false;
+end
+@z
+
+@x
+begin if n<63 then
+ begin q:=get_avail; link(q):=p; info(q):=n; p:=q;
+ end;
+end
+@y
+begin if n<63 then
+ begin q:=get_avail; link(q):=p;
+ hyphen_exception_pos(q):=n;
+ hyphen_exception_class(q):=1;
+ p:=q;
+ end;
+end
+@z
+
+@x
+@!digit_sensed:boolean; {should the next digit be treated as a letter?}
+@y
+@!digits_sensed:integer; {should the next digit be treated as a letter?}
+@z
+
+@x
+k:=0; hyf[0]:=0; digit_sensed:=false;
+loop@+ begin get_x_token;
+@y
+k:=0; hyf[0]:=0; digits_sensed:=0;
+loop@+ begin get_x_token;
+@z
+
+@x
+ if cur_cmd=right_brace then goto done;
+ k:=0; hyf[0]:=0; digit_sensed:=false;
+@y
+ if cur_cmd=right_brace then goto done;
+ k:=0; hyf[0]:=0; digits_sensed:=0;
+@z
+
+@x
+if digit_sensed or(cur_chr<"0")or(cur_chr>"9") then
+@y
+if (cur_chr<"0")or(cur_chr>"9")or
+ ((not hyphen_classes_en)and(digits_sensed>=1))or(digits_sensed>=2) then
+@z
+
+@x
+ begin incr(k); hc[k]:=cur_chr; hyf[k]:=0; digit_sensed:=false;
+@y
+ begin incr(k); hc[k]:=cur_chr; hyf[k]:=0; digits_sensed:=0;
+@z
+
+@x
+else if k<63 then
+ begin hyf[k]:=cur_chr-"0"; digit_sensed:=true;
+ end
+@y
+else if k<63 then begin
+ if 10*hyf[k]+cur_chr-"0"<=63 then begin
+ hyf[k]:=10*hyf[k]+cur_chr-"0"; incr(digits_sensed);
+ end else begin
+ print_err("Bad "); print_esc("patterns");
+@.Bad \\patterns@>
+ help1("(See Appendix H.)"); error;
+ end;
+end
+@z
+
+@x
+ if mode>0 then tail_append(new_disc);
+@y
+ if mode>0 then tail_append(new_disc(ex_hyphen_class));
+@z
+
+@x
+else norm_min:=h;
+end;
+@y
+else norm_min:=h;
+end;
+@#
+function hyphen_classes:small_number;
+var h:integer;
+begin
+ if not hyphen_classes_en then hyphen_classes:=2
+ else begin
+ h:=int_par(hyphen_classes_code);
+ if h<2 then hyphen_classes:=2@+else if h>10 then hyphen_classes:=10@+
+ else hyphen_classes:=h;
+ end;
+end;
+
+function ex_hyphen_class:small_number;
+var h:integer;
+begin
+ if not hyphen_classes_en then ex_hyphen_class:=2
+ else begin
+ h:=int_par(ex_hyphen_class_code);
+ if h<0 then ex_hyphen_class:=0@+else if h>9 then ex_hyphen_class:=9@+
+ else ex_hyphen_class:=h;
+ end;
+end;
+@z
+
+@x
+prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min))
+ *@'200000+cur_lang;
+@y
+prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min))
+ *@'200000+hyphen_classes*@'400+cur_lang;
+@z
+
+@x
+primitive("discretionary",discretionary,0);
+@!@:discretionary_}{\.{\\discretionary} primitive@>
+@y
+primitive("discretionary",discretionary,0);
+@!@:discretionary_}{\.{\\discretionary} primitive@>
+primitive("gendiscretionary",discretionary,2);
+@!@:gendiscretionary_}{\.{\\gendiscretionary} primitive@>
+@z
+
+@x
+discretionary: if chr_code=1 then
+ print_esc("-")@+else print_esc("discretionary");
+@y
+discretionary: if chr_code=1 then
+ print_esc("-")@+else if chr_code=0 then print_esc("discretionary")
+ else print_esc("gendiscretionary");
+@z
+
+@x
+@ The space factor does not change when we append a discretionary node,
+but it starts out as 1000 in the subsidiary lists.
+
+@<Declare act...@>=
+procedure append_discretionary;
+var c:integer; {hyphen character}
+begin tail_append(new_disc);
+if cur_chr=1 then
+ begin c:=hyphen_char[cur_font];
+ if c>=0 then if c<256 then pre_break(tail):=new_character(cur_font,c);
+ end
+@y
+@ The space factor does not change when we append a discretionary node,
+but it starts out as 1000 in the subsidiary lists. We temporarily assign
+hyphen class 0 to discretionaries generated by one of the original
+primitives. This is necessary to simulate \TeX's behaviour on discretionaries
+with empty pre-break text. They charge the \.{\\exhyphenpenalty}, so we
+have to assign them to hyphen class |ex_hyphen_class|. Using
+\.{\\gendiscretionary}, one can generate discretionaries with empty pre-break
+text in other hyphen classes.
+
+@<Declare act...@>=
+procedure append_discretionary;
+var c:integer; {hyphen character}
+ class:integer; {hyphen class}
+begin
+ class:=default_hyphen_class;
+ if cur_chr<2 then class:=0
+ else if is_enabled(hyphen_classes_en,cur_cmd,cur_chr) then begin
+ scan_int;
+ if (1<=cur_val)and(cur_val<=9) then class:=cur_val
+ else begin
+ print_err("No such "); print_esc("hyphen class");
+@.No such \\hyphenpenalties@>
+ help2("Only numbers 1..9 are valid here.")@/
+ ("Proceed; I'll take 1 instead.");
+ error;
+ end;
+ end;
+ tail_append(new_disc(class));
+ if cur_chr=1 then begin
+ c:=hyphen_char[cur_font];
+ if c>=0 then if c<256 then pre_break(tail):=new_character(cur_font,c);
+ if pre_break(tail)=null then hyphen_class(tail):=ex_hyphen_class
+ else hyphen_class(tail):=default_hyphen_class;
+ end
+@z
+
+@x
+@ The three discretionary lists are constructed somewhat as if they were
+hboxes. A~subroutine called |build_discretionary| handles the transitions.
+(This is sort of fun.)
+@y
+@ The three discretionary lists are constructed somewhat as if they were
+hboxes. A~subroutine called |build_discretionary| handles the transitions.
+(This is sort of fun.)
+
+When we enter this routine, |tail| is a discretionary node whose hyphen class
+is zero, if it comes from \.{\\discretionary}. In that case we decide about
+the proper hyphen class after reading the pre-break text.
+@z
+
+@x
+0:pre_break(tail):=p;
+@y
+0:begin pre_break(tail):=p;
+ if hyphen_class(tail)=0 then
+ if (p=null) then hyphen_class(tail):=ex_hyphen_class
+ else hyphen_class(tail):=default_hyphen_class;
+end;
+@z
+
+@x
+primitive("patterns",hyph_data,1);
+@!@:patterns_}{\.{\\patterns} primitive@>
+@y
+primitive("patterns",hyph_data,1);
+@!@:patterns_}{\.{\\patterns} primitive@>
+primitive("hyphenpenalties",hyph_data,2);
+@!@:hyphenpenalties_}{\.{\\hyphenpenalties} primitive@>
+@z
+
+@x
+hyph_data: if chr_code=1 then print_esc("patterns")
+ else print_esc("hyphenation");
+@y
+hyph_data: if chr_code=1 then print_esc("patterns")
+ else if chr_code=0 then print_esc("hyphenation")
+ else print_esc("hyphenpenalties");
+@z
+
+@x
+ else begin new_hyph_exceptions; goto done;
+ end;
+@y
+ else if cur_chr=0 then begin
+ new_hyph_exceptions;
+ goto done;
+ end else if is_enabled(hyphen_classes_en,cur_cmd,cur_chr) then begin
+ scan_int; p:=cur_val;
+ scan_optional_equals; scan_int;
+ if (1<=p)and(p<=9) then begin
+ word_define(int_base+hyphen_penalty_base+p,cur_val);
+ end else begin
+ print_err("No such "); print_esc("hyphenpenalties");
+@.No such \\hyphenpenalties@>
+ help2("Only numbers 1..9 are valid here.")@/
+ ("Proceed; I'll ignore the assignment I just read.");
+ error;
+ end;
+ end;
+@z
+
+@x
+@d what_lang(#)==link(#+1) {language number, in the range |0..255|}
+@d what_lhm(#)==type(#+1) {minimum left fragment, in the range |1..63|}
+@d what_rhm(#)==subtype(#+1) {minimum right fragment, in the range |1..63|}
+@y
+@d what_lhm(#)==mem[#+1].qqqq.b0 {minimum left fragment, in the range |1..63|}
+@d what_rhm(#)==mem[#+1].qqqq.b1 {minimum right fragment, in the range |1..63|}
+@d what_lang(#)==mem[#+1].qqqq.b2 {language number, in the range |0..255|}
+@d what_hyf(#)==mem[#+1].qqqq.b3 {number of hyphen classes, in the range |2..10|}
+@z
+
+@x
+ print_int(what_lhm(p)); print_char(",");
+ print_int(what_rhm(p)); print_char(")");
+@y
+ print_int(what_lhm(p)); print_char(",");
+ print_int(what_rhm(p)); print_char(")");
+ if hyphen_classes_en then begin
+ print("(hyphen classes "); print_int(what_hyf(p));
+ print_char(")");
+ end;
+@z
+
+@x
+@ @d adv_past(#)==@+if subtype(#)=language_node then
+ begin cur_lang:=what_lang(#); l_hyf:=what_lhm(#); r_hyf:=what_rhm(#);@+end
+@y
+@ @d adv_past(#)==@+if subtype(#)=language_node then
+ begin cur_lang:=what_lang(#); l_hyf:=what_lhm(#); r_hyf:=what_rhm(#);
+ hyf_class:=what_hyf(#);@+end
+@z
+
+@x
+if l<>clang then
+ begin new_whatsit(language_node,small_node_size);
+ what_lang(tail):=l; clang:=l;@/
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+@y
+if l<>clang then
+ begin new_whatsit(language_node,small_node_size);
+ what_lang(tail):=l; clang:=l;@/
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+ what_hyf(tail):=hyphen_classes;
+@z
+
+@x
+ what_lang(tail):=clang;
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+@y
+ what_lang(tail):=clang;
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+ what_hyf(tail):=hyphen_classes;
+@z
+
diff --git a/systems/tex-extensions/clasen/hyphenation/hyphenation.tex b/systems/tex-extensions/clasen/hyphenation/hyphenation.tex
new file mode 100644
index 0000000000..5fbbd5a14e
--- /dev/null
+++ b/systems/tex-extensions/clasen/hyphenation/hyphenation.tex
@@ -0,0 +1,249 @@
+\documentclass[preprint]{ltugboat}
+\usepackage{shortvrb}
+\usepackage{booktabs}
+
+\providecommand{\meta}[1]{\ensuremath{\langle\textit{#1}\rangle}}
+\makeatletter
+\providecommand{\eTeX}{$\m@th\varepsilon$-\TeX}
+\makeatother
+\hyphenation{pa-ra-me-ter}
+
+\emergencystretch=4mm
+\title{An extension of \TeX's hyphenation algorithm}
+\author{Matthias Clasen}
+%\address{}
+\netaddress{maclas@gmx.de}
+\setcounter{page}{1}
+
+\begin{document}
+\maketitle
+\MakeShortVerb{\|}
+
+\section{Introduction}
+
+\TeX{}'s hyphenation algorithm works quite well and has been adapted for
+a large number of languages. But there are a few shortcomings, which have
+been noticed long ago \cite{Mittelbach:90,MR:92}:
+\begin{itemize}
+\item
+ While \TeX{} has provisions to deal with general discretionaries like
+ \textit{ck$\rightarrow$k-k}, there is no way to generate these automatically
+ in the same way as ordinary discretionaries. They have to be entered manually
+ using macros like |"ck| from |german.sty|.
+\item
+ \TeX{} has \cs{doublehyphendemerits} to discourage consecutive hyphenated
+ lines, but there is no provision to enforce a specification like ``no more
+ that three consecutive hyphenated lines''.
+\item
+ All breakpoints inserted by the hyphenation algorithm are treated the same,
+ although their quality might be quite different. Especially for languages
+ like German it would be nice to prefer breakpoints at word boundaries over
+ intra-word breakpoints.
+\end{itemize}
+
+I don't tackle the first problem, but I do propose a solution for the other
+problems in the sequel.
+
+\section{Extensions to \TeX{}}
+
+\subsection{Consecutive hyphens}
+\label{sec:linebreaking}
+
+\TeX's linebreaking algorithm does already keep track of the hyphenation
+status of the feasible line breaks. All one has to do to solve the second
+problem is to change this boolean parameter into an integer and accumulate
+the information for consecutive line breaks. This is not very difficult, since
+the data structures for line breaks (the |active_node| node type) has enough
+room for this information.
+
+Well, actually this is not quite true, since it fails to preserve the dynamic
+programming principle of optimality and thus might miss optimal solutions. To
+do it properly we have to maintain information about optimal solutions not
+only for each fitness class, but for each combination of fitness class and
+number of consecutive hyphens. This is what I have implemented.
+
+With this bookkeeping in place, it would in principle be possible to apply
+different demerits for arbitrary numbers of consecutive hyphens. I have
+implemented this only for three, four, and five lines since higher numbers are
+unlikely to be relevant in practice. The new demerits are made available as
+integer parameters
+\begin{quotation}
+ \cs{threehyphendemerits},\\
+ \cs{fourhyphendemerits},
+\end{quotation}
+and
+\begin{quotation}
+ \cs{fivehyphendemerits}.
+\end{quotation}
+
+\subsection{Hyphen classes}
+\label{sec:hyphenclasses}
+
+\TeX's hyphenation algorithm works by assigning numbers to inter-letter
+ positions in a word and reducing these numbers modulo~2 to obtain a binary
+ alternative (breakpoint or not). A natural extension of this algorithm would
+ be to reduce modulo~$n$ to obtain an $n$-ary alternative, e.\,g.\ the class
+ of the hyphen (where a higher class means a more acceptable breakpoint).
+
+ This of course implies that the patterns have to be generated with this in
+ mind, i.\,e.\ the number of hyphen classes becomes a parameter of the pattern
+ generation algorithm like \cs{lefthyphenmin} and \cs{righthyphenmin}. This
+ has been implemented in a change to \textsf{patgen} which enables
+ it to deal with up~to~10 hyphen classes and eject inter-letter
+ values of up~to~63. My preliminary tests seem to indicate that it is indeed
+ possible to generate useful patterns for more than one hyphen class, but more
+ extensive experiments are needed.
+
+ The extended \TeX{} knows the number of hyphen classes through the integer
+ parameter
+ \begin{quotation}
+ \cs{hyphenclasses}.
+ \end{quotation}
+ It is saved and restored like \cs{lefthyphenmin} and
+ \cs{righthyphenmin} when the language is changed in the middle of a
+ paragraph.
+
+ To make use of the hyphen classes, it is necessary to make \TeX{} charge
+ different penalties for them. To this end, the extended \TeX{} has the
+ integer parameters
+ \begin{quotation}
+ \cs{hyphenpenalties}\meta{hyphen class},\\
+ \null\qquad\qquad\qquad\qquad$(1\leq\meta{hyphen class}\leq 9)$.
+ \end{quotation}
+ The parameters \cs{hyphen\-penalty} and \cs{exhyphen\-penalty} are now
+ synonyms for \cs{hyphen\-penalties1} and \cs{hyphen\-penalties}\meta{n},
+ where \meta{n} is the value of the new integer parameter
+ \begin{quotation}
+ \cs{exhyphenclass}.
+ \end{quotation}
+ It determines the class to which the automatically inserted discretionaries
+ after~|-| and discretionaries with empty pre-break text generated by \cs{-}
+ or \cs{discretionary} belong (\cs{exhyphen\-class} may also be~0 to disable
+ breaking after~|-|).
+
+ Discretionaries of any class can be inserted with the help of the
+ new primitive
+ \begin{quotation}
+ \cs{gendiscretionary}\meta{hyphen class}.
+ \end{quotation}
+
+ If these extensions are enabled, the \TeX{} primitives \cs{patterns}
+ and \cs{hyphenation} accept slightly more general input: \cs{patterns}
+ accepts two-digit values up~to~63 between letters and \cs{hyphenation}
+ accepts one-digit hyphen classes after hyphens.
+
+\subsection{Enabling the extensions}
+
+ Following the model of \eTeX, the extensions described above are
+ protected by two integer parameters,
+ \begin{quotation}
+ \cs{hyphencountstate}
+ \end{quotation}
+ and
+ \begin{quotation}
+ \cs{hyphenclassesstate},
+ \end{quotation}
+ which must be set to a positive value to enable them. With both
+ state variables set to zero the extended \TeX{} still passes the trip test
+ (with small differences in memory usage caused by the different size of
+ discretionary nodes). In this mode, the primitives \cs{gendiscretionary} and
+ \cs{hyphenpenalties} are forbidden and the values of the integer parameters
+ \cs{exhyphenclass}, \cs{hyphen\-classes},
+ \cs{hyphen\-penalties3}, \dots, \cs{hyphen\-penalties9},
+ \cs{three\-hy\-phen\-demerits},
+ \dots, \cs{five\-hyphen\-demerits} are ignored.
+
+\section{Generating patterns}
+
+I have done some experiments to see if it is possible to generate
+patterns for more than one hyphen class. My test data was a list
+of approximately 25\,000 German words, many of them compound. I used
+\TeX's hyphenation to insert hyphens and flagged the inter-word hyphens
+manually as hyphen class~2. For the last experiment, I broke all compound
+words in their constituents.
+
+\medskip
+
+\hspace{-4cm}\hfill
+\begin{tabular}{cccccc}
+\toprule
+break points&\multicolumn{2}{c}{patterns}&good&bad&missed\\
+&kB&\#&\%&\%&\%\\
+\midrule
+all&65582&9271&99.02&0.10&0.98\\
+all in one class&32892&4970&99.98&0.01&0.02\\
+only inter-word&37407&5386&99.63&0.01&0.37\\
+only intra-word&14653&2226&99.70&0.04&0.30\\
+\bottomrule
+\end{tabular}
+
+\medskip
+
+Note that in the first experiment, hyphens of class~1 which are inserted
+where a hyphen of class~2 was wanted do count as bad. The percentage
+of \emph{really} bad (i.\,e.\ too permissive) hyphens is much smaller.
+
+It's not too surprising that the patterns for two hyphen classes are bigger
+than the patterns for one hyphen class, since they contain more information.
+
+The results of the third and fourth experiment might encourage a different
+approach to the problem of weighting breaks: Replace the current hyphenation
+algorithm by two passes of the same algorithm, where the first pass would use
+special patterns to find word boundaries and the second would find breakpoints
+in the broken words. This would fit nicely with \TeX's three line-breaking
+passes. The first pass would be done as always before any hyphenation. The
+second try would be done after the insertion of inter-word breaks. Only the
+last pass would make use of intra-word breaks.
+
+But I haven't tried this yet.
+
+\section{Implementation}
+
+The changes to \TeX{} the program and \textsf{patgen} sketched above are
+realized as a series of change files.
+
+\begin{itemize}
+\item |classes.ch|
+ extends \TeX's hyphenation routines to deal with hyphens of up to~9 different
+ classes. It implements the new control sequences described in
+ section~\ref{sec:hyphenclasses}.
+\item |count.ch|
+ extends \TeX's line breaking routines to deal with sequences of breakpoints
+ containing more than two consecutive hyphens. It implements the new control
+ sequences described in section~\ref{sec:linebreaking}.
+\item |patgen-classes.ch|
+ extends \textsf{patgen}s pattern generation algorithm to deal with up~to~10
+ different hyphen classes. The new algorithm has one new integer parameter, the
+ number of hyphen classes (between 2 and~10). This parameter can be specified
+ in columns 8 and~9 of the first line of the translate file. \textsf{patgen}
+ will now produce values up~to~63.
+\end{itemize}
+
+\section{Installation}
+
+ The change files are written for \TeX~3.1459 and \textsf{patgen}~2.3. But
+ it should need only cosmetic changes to make them work with other
+ versions of \TeX3 or \textsf{patgen}2.
+
+ First, you have to apply the change file
+ |pre.ch|. The |count.ch| and |classes.ch| change files should be
+ independent of each other. I have only tried these files with |web2c|, and
+ for that you need to surround the |web2c| change file with |pre-web2c.ch| and
+ |post-web2c.ch|. All this boils down to the command line
+
+\begin{verbatim}
+mv tex.ch tex.ch.orig
+tie -c tex.ch tex.web pre.ch classes.ch \
+ count.ch pre-web2c.ch tex.ch.orig \
+ post-web2c.ch
+\end{verbatim}
+
+ \makesignature
+
+ \bibliographystyle{plain}
+ \bibliography{etex}
+
+\end{document}
+
+
+
diff --git a/systems/tex-extensions/clasen/hyphenation/patgen-hyf.ch b/systems/tex-extensions/clasen/hyphenation/patgen-hyf.ch
new file mode 100644
index 0000000000..db2fb9c460
--- /dev/null
+++ b/systems/tex-extensions/clasen/hyphenation/patgen-hyf.ch
@@ -0,0 +1,460 @@
+% This change extends patgens pattern generation algorithm to deal with up to
+% 10 different hyphen classes. The new algorithm has one new integer
+% parameter, the number of hyphen classes (between 2 and 10). This parameter
+% can be specified in columns 8 and 9 of the first line of the translate
+% file. patgen will now produce values up to 63.
+
+@x l.54
+@d banner=='This is PATGEN, Version 2.3' {printed when the program starts}
+@y
+@d banner=='This is PATGEN, Version 2.3 (with multiple hyphen classes)'
+ {printed when the program starts}
+@z
+
+@x l.588
+@!max_val=10; {maximum number of levels$+1$, also used to denote bad patterns}
+@y
+@!max_val=64; {maximum number of levels$+1$, also used to denote bad patterns}
+@z
+
+@x l.603
+if max_val>10 then bad:=5;
+@y
+if max_val>100 then bad:=5;
+@z
+
+@x l.1107
+print_ln('left_hyphen_min = ',left_hyphen_min:1,
+ ', right_hyphen_min = ',right_hyphen_min:1,
+ ', ',imax-edge_of_word:1,' letters');
+@y
+print_ln('left_hyphen_min = ',left_hyphen_min:1,
+ ', right_hyphen_min = ',right_hyphen_min:1,
+ ', hyphen_class_num = ',hyphen_class_num:1,
+ ', ',imax-edge_of_word:1,' letters');
+@z
+
+@x l.1113
+@ @<Globals...@>=
+@!imax: internal_code; {largest |internal_code| assigned so far}
+@!left_hyphen_min, @!right_hyphen_min: dot_type;
+
+@ @<Set up default...@>=
+begin left_hyphen_min:=2; right_hyphen_min:=3;
+@y
+
+@ @d hyphen_class(#)==(# mod hyphen_class_num)
+
+@<Globals...@>=
+@!imax: internal_code; {largest |internal_code| assigned so far}
+@!left_hyphen_min, @!right_hyphen_min: dot_type;
+@!hyphen_class_num: 2..10; { allow up to 10 hyphen classes, default is 2 }
+
+@ @<Set up default...@>=
+begin left_hyphen_min:=2; right_hyphen_min:=3;
+hyphen_class_num:=2;
+@z
+
+@x
+If the values specified for \.{\\lefthyphenmin} and \.{\\righthyphenmin}
+are invalid (e.g., blank) new values are read from the terminal.
+@y
+Another addition is, that columns 8 and~9 may optionally contain a value for
+\.{\\hyphenclassnum}.
+
+If the values specified for \.{\\lefthyphenmin}, \.{\\righthyphenmin} and
+\.{\\hyphenclassnum} are invalid (e.g., blank) new values are read from the
+terminal.
+@z
+@x l.1148
+if (n>=1)and(n<max_dot) then right_hyphen_min:=n@+
+else bad:=true;
+@y
+if (n>=1)and(n<max_dot) then right_hyphen_min:=n@+
+else bad:=true;
+if buf[8]=' ' then n:=0
+else if xclass[buf[8]]=digit_class then n:=xint[buf[8]]@+
+else bad:=true;
+if xclass[buf[9]]=digit_class then n:=10*n+xint[buf[9]]@+
+else bad:=true;
+if (n>=2)and(n<=10) then hyphen_class_num:=n@+
+else bad:=true;
+@z
+
+@x l.1358
+@!more_to_come: boolean;
+@y
+@!more_to_come: boolean;
+@!off_count: array [1..9] of integer;
+ { off by $<-3$, $-3$, $-2$, $-1$, $0$, $1$, $2$, $3$, $>3$ }
+@z
+
+@x l.1480
+@ @<Output this pattern@>=
+begin for d:=0 to pat_len do hval[d]:=0;
+ repeat d:=hyf_dot(h);
+ if hval[d]<hyf_val(h) then hval[d]:=hyf_val(h);
+ h:=hyf_nxt(h);
+ until h=0;
+ if hval[0]>0 then write(patout,xdig[hval[0]]);
+ for d:=1 to pat_len do
+ begin write_letter(pat[d])(patout); write(patout,xext[pat[d]]);
+ if hval[d]>0 then write(patout,xdig[hval[d]]);
+ end;
+ write_ln(patout);
+end
+@y
+@ Since we have increased |max_val|, we must allow for two-digit values
+in patterns.
+
+@<Output this pattern@>=
+begin for d:=0 to pat_len do hval[d]:=0;
+ repeat d:=hyf_dot(h);
+ if hval[d]<hyf_val(h) then hval[d]:=hyf_val(h);
+ h:=hyf_nxt(h);
+ until h=0;
+ if hval[0]>9 then write(patout,xdig[hval[0] div 10]);
+ if hval[0]>0 then write(patout,xdig[hval[0] mod 10]);
+ for d:=1 to pat_len do
+ begin write_letter(pat[d])(patout); write(patout,xext[pat[d]]);
+ if hval[d]>9 then write(patout,xdig[hval[d] div 10]);
+ if hval[d]>0 then write(patout,xdig[hval[d] mod 10]);
+ end;
+ write_ln(patout);
+end
+@z
+
+@x l.1502
+@!dots: array[word_index] of hyf_type; {current hyphens}
+@y
+@!hclass: array[word_index] of digit; {current wanted hyphen classes}
+@z
+
+@x
+applied to all following words (until the next global word weight). A
+digit at some intercharacter position indicates a weight for that position
+only.
+
+The |read_word| procedure scans a line of input representing a word,
+and places the letters into the array |word|, with |word[1]=word[wlen]=
+edge_of_word|. The dot appearing between |word[dpos]| and |word[dpos+1]|
+is placed in |dots[dpos]|, and the corresponding dot weight in
+|dotw[dpos]|.
+@y
+applied to all following words (until the next global word weight). A
+digit at the beginning of some intercharacter position indicates a weight for
+that position only. A digit at the end of some intercharacter position
+indicates the hyphen class for the hyphen wanted at this position.
+
+The |read_word| procedure scans a line of input representing a word,
+and places the letters into the array |word|, with |word[1]=word[wlen]=
+edge_of_word|. The class of the hyphen appearing between |word[dpos]| and
+|word[dpos+1]| is placed in |hclass[dpos]|, and the corresponding dot weight in
+|dotw[dpos]|.
+@z
+
+@x l.1537
+@p procedure read_word;
+label done, found;
+var c: text_char;
+@!t: trie_pointer;
+begin read_buf(dictionary);
+word[1]:=edge_of_word; wlen:=1; buf_ptr:=0;
+repeat incr(buf_ptr); c:=buf[buf_ptr];
+ case xclass[c] of
+ space_class: goto found;
+ digit_class:
+ if wlen=1 then {global word weight}
+ begin if xint[c]<>word_wt then wt_chg:=true;
+ word_wt:=xint[c];
+ end
+ else dotw[wlen]:=xint[c]; {dot weight}
+ hyf_class: dots[wlen]:=xint[c]; {record the dot |c|}
+ letter_class: {record the letter |c|}
+ begin incr(wlen);
+ if wlen=max_len then
+ begin print_buf; overflow('word length=',max_len:1);
+ end;
+ word[wlen]:=xint[c]; dots[wlen]:=no_hyf; dotw[wlen]:=word_wt;
+ end;
+ escape_class: {record a multi-character sequence starting with |c|}
+ begin incr(wlen);
+ if wlen=max_len then
+ begin print_buf; overflow('word length=',max_len:1);
+ end;
+ get_letter(word[wlen]); dots[wlen]:=no_hyf; dotw[wlen]:=word_wt;
+ end;
+ invalid_class: bad_input('Bad character');
+@.Bad character@>
+ end;
+until buf_ptr=max_buf_len;
+found: incr(wlen); word[wlen]:=edge_of_word;
+end;
+@y
+@p procedure read_word;
+label done, found;
+var c: text_char;
+i: word_index;
+@!t: trie_pointer;
+begin read_buf(dictionary);
+word[1]:=edge_of_word; wlen:=1; buf_ptr:=0;
+for i:=0 to max_len do hclass[i]:=0;
+repeat incr(buf_ptr); c:=buf[buf_ptr];
+ case xclass[c] of
+ space_class: goto found;
+ digit_class:
+ if wlen=1 then {global word weight}
+ begin if xint[c]<>word_wt then wt_chg:=true;
+ word_wt:=xint[c];
+ end
+ else if hclass[wlen]>0 then begin
+ if hyphen_class_num>xint[c] then hclass[wlen]:=xint[c]
+ else error('unexpected hyphen class!');
+ end else dotw[wlen]:=xint[c]; {dot weight}
+ hyf_class:
+ begin
+ hclass[wlen]:=1;
+ end;
+ letter_class: {record the letter |c|}
+ begin
+ incr(wlen);
+ if wlen=max_len then
+ begin print_buf; overflow('word length=',max_len:1);
+ end;
+ word[wlen]:=xint[c]; hclass[wlen]:=0; dotw[wlen]:=word_wt;
+ end;
+ escape_class: {record a multi-character sequence starting with |c|}
+ begin incr(wlen);
+ if wlen=max_len then
+ begin print_buf; overflow('word length=',max_len:1);
+ end;
+ get_letter(word[wlen]); dotw[wlen]:=word_wt;
+ end;
+ invalid_class: bad_input('Bad character');
+@.Bad character@>
+ end;
+until buf_ptr=max_buf_len;
+found: incr(wlen); word[wlen]:=edge_of_word;
+end;
+@z
+
+@x l.1628
+@ The |change_dots| procedure updates the |dots| array representing the
+printing values of the hyphens. Initially, hyphens (and correctly
+found hyphens) in the word list are represented by |is_hyf| whereas
+non-hyphen positions (and erroneous hyphens) are represented by |no_hyf|. A
+Here these values are increased by one for each hyphen found by the
+current patterns, thus changing |no_hyf| into |err_hyf| and |is_hyf|
+into |found_hyf|. The routine also collects statistics about the number
+of good, bad, and missed hyphens.
+
+@d incr_wt(#)==Incr(#)(dotw[dpos])
+
+@p procedure change_dots;
+var dpos: word_index;
+begin for dpos:=wlen-hyf_max downto hyf_min do
+ begin if odd(hval[dpos]) then incr(dots[dpos]);
+ if dots[dpos]=found_hyf then incr_wt(good_count)
+ else if dots[dpos]=err_hyf then incr_wt(bad_count)
+ else if dots[dpos]=is_hyf then incr_wt(miss_count);
+ end;
+end;
+@y
+@ The |change_dots| procedure owes its name to the fact that its job was
+once to update an array called |dots| representing the printing values of the
+hyphens. This is no longer the case, as |dots| is gone.
+
+The routine collects statistics about the number of good, bad, and missed hyphens.
+
+@d incr_wt(#)==Incr(#)(dotw[dpos])
+
+@p procedure change_dots;
+var dpos: word_index;
+ have: integer;
+begin for dpos:=wlen-hyf_max downto hyf_min do
+ begin
+ have:=hyphen_class(hval[dpos]);
+ {good/bad/miss statistics}
+ if have>0 then
+ if have=hclass[dpos] then incr_wt(good_count)
+ else incr_wt(bad_count)
+ else if hclass[dpos]>0 then incr_wt(miss_count);
+ {off statistics}
+ if have+hclass[dpos]>0 then
+ if abs(have-hclass[dpos])<=3 then
+ incr_wt(off_count[have-hclass[dpos]+5])
+ else if have<hclass[dpos] then
+ incr_wt(off_count[1])
+ else incr_wt(off_count[9])
+ end;
+end;
+@z
+
+@x l.1653
+@ The following procedure outputs the word as hyphenated by the current
+patterns, including any word weights. Hyphens inhibited by the values of
+\.{\\lefthyphenmin} and \.{\\righthyphenmin} are output as well.
+
+@p procedure output_hyphenated_word;
+var dpos: word_index;@/
+@!l: triec_pointer; {for |write_letter|}
+begin if wt_chg then {output global word weight}
+ begin write(pattmp,xdig[word_wt]); wt_chg:=false
+ end;
+for dpos:=2 to wlen-2 do
+ begin write_letter(word[dpos])(pattmp); write(pattmp,xext[word[dpos]]);
+ if dots[dpos]<>no_hyf then write(pattmp,xhyf[dots[dpos]]);
+ if dotw[dpos]<>word_wt then write(pattmp,xdig[dotw[dpos]]);
+ end;
+write_letter(word[wlen-1])(pattmp); write_ln(pattmp,xext[word[wlen-1]]);
+end;
+@y
+@ The following procedure outputs the word as hyphenated by the current
+patterns, including the found hyphen classes. A correct hyphen is shown with
+|found_hyf|, an incorrect one with |err_hyf|. Hyphens inhibited by the values of
+\.{\\lefthyphenmin} and \.{\\righthyphenmin} are {\it not} shown.
+
+@p procedure output_hyphenated_word;
+var dpos: word_index;@/
+@!l: triec_pointer; {for |write_letter|}
+begin
+ for dpos:=2 to hyf_min-1 do begin
+ write_letter(word[dpos])(pattmp);
+ write(pattmp,xext[word[dpos]]);
+ end;
+ for dpos:=hyf_min to wlen-hyf_max do begin
+ write_letter(word[dpos])(pattmp);
+ write(pattmp,xext[word[dpos]]);
+ if hyphen_class(hval[dpos])>0 then begin
+ if hyphen_class(hval[dpos])=hclass[dpos] then write(pattmp,xhyf[found_hyf])
+ else write(pattmp,xhyf[err_hyf]);
+ if hyphen_class(hval[dpos])>1 then
+ write(pattmp,xdig[hyphen_class(hval[dpos])]);
+ end;
+ end;
+ for dpos:=wlen-hyf_max+1 to wlen-1 do begin
+ write_letter(word[dpos])(pattmp);
+ write(pattmp,xext[word[dpos]]);
+ end;
+ write_ln(pattmp,'');
+end;
+@z
+
+@x l.1702
+@ The globals |good_dot| and |bad_dot| will be set to |is_hyf| and
+|no_hyf|, or |err_hyf| and |found_hyf|, depending on whether the current
+level is odd or even, respectively. The globals |dot_min|, |dot_max|,
+and |dot_len| are analogous to |hyf_min|, |hyf_max|, and |hyf_len|
+defined earlier.
+
+@<Globals...@>=
+@!good_dot, @!bad_dot: hyf_type; {good and bad hyphens at current level}
+@!dot_min, @!dot_max, @!dot_len: word_index; {limits for legal dots}
+
+@ @<Prepare to read dictionary@>=
+if procesp then
+ begin dot_min:=pat_dot; dot_max:=pat_len-pat_dot;
+ if dot_min<hyf_min then dot_min:=hyf_min;
+ if dot_max<hyf_max then dot_max:=hyf_max;
+ dot_len:=dot_min+dot_max;
+ if odd(hyph_level) then
+ begin good_dot:=is_hyf; bad_dot:=no_hyf;
+ end
+ else begin good_dot:=err_hyf; bad_dot:=found_hyf;
+ end;
+ end;
+@y
+@ The globals |dot_min|, |dot_max|, and |dot_len| are analogous to |hyf_min|,
+|hyf_max|, and |hyf_len| defined earlier.
+
+@<Globals...@>=
+@!dot_min, @!dot_max, @!dot_len: word_index; {limits for legal dots}
+
+@ @<Prepare to read dictionary@>=
+if procesp then
+ begin dot_min:=pat_dot; dot_max:=pat_len-pat_dot;
+ if dot_min<hyf_min then dot_min:=hyf_min;
+ if dot_max<hyf_max then dot_max:=hyf_max;
+ dot_len:=dot_min+dot_max;
+ end;
+@z
+
+@x
+ @!goodp: boolean;
+@y
+ @!goodp: boolean;
+ have,get: integer;
+@z
+
+@x l.1729
+@<Check this dot position...@>=
+if no_more[dpos] then goto continue;
+if dots[dpos]=good_dot then goodp:=true else
+if dots[dpos]=bad_dot then goodp:=false else goto continue;
+@y
+@<Check this dot position...@>=
+if no_more[dpos] then goto continue;
+have:=hyphen_class(hval[dpos]);
+get:=hyphen_class(hyph_level);
+if abs(get-hclass[dpos])<abs(have-hclass[dpos]) then goodp:=true
+else if abs(get-hclass[dpos])>abs(have-hclass[dpos]) then goodp:=false
+else goto continue;
+@z
+
+@x l.1750
+@p procedure do_dictionary;
+begin good_count:=0; bad_count:=0; miss_count:=0;
+@y
+@p procedure do_dictionary;
+var i: integer;
+begin
+ for i:=1 to 9 do begin
+ off_count[i]:=0;
+ end;
+ good_count:=0; bad_count:=0; miss_count:=0;
+@z
+
+@x l.1771
+ if (good_count+miss_count)>0 then
+ print_ln((100*good_count/(good_count+miss_count)):1:2,' %, ',
+ (100*bad_count/(good_count+miss_count)):1:2,' %, ',
+ (100*miss_count/(good_count+miss_count)):1:2,' %');
+@y
+ if (good_count+miss_count)>0 then
+ print_ln((100*good_count/(good_count+miss_count)):1:2,' %, ',
+ (100*bad_count/(good_count+miss_count)):1:2,' %, ',
+ (100*miss_count/(good_count+miss_count)):1:2,' %');
+ print_ln('off by <-3, -3,...: ',
+ off_count[1]:1, ', ',
+ off_count[2]:1, ', ',
+ off_count[3]:1, ', ',
+ off_count[4]:1, ', ',
+ off_count[5]:1, ', ',
+ off_count[6]:1, ', ',
+ off_count[7]:1, ', ',
+ off_count[8]:1, ', ',
+ off_count[9]:1);
+@z
+
+@x l.1835
+ digit_class:
+ begin d:=xint[c];
+ if d>=max_val then bad_input('Bad hyphenation value');
+@.Bad hyphenation value@>
+ if d>max_pat then max_pat:=d;
+ hval[pat_len]:=d;
+ end;
+@y
+ digit_class:
+ begin d:=xint[c];
+ if xclass[buf[buf_ptr+1]]=digit_class then begin
+ incr(buf_ptr);
+ c:=buf[buf_ptr];
+ d:=10*d+xint[c];
+ end;
+ if d>=max_val then bad_input('Bad hyphenation value');
+@.Bad hyphenation value@>
+ if d>max_pat then max_pat:=d;
+ hval[pat_len]:=d;
+ end;
+@z
diff --git a/systems/tex-extensions/clasen/hz/etex.bib b/systems/tex-extensions/clasen/hz/etex.bib
new file mode 120000
index 0000000000..59519b0c14
--- /dev/null
+++ b/systems/tex-extensions/clasen/hz/etex.bib
@@ -0,0 +1 @@
+../etex.bib \ No newline at end of file
diff --git a/systems/tex-extensions/clasen/hz/hz-glue.ch b/systems/tex-extensions/clasen/hz/hz-glue.ch
new file mode 100644
index 0000000000..e38a1f4572
--- /dev/null
+++ b/systems/tex-extensions/clasen/hz/hz-glue.ch
@@ -0,0 +1,26 @@
+@x
+@p function adjust_excess(p:pointer;r:real):scaled;
+@y
+@p function adjust_excess(p:pointer;r:glue_ratio):scaled;
+@z
+
+@x
+ d:=abs(v+char_width(f)(i)-r*w);
+@y
+ d:=abs(v+char_width(f)(i)-glue_mult(r,w));
+@z
+
+@x
+ dd:=abs(v+char_width(ff)(ii)-r*w);
+@y
+ dd:=abs(v+char_width(ff)(ii)-glue_mult(r,w));
+@z
+
+@x
+ x:=x-adjust_excess(link(q),(gw+x)/gw);
+@y
+ { |adjust_excess| tries to make up the excess~|x| by stretching the glyphs
+ by the factor |gw+x/gw| (represented as a |glue_ratio| value). }
+ x:=x-adjust_excess(link(q),glue_fix(gw,gw+x,gw));
+@z
+
diff --git a/systems/tex-extensions/clasen/hz/hz-post-web2c.ch b/systems/tex-extensions/clasen/hz/hz-post-web2c.ch
new file mode 100644
index 0000000000..f6c17e3af6
--- /dev/null
+++ b/systems/tex-extensions/clasen/hz/hz-post-web2c.ch
@@ -0,0 +1,76 @@
+%
+% This is web2c-specific.
+%
+
+@x
+@!font_variants:array[internal_font_number] of min_halfword..max_halfword;
+@y
+@!font_variants:^pointer;
+@z
+
+%
+% web2c moves the initialization to somewhere else.
+%
+
+@x
+font_variants[null_font]:=null;
+@y
+@z
+
+%
+% We must dump the font_variants table as well.
+%
+
+@x
+dump_things(font_glue[null_font], font_ptr+1-null_font);
+@y
+dump_things(font_glue[null_font], font_ptr+1-null_font);
+dump_things(font_variants[null_font], font_ptr+1-null_font);
+@z
+
+%
+% This is web2c-specific.
+%
+
+@x
+xmalloc_array(param_base, font_max);
+@y
+xmalloc_array(param_base, font_max);
+xmalloc_array(font_variants, font_max);
+@z
+
+%
+% We must undump the font_variants table as well.
+%
+
+@x
+undump_checked_things(min_halfword, lo_mem_max,
+ font_glue[null_font], font_ptr+1-null_font);
+@y
+undump_checked_things(min_halfword, lo_mem_max,
+ font_glue[null_font], font_ptr+1-null_font);
+undump_things(font_variants[null_font], font_ptr+1-null_font);
+@z
+
+%
+% This is web2c-specific.
+%
+
+@x
+ xmalloc_array(param_base, font_max);
+@y
+ xmalloc_array(param_base, font_max);
+ xmalloc_array(font_variants, font_max);
+@z
+
+%
+% web2c moves the initialization to somewhere else.
+%
+
+@x
+ param_base[null_font]:=-1;
+@y
+ param_base[null_font]:=-1;
+ font_variants[null_font]:=null;
+@z
+
diff --git a/systems/tex-extensions/clasen/hz/hz.ch b/systems/tex-extensions/clasen/hz/hz.ch
new file mode 100644
index 0000000000..b2b2d9f6f5
--- /dev/null
+++ b/systems/tex-extensions/clasen/hz/hz.ch
@@ -0,0 +1,465 @@
+@x
+{hz int_pars go here}
+@y
+@d hz_state_code=80
+@z
+
+@x
+@d error_context_lines==int_par(error_context_lines_code)
+@y
+@d hz_state==int_par(hz_state_code)
+@d hz_en==(hz_state>0)
+@d error_context_lines==int_par(error_context_lines_code)
+@z
+
+@x
+error_context_lines_code:print_esc("errorcontextlines");
+@y
+error_context_lines_code:print_esc("errorcontextlines");
+hz_state_code:print_esc("hzstate");
+@z
+
+@x
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+@y
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+primitive("hzstate",assign_int,int_base+hz_state_code);@/
+@!@:hz_state_}{\.{\\hzstate} primitive@>
+@z
+
+@x
+escape_char:="\"; end_line_char:=carriage_return;
+@y
+escape_char:="\"; end_line_char:=carriage_return;
+hz_state:=0;
+@z
+
+@x
+primitive("font",def_font,0);@/
+@!@:font_}{\.{\\font} primitive@>
+@y
+primitive("font",def_font,0);@/
+@!@:font_}{\.{\\font} primitive@>
+primitive("fontvariant",def_font,1);@/
+@!@:fontvariant_}{\.{\\fontvariant} primitive@>
+@z
+
+@x
+def_font: print_esc("font");
+@y
+def_font: if chr_code=0 then print_esc("font") else print_esc("fontvariant");
+@z
+
+@x l.8326
+@p procedure scan_something_internal(@!level:small_number;@!negative:boolean);
+ {fetch an internal parameter}
+var m:halfword; {|chr_code| part of the operand token}
+@y
+@p procedure scan_something_internal(@!level:small_number;@!negative:boolean);
+ {fetch an internal parameter}
+var m:halfword; {|chr_code| part of the operand token}
+r:pointer; {used with font variants}
+@z
+
+@x l.8379
+else begin back_input; scan_font_ident;
+ scanned_result(font_id_base+cur_val)(ident_val);
+ end
+@y
+else begin
+ if m=0 then begin
+ back_input; scan_font_ident;
+ scanned_result(font_id_base+cur_val)(ident_val);
+ end else if hz_en then begin
+ scan_font_ident;
+ r:=font_variants[cur_val]; cur_val:=0;
+ while r<>null do begin
+ incr(cur_val); r:=link(r);
+ end;
+ scanned_result(cur_val)(int_val);
+ end else begin
+ print_err("Improper "); print_cmd_chr(def_font,m);
+ error;
+ end;
+end
+@z
+
+@x l.10710
+@!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
+@y
+@!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
+@!font_variants:array[internal_font_number] of min_halfword..max_halfword;
+@z
+
+@x l.10762
+for k:=0 to 6 do font_info[k].sc:=0;
+@y
+for k:=0 to 6 do font_info[k].sc:=0;
+font_variants[null_font]:=null;
+@z
+
+@x l.11189
+fmem_ptr:=fmem_ptr+lf; font_ptr:=f; g:=f; goto done
+@y
+fmem_ptr:=fmem_ptr+lf; font_ptr:=f; g:=f;
+for a:=0 to 255 do begin
+ qw:=char_info(f)(a);
+ if char_exists(qw) then begin
+ font_variants[f]:=get_avail;
+ font(font_variants[f]):=f;
+ character(font_variants[f]):=a;
+ link(font_variants[f]):=null;
+ goto done;
+ end;
+end;
+goto done;
+@z
+
+@x l.12860
+@ Here now is |hpack|, which contains few if any surprises.
+
+@p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
+label reswitch, common_ending, exit;
+var r:pointer; {the box node that will be returned}
+@!q:pointer; {trails behind |p|}
+@!h,@!d,@!x:scaled; {height, depth, and natural width}
+@y
+@ This routine replaces characters in the hlist |p| with variants from other
+fonts in order to stretch the natural width by |r|. It returns the amount by
+which the natural width could be stretched.
+
+@p function adjust_excess(p:pointer;r:real):scaled;
+label reswitch,found,done;
+var v,w,d,dd:scaled;
+f,ff,c:eight_bits;
+i,ii:four_quarters;
+s:pointer;
+j:integer;
+begin
+@!debug
+print("(adjust_excess: "); print_scaled(round(unity*r));
+print(" --> ");
+gubed
+v:=0; w:=0;
+while p<>null do begin
+ reswitch: while is_char_node(p) do begin
+ c:=character(p); f:=font(p); i:=char_info(f)(c);
+ w:=w+char_width(f)(i);
+ s:=font_variants[f];
+ f:=font(s); i:=char_info(f)(c);
+ d:=abs(v+char_width(f)(i)-r*w);
+ s:=link(s);
+@!debug
+ j:=0;
+gubed
+ while s<>null do begin
+ ff:=font(s); ii:=char_info(ff)(c);
+ dd:=abs(v+char_width(ff)(ii)-r*w);
+ if dd>=d then goto found;
+ d:=dd; f:=ff; i:=ii;
+@!debug
+ j:=j+1;
+gubed
+ s:=link(s);
+ end;
+ found:
+ font(p):=f;
+@!debug
+ print_int(j);
+gubed
+ v:=v+char_width(f)(i);
+ p:=link(p);
+ end;
+ if p=null then goto done;
+ if type(p)=ligature_node then
+ @<Make node |p| look like a |char_node| and |goto reswitch|@>
+ else p:=link(p);
+end;
+done:
+@!debug
+print_ln;
+print(" got "); print_scaled(v-w); print(")");
+gubed
+adjust_excess:=v-w;
+end;
+
+@ Here now is |hpack|, which contains few if any surprises.
+
+@p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
+label reswitch, common_ending, exit;
+var r:pointer; {the box node that will be returned}
+@!q:pointer; {trails behind |p|}
+@!h,@!d,@!x:scaled; {height, depth, and natural width}
+@!gw:scaled; {natural width coming from glyphs}
+@z
+
+@x
+h:=0; @<Clear dimensions to zero@>;
+@y
+h:=0; gw:=0; @<Clear dimensions to zero@>;
+@z
+
+@x
+@<Incorporate character dimensions into the dimensions of the hbox...@>=
+begin f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i);
+x:=x+char_width(f)(i);@/
+@y
+@<Incorporate character dimensions into the dimensions of the hbox...@>=
+begin f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i);
+x:=x+char_width(f)(i);@/
+gw:=gw+char_width(f)(i);
+@z
+
+@x
+else if x>0 then @<Determine horizontal glue stretch setting, then |return|
+ or \hbox{|goto common_ending|}@>
+else @<Determine horizontal glue shrink setting, then |return|
+ or \hbox{|goto common_ending|}@>
+@y
+else begin
+ if hz_en then begin
+ if gw<>0 then begin
+ x:=x-adjust_excess(link(q),(gw+x)/gw);
+ end;
+ end;
+ if x>0 then @<Determine horizontal glue stretch setting, then |return|
+ or \hbox{|goto common_ending|}@>
+ else @<Determine horizontal glue shrink setting, then |return|
+ or \hbox{|goto common_ending|}@>;
+end
+@z
+
+@x
+@d delta_node_size=7 {number of words in a delta node}
+@d delta_node=2 {|type| field in a delta node}
+@y
+@d delta_node_size=9 {number of words in a delta node}
+@d delta_node=2 {|type| field in a delta node}
+@z
+
+@x
+@d do_all_six(#)==#(1);#(2);#(3);#(4);#(5);#(6)
+
+@<Glo...@>=
+@!active_width:array[1..6] of scaled;
+ {distance from first active node to~|cur_p|}
+@!cur_active_width:array[1..6] of scaled; {distance from current active node}
+@!background:array[1..6] of scaled; {length of an ``empty'' line}
+@!break_width:array[1..6] of scaled; {length being computed after current break}
+@y
+For the hz algorithm, we add two more fields to store the finite
+stretch and shrink from glyphs.
+
+@d do_all_six(#)==#(1);#(2);#(3);#(4);#(5);#(6)
+@d do_all_eight(#)==do_all_six(#);#(7);#(8)
+
+@<Glo...@>=
+@!active_width:array[1..8] of scaled;
+ {distance from first active node to~|cur_p|}
+@!cur_active_width:array[1..8] of scaled; {distance from current active node}
+@!background:array[1..8] of scaled; {length of an ``empty'' line}
+@!break_width:array[1..8] of scaled; {length being computed after current break}
+@z
+
+@x
+background[6]:=shrink(q)+shrink(r);
+@y
+background[6]:=shrink(q)+shrink(r);
+background[7]:=0; background[8]:=0;
+@z
+
+@x
+do_all_six(copy_to_cur_active);
+@y
+do_all_eight(copy_to_cur_active);
+@z
+
+@x
+ begin do_all_six(update_width);
+@y
+ begin do_all_eight(update_width);
+@z
+
+@x
+begin no_break_yet:=false; do_all_six(set_break_width_to_background);
+@y
+begin no_break_yet:=false; do_all_eight(set_break_width_to_background);
+@z
+
+@x
+ begin do_all_six(convert_to_break_width);
+@y
+ begin do_all_eight(convert_to_break_width);
+@z
+
+@x
+ begin do_all_six(store_break_width);
+@y
+ begin do_all_eight(store_break_width);
+@z
+
+@x
+ do_all_six(new_delta_to_break_width);
+@y
+ do_all_eight(new_delta_to_break_width);
+@z
+
+@x
+ do_all_six(new_delta_from_break_width);
+@y
+ do_all_eight(new_delta_from_break_width);
+@z
+
+@x
+shortfall:=line_width-cur_active_width[1]; {we're this much too short}
+@y
+if hz_en then begin
+ if cur_active_width[1]+cur_active_width[7]<line_width then
+ shortfall:=line_width-(cur_active_width[1]+cur_active_width[7])
+ else if cur_active_width[1]-cur_active_width[8]>line_width then
+ shortfall:=line_width-(cur_active_width[1]-cur_active_width[8])
+ else shortfall:=0;
+end else shortfall:=line_width-cur_active_width[1]; {we're this much too short}
+@z
+
+@x
+ begin do_all_six(downdate_width);
+@y
+ begin do_all_eight(downdate_width);
+@z
+
+@x
+ begin do_all_six(update_width);
+ do_all_six(combine_two_deltas);
+@y
+ begin do_all_eight(update_width);
+ do_all_eight(combine_two_deltas);
+@z
+
+@x
+ begin do_all_six(update_active);
+ do_all_six(copy_to_cur_active);
+@y
+ begin do_all_eight(update_active);
+ do_all_eight(copy_to_cur_active);
+@z
+
+@x
+do_all_six(store_background);@/
+@y
+do_all_eight(store_background);@/
+@z
+
+@x
+begin prev_p:=cur_p;
+repeat f:=font(cur_p);
+act_width:=act_width+char_width(f)(char_info(f)(character(cur_p)));
+cur_p:=link(cur_p);
+until not is_char_node(cur_p);
+end
+@y
+begin prev_p:=cur_p;
+repeat f:=font(cur_p);
+w:=char_width(f)(char_info(f)(character(cur_p)));
+act_width:=act_width+w;
+if hz_en then @<Update stretch and shrink in the presence of font variants@>;
+cur_p:=link(cur_p);
+until not is_char_node(cur_p);
+end
+
+@ @<Local variables for line...@>=
+@!w:scaled; {used when calculating character widths}
+
+@ @<Update stretch and shrink...@>=
+begin
+r:=font_variants[f];
+active_width[7]:=active_width[7]+
+ char_width(font(r))(char_info(font(r))(character(cur_p)))-w;
+while link(r)<>null do r:=link(r);
+active_width[8]:=active_width[8]+
+ w-char_width(font(r))(char_info(font(r))(character(cur_p)));
+end
+@z
+
+@x
+def_font: new_font(a);
+@y
+def_font: if cur_chr=0 then new_font(a) else
+ if hz_en then font_variant(a)
+ else begin print_err("Improper "); print_cmd_chr(def_font,cur_chr); error; end;
+
+
+@ @<Declare subprocedures for |prefixed_command|@>=
+procedure font_variant(@!a:small_number);
+label found,done;
+var @!f,ff:internal_font_number;
+@!i:eight_bits;
+@!qw,qww:four_quarters;
+@!r,s,p: pointer;
+begin
+ scan_font_ident; f:=cur_val;
+ scan_optional_equals; scan_font_ident; ff:=cur_val;
+ @<If |ff| is |null_font|, reset the list of variants and goto |found|@>;
+ @<Check that |ff| is a valid variant of |f|, else goto |done|@>;
+ s:=null; r:=font_variants[f];
+ i:=character(r);
+ p:=new_character(ff,i);
+ qww:=char_info(ff)(i);
+ while r<>null do begin
+ if font(r)=ff then goto done;
+ qw:=char_info(font(r))(i);
+ if char_width(font(r))(qw)<char_width(ff)(qww) then goto found;
+ s:=r; r:=link(r);
+ end;
+found:
+ link(p):=r;
+ if s=null then font_variants[f]:=p
+ else link(s):=p;
+ done:
+@!debug
+ print("(fontvariants of ");
+ print(font_name[f]); print(": ");
+ r:=font_variants[f];
+ while r<>null do begin
+ print(font_name[font(r)]);
+ r:=link(r);
+ if r<>null then print(", ");
+ end;
+ print(")");
+gubed
+end;
+
+@ Fonts can only be variants of each other if they provide the
+same characters.
+
+@<Check that |ff| is a valid variant of |f|...@>=
+for i:=0 to 255 do begin
+ qw:=char_info(f)(i);
+ qww:=char_info(f)(i);
+ if (char_exists(qw) and not char_exists(qww)) or
+ (not char_exists(qw) and char_exists(qww)) then begin
+ print_err("Font "); print_esc(font_id_text(ff));
+ print(" is not a variant of font "); print_esc(font_id_text(f));
+@.Font x is not a...@>
+ help2("Fonts can only be used as variants of each other")@/
+ ("if they contain the same characters.");
+ error;
+ goto done;
+ end;
+end
+
+@ The only way to remove variants of a font is to assign |null_font|
+as a variant.
+
+@<If |ff| is |null_font|...@>=
+if ff=null_font then begin
+ r:=null; s:=null; p:=new_character(f,character(font_variants[f]));
+ flush_node_list(font_variants[f]);
+ goto found;
+end
+@z
+
diff --git a/systems/tex-extensions/clasen/hz/hz.tex b/systems/tex-extensions/clasen/hz/hz.tex
new file mode 100644
index 0000000000..3ff4432261
--- /dev/null
+++ b/systems/tex-extensions/clasen/hz/hz.tex
@@ -0,0 +1,104 @@
+\documentclass[preprint]{ltugboat}
+\usepackage{shortvrb}
+\usepackage{url}
+
+\providecommand{\meta}[1]{\ensuremath{\langle\textit{#1}\rangle}}
+\makeatletter
+\providecommand{\eTeX}{$\m@th\varepsilon$-\TeX}
+\makeatother
+\hyphenation{pa-ra-me-ter}
+
+\emergencystretch=4mm
+\overfullrule=0pt
+\title{Why \TeX\ can't set the Gutenberg bible}
+\author{Matthias Clasen}
+%\address{}
+\netaddress{maclas@gmx.de}
+\setcounter{page}{1}
+
+\begin{document}
+\maketitle
+\MakeShortVerb{\|}
+
+\section{Introduction}
+
+\TeX's paragraph breaking algorithm is one of its virtues. It usually
+achieves a fairly uniform grey value throughout the page. If it can't achieve
+completely uniform spacing, the excess space is distributed among the
+interword spaces in the line.
+
+Thus \TeX\ doesn't use one technique for uniform spacing which was invented
+as far back as Gutenberg: variation of the letter width to make up excess
+space.
+
+I propose a minimalist extension of \TeX\ to enable it to use letters of
+variable width. The extension is to associate \textit{variants} with
+fonts. If \TeX\ is about to set character~|c| from font~|f|, it looks for
+character~|c| in all variants associated with~|f| and chooses the one
+which ``fits best in the current situation''. I.\,e.\ in a tight line,
+a narrow variant will be chosen, while a wide variant would be preferable
+in a loose line. The variability of the character width also influences the
+calculation of the badness during the paragraph breaking. This is the true
+strength of the extension: like |\emergencystretch|, it adds flexibility
+during paragraph breaking and thus increases the number of feasible
+breakpoints, but without tearing ugly holes in the shape of the paragraph.
+
+I call this a minimalist extension, because it completely ignores the
+questions of suitable font technology for automatic generation of font
+variants from existing fonts. From the point of view taken here, font
+variants are just separate |tfm| files which are only required to contain
+characters in the same positions. Furthermore \TeX\ assumes that the
+widths vary consistently between the variants, i.\,e.\ if variant~|f|
+contains \emph{one} character which is wider than the corresponding
+character in variant~|f'|, then \emph{all} characters from~|f| should
+be at least as wide as their counterparts in~|f'|.
+
+\section{Implementation}
+
+The changes to \TeX{} the program sketched above are realized in the
+change file |hz.ch|. It implements the new primitive
+\[\cs{fontvariant}\meta{font$_1$}=\meta{font$_2$}\]
+which declares \meta{font$_2$} to be a variant of \meta{font$_1$}
+(where \meta{font$_1$} and \meta{font$_2$} must be font identifiers).
+Font variants can only be removed \textit{en bloc}, by using
+|\nullfont| as \meta{font$_2$}.
+
+\TeX\ will use the fontvariants and allow the |\fontvariant| primitive only
+when the new integer parameter |\hzstate| has a positive value. Setting
+|\hzstate| to zero does \emph{not} remove the font variants previously
+declared.
+
+\TeX\ uses the font variants only when it looks for the width of a character.
+All other |tfm| informations, in particular kerning and ligaturing, are always
+taken from the base font.
+
+\section{Installation}
+
+ The change files are written for \TeX~3.1459. But it should need only
+ cosmetic changes to get them to work with other versions of \TeX3.
+
+ To make the change files for \TeX{} work, you have to apply the change file
+ |pre.ch| first. I have only tried these files with |web2c|, and
+ for that you need to surround the |web2c| change file with |pre-web2c.ch| and
+ |post-web2c.ch|. You also need the additional change file
+ |hz-post-web2c.ch|. If you want to use this change together with the
+ change for fixed-point arithmetic (|glue.ch|), then you also need
+ the file |hz-glue.ch|.
+
+ All this boils down to the command line
+
+\begin{verbatim}
+mv tex.ch tex.ch.orig
+tie -c tex.ch tex.web pre.ch hz.ch \
+ hz-glue.ch pre-web2c.ch \
+ tex.ch.orig post-web2c.ch \
+ hz-post-web2c.ch
+\end{verbatim}
+
+ \makesignature
+
+ \bibliographystyle{plain}
+ \bibliography{etex}
+
+\end{document}
+
diff --git a/systems/tex-extensions/clasen/margin/etex.bib b/systems/tex-extensions/clasen/margin/etex.bib
new file mode 120000
index 0000000000..59519b0c14
--- /dev/null
+++ b/systems/tex-extensions/clasen/margin/etex.bib
@@ -0,0 +1 @@
+../etex.bib \ No newline at end of file
diff --git a/systems/tex-extensions/clasen/margin/margin-post-web2c.ch b/systems/tex-extensions/clasen/margin/margin-post-web2c.ch
new file mode 100644
index 0000000000..2329dae6fb
--- /dev/null
+++ b/systems/tex-extensions/clasen/margin/margin-post-web2c.ch
@@ -0,0 +1,45 @@
+@x
+@!margin_char:array[internal_font_number] of integer;
+@y
+@!margin_char:^integer;
+@z
+
+@x
+margin_char[null_font]:=-1;
+@y
+@z
+
+@x
+dump_things(skew_char[null_font], font_ptr+1-null_font);
+@y
+dump_things(skew_char[null_font], font_ptr+1-null_font);
+dump_things(margin_char[null_font], font_ptr+1-null_font);
+@z
+
+@x
+xmalloc_array(skew_char, font_max);
+@y
+xmalloc_array(skew_char, font_max);
+xmalloc_array(margin_char, font_max);
+@z
+
+@x
+undump_things(skew_char[null_font], font_ptr+1-null_font);
+@y
+undump_things(skew_char[null_font], font_ptr+1-null_font);
+undump_things(margin_char[null_font], font_ptr+1-null_font);
+@z
+
+@x
+ xmalloc_array(skew_char, font_max);
+@y
+ xmalloc_array(skew_char, font_max);
+ xmalloc_array(margin_char, font_max);
+@z
+
+@x
+ hyphen_char[null_font]:="-"; skew_char[null_font]:=-1;
+@y
+ hyphen_char[null_font]:="-"; skew_char[null_font]:=-1;
+ margin_char[null_font]:=-1;
+@z \ No newline at end of file
diff --git a/systems/tex-extensions/clasen/margin/margin.ch b/systems/tex-extensions/clasen/margin/margin.ch
new file mode 100644
index 0000000000..d8666a73da
--- /dev/null
+++ b/systems/tex-extensions/clasen/margin/margin.ch
@@ -0,0 +1,341 @@
+@x
+{margin int_pars go here}
+@y
+@d default_margin_char_code=81
+@z
+
+@x
+@d error_context_lines==int_par(error_context_lines_code)
+@y
+@d error_context_lines==int_par(error_context_lines_code)
+@d default_margin_char==int_par(default_margin_char_code)
+@z
+
+@x
+error_context_lines_code:print_esc("errorcontextlines");
+@y
+error_context_lines_code:print_esc("errorcontextlines");
+default_margin_char_code:print_esc("defaultmarginchar");
+@z
+
+@x
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+@y
+primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+@!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
+primitive("defaultmarginchar",assign_int,int_base+default_margin_char_code);@/
+@!@:default_margin_char_}{\.{\\defaultmarginchar} primitive@>
+@z
+
+@x
+@!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
+@y
+@!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
+@!margin_char:array[internal_font_number] of integer;
+ {current \.{\\marginchar} values}
+@z
+
+@x
+for k:=0 to 6 do font_info[k].sc:=0;
+@y
+for k:=0 to 6 do font_info[k].sc:=0;
+margin_char[null_font]:=-1;
+@z
+
+@x
+hyphen_char[f]:=default_hyphen_char; skew_char[f]:=default_skew_char;
+@y
+hyphen_char[f]:=default_hyphen_char; skew_char[f]:=default_skew_char;
+margin_char[f]:=default_margin_char;
+@z
+
+@x
+@d copy_to_cur_active(#)==cur_active_width[#]:=active_width[#]
+@d deactivate=60 {go here when node |r| should be deactivated}
+
+@<Declare subprocedures for |line_break|@>=
+@y
+The function |kerning| returns the kerning between the characters
+|cl| and |cr| in font |f|, or zero if there is none.
+
+@d copy_to_cur_active(#)==cur_active_width[#]:=active_width[#]
+@d deactivate=60 {go here when node |r| should be deactivated}
+
+@<Declare subprocedures for |line_break|@>=
+function kerning(f,cl,cr:eight_bits):scaled;
+label done;
+var s:scaled;
+i:four_quarters;
+a:integer;
+begin
+ s:=0;
+ i:=char_info(f)(cl);
+ if char_tag(i)=lig_tag then begin
+ a:=lig_kern_start(f)(i);
+ i:=font_info[a].qqqq;
+ if skip_byte(i)>stop_flag then begin
+ a:=lig_kern_restart(f)(i);
+ i:=font_info[a].qqqq;
+ end;
+ loop@+ begin
+ if next_char(i)=cr then begin
+ if op_byte(i)>=kern_flag then
+ if skip_byte(i)<=stop_flag then s:=char_kern(f)(i);
+ goto done;
+ end;
+ if skip_byte(i)>=stop_flag then goto done;
+ a:=a+qo(skip_byte(i))+1;
+ i:=font_info[a].qqqq;
+ end;
+ end;
+done: kerning:=s;
+end;
+
+@ The function |margin_correction| expects an active node |r| and
+a |cur_p| pointing directly into the horizontal list with the tentative
+line to be broken extending from |r| to |cur_p|.
+
+It returns the sum of the margin corrections for the line between them. It
+does so by finding the first node in the line, skipping everything that would
+be dropped after a break (including a possible |\parindent| box), and
+calculating the kern between the |marginchar| and it. Similarly, the last node
+of the line is used to find the kern between it and the |marginchar|. This
+routine could be made more efficient by avoiding the list traversal. The main
+loop of |try_break| could remember the last node before |cur_p|.
+
+@<Declare subprocedures for |line_break|@>=
+function margin_correction(r,cur_p:pointer):scaled;
+label done;
+var left_kern,right_kern:scaled;
+ sl,s:pointer;
+ f,c:eight_bits;
+ ii:four_quarters;
+ rc,a:integer;
+begin
+ left_kern:=0;
+ right_kern:=0;
+ if break_node(r)=null then begin
+ sl:=temp_head;
+ if (type(link(sl))=hlist_node)and
+ (list_ptr(link(sl))=null) then begin
+ sl:=link(sl); { skip |\parindent| box }
+ end;
+ end else sl:=cur_break(break_node(r));
+ s:=sl;
+ if type(s)=disc_node then begin
+ if post_break(s)<>null then s:=post_break(s)
+ else begin
+ rc:=replace_count(s);
+ s:=link(s);
+ while rc>0 do begin
+ if link(s)<>null then s:=link(s);
+ decr(rc);
+ end;
+ end;
+ end;
+ f:=null_font; c:=qi(0);
+ while s<>null do begin
+ if is_char_node(s) then begin
+ f:=font(s); c:=character(s);
+ s:=null;
+ end else case type(s) of
+ glue_node: s:=link(s);
+ penalty_node: s:=link(s);
+ ligature_node: begin
+ f:=font(lig_char(s));
+ c:=character(lig_char(s));
+ s:=null;
+ end;
+ math_node: s:=link(s);
+ kern_node: if subtype(s)<>explicit then s:=null else s:=link(s);
+ othercases s:=null;
+ endcases;@/
+ end;
+ { if we reach this point, |(f,c)| is the font-char pair starting the line }
+ if (0<=margin_char[f])and(margin_char[f]<=255) then begin
+ left_kern:=kerning(f,qi(margin_char[f]),c);
+ end;
+
+ s:=null;
+ if cur_p then
+ if type(cur_p)=disc_node then begin
+ if pre_break(cur_p)<>null then begin
+ s:=pre_break(cur_p);
+ while link(s)<>null do s:=link(s); { unnecessary list traversal! }
+ goto done;
+ end;
+ end;
+ s:=sl;
+ while link(s)<>cur_p do begin
+ s:=link(s);
+ if s=null then goto done;
+ end;
+done:
+ f:=null_font; c:=qi(0);
+ if s<>null then if is_char_node(s) then begin
+ f:=font(s); c:=character(s);
+ end else if type(s)=ligature_node then begin
+ f:=font(lig_char(s));
+ c:=character(lig_char(s));
+ end;
+ { if we reach this point, |(f,c)| is the font-char pair ending the line }
+ if (0<=margin_char[f])and(margin_char[f]<=255) then begin
+ right_kern:=kerning(f,c,qi(margin_char[f]));
+ end;
+ margin_correction:=left_kern+right_kern;
+end;
+@z
+
+@x
+@!line_width:scaled; {the current line will be justified to this width}
+@y
+@!line_width:scaled; {the current line will be justified to this width}
+@!local_line_width:scaled; {|line_width| including |marginchar| kerning}
+@z
+
+@x
+if hz_en then begin
+ if cur_active_width[1]+cur_active_width[7]<line_width then
+ shortfall:=line_width-(cur_active_width[1]+cur_active_width[7])
+ else if cur_active_width[1]-cur_active_width[8]>line_width then
+ shortfall:=line_width-(cur_active_width[1]-cur_active_width[8])
+ else shortfall:=0;
+end else shortfall:=line_width-cur_active_width[1]; {we're this much too short}
+@y
+local_line_width:=line_width-margin_correction(r,cur_p);
+if hz_en then begin
+ if cur_active_width[1]+cur_active_width[7]<local_line_width then
+ shortfall:=line_width-(cur_active_width[1]+cur_active_width[7])
+ else if cur_active_width[1]-cur_active_width[8]>local_line_width then
+ shortfall:=line_width-(cur_active_width[1]-cur_active_width[8])
+ else shortfall:=0;
+end else shortfall:=local_line_width-cur_active_width[1]; {we're this much too short}
+@z
+
+@x
+procedure post_line_break(@!final_widow_penalty:integer);
+label done,done1;
+var q,@!r,@!s:pointer; {temporary registers for list manipulation}
+@y
+procedure post_line_break(@!final_widow_penalty:integer);
+label done,done1,done2,done3;
+var q,@!r,@!s:pointer; {temporary registers for list manipulation}
+f,c:eight_bits;
+ss:scaled;
+@z
+
+@x
+@<Modify the end of the line to reflect the nature of the break and to include
+ \.{\\rightskip}; also set the proper value of |disc_break|@>;
+@<Put the \(l)\.{\\leftskip} glue at the left and detach this line@>;
+@y
+@<Modify the end of the line to reflect the nature of the break and to include
+ \.{\\rightskip}; also set the proper value of |disc_break|@>;
+@<Put the \(l)\.{\\leftskip} glue at the left and detach this line@>;
+@<Deal with the \.{\\marginchar} kerning@>;
+@z
+
+@x
+@<Put the \(l)\.{\\leftskip} glue at the left...@>=
+r:=link(q); link(q):=null; q:=link(temp_head); link(temp_head):=r;
+if left_skip<>zero_glue then
+ begin r:=new_param_glue(left_skip_code);
+ link(r):=q; q:=r;
+ end
+@y
+We change this code to always insert the \.{\\leftskip}.
+
+@<Put the \(l)\.{\\leftskip} glue at the left...@>=
+r:=link(q); link(q):=null; q:=link(temp_head); link(temp_head):=r;
+r:=new_param_glue(left_skip_code);
+link(r):=q; q:=r
+
+@ When we reach this code, |q| points to the line in question. The line starts
+with \.{\\leftskip} glue and ends with \.{\\rightskip} glue. If the first node
+after the |leftskip| is a character~|c| whose font has a |marginchar|~|m|, we
+insert the kerning |m|--|c| between the |leftskip| node and charnode~|c|.
+
+If the last node before the |rightskip is a character~|c'| whose font has a
+|marginchar|~|m'|, we insert the kerning |c'|--|m'| between charnode~|c'|
+and the |rightskip| node.
+
+@<Deal with the \.{\\marginchar} kerning@>=
+s:=q; r:=link(s);
+if cur_line=prev_graf+1 then begin {treat the first line specially}
+ if (type(r)=hlist_node)and(list_ptr(r)=null) then begin {skip |parindent| box}
+ s:=r; r:=link(s);
+ end;
+end;
+ss:=0;
+if is_char_node(r) then begin
+ f:=font(r); c:=character(r);
+end else if type(r)=ligature_node then begin
+ f:=font(lig_char(r)); c:=character(lig_char(r));
+end else goto done2;
+if (0<=margin_char[f])and(margin_char[f]<=255) then begin
+ ss:=kerning(f,qi(margin_char[f]),c);
+end;
+done2:
+if ss<>0 then begin
+ s:=new_kern(ss); link(q):=s; link(s):=r;
+ s:=link(q);
+end;
+while link(r)<>null do begin
+ s:=r; r:=link(r); { unnecessary list traversal! }
+end;
+ss:=0;
+if is_char_node(s) then begin
+ f:=font(s); c:=character(s);
+end else if type(s)=ligature_node then begin
+ f:=font(lig_char(s)); c:=character(lig_char(s));
+end else goto done3;
+if (0<=margin_char[f])and(margin_char[f]<=255) then begin
+ ss:=kerning(f,c,qi(margin_char[f]));
+end;
+done3:
+if ss<>0 then begin
+ link(s):=new_kern(ss);
+ link(link(s)):=r;
+end;
+@z
+
+@x
+assign_font_int: begin n:=cur_chr; scan_font_ident; f:=cur_val;
+ scan_optional_equals; scan_int;
+ if n=0 then hyphen_char[f]:=cur_val@+else skew_char[f]:=cur_val;
+ end;
+@y
+assign_font_int: begin n:=cur_chr; scan_font_ident; f:=cur_val;
+ scan_optional_equals; scan_int;
+ case n of
+ 0: hyphen_char[f]:=cur_val;
+ 1: skew_char[f]:=cur_val;
+ othercases margin_char[f]:=cur_val;
+ endcases;
+ end;
+@z
+
+@x
+primitive("skewchar",assign_font_int,1);
+@!@:skew_char_}{\.{\\skewchar} primitive@>
+@y
+primitive("skewchar",assign_font_int,1);
+@!@:skew_char_}{\.{\\skewchar} primitive@>
+primitive("marginchar",assign_font_int,2);
+@!@:margin_char_}{\.{\\marginchar} primitive@>
+@z
+
+@x
+assign_font_int: if chr_code=0 then print_esc("hyphenchar")
+ else print_esc("skewchar");
+@y
+assign_font_int: case chr_code of
+ 0: print_esc("hyphenchar");
+ 1: print_esc("skewchar");
+ othercases print_esc("marginchar");
+ endcases;
+@z
+
diff --git a/systems/tex-extensions/clasen/margin/margin.tex b/systems/tex-extensions/clasen/margin/margin.tex
new file mode 100644
index 0000000000..561ab8514f
--- /dev/null
+++ b/systems/tex-extensions/clasen/margin/margin.tex
@@ -0,0 +1,97 @@
+\documentclass[preprint]{ltugboat}
+\usepackage{shortvrb}
+\usepackage{url}
+
+\providecommand{\meta}[1]{\ensuremath{\langle\textit{#1}\rangle}}
+\makeatletter
+\providecommand{\eTeX}{$\m@th\varepsilon$-\TeX}
+\makeatother
+\hyphenation{pa-ra-me-ter}
+
+\emergencystretch=4mm
+\title{Hanging punctuation revisited}
+\author{Matthias Clasen}
+%\address{}
+\netaddress{maclas@gmx.de}
+\setcounter{page}{1}
+
+\begin{document}
+\maketitle
+\MakeShortVerb{\|}
+
+\section{Introduction}
+
+In appendix D of the \TeX book~\cite{Knuth:86}, Knuth discusses a way to
+implement hanging punctuation within \TeX. As noted by Frank
+Mittelbach~\cite{Mittelbach:90}, this solution \textit{make[s] the ligature
+ mechanism partly unusable, along with other side effects,}
+and thus a better solution is needed.
+
+Since the problem obviously depends on the shape of the letters, it seems
+natural to attack it at the font level. The basic idea is to associate
+a |\marginchar| with each font. The kerning with the |\marginchar| (at the
+appropriate side) is used to determine how far the first/last character on
+a line should drop in the margin. This information is used in the calculation
+of the length (and badness) of a ``candidate line'' during paragraph breaking.
+
+Every font in \TeX\ has an associated |\margin|\-|char| parameter (analogous
+to |\hyphenchar| and |\skewchar|) whose initial value is the value of
+|\default|\-|margin|\-|char|. The |tfm| file doesn't have to know anything
+about |\marginchar|s, it just has to contain appropriate kern values. It is
+perfectly possible to have more than one |\marginchar| in a |tfm| file,
+e.\,g.\ for
+\begin{itemize}
+\item hanging punctuation,
+\item hanging hyphenation,
+\item optically correct margins,
+\item various combinations thereof.
+\end{itemize}
+
+Imagine the |\marginchar| as a zero-width character which is automatically
+inserted at the beginning and end of every line. It is fixed at the margin,
+thus kerning against it will drag the first or last character in the margin.
+This is of course a gross simplification of the actual algorithm which is
+complicated by the need to deal properly with |\parindent| boxes, hanging
+indentation, |\right-| and |\leftskip|s, discretionaries, and breakpoints which
+are not taken.
+
+
+\section{Implementation}
+
+The changes to \TeX{} the program sketched above are realized in the
+change file |margin.ch|. The implementation is highly inefficient:
+Lists are traversed more often than necessary and results are not cached. But
+this implementation was possible without figuring out in detail how
+|break_width| and |cur_active_width| have to be changed to incorporate
+the |\marginchar| kerning. This is what eventually should be done.
+
+\section{Installation}
+
+ The change files are written for \TeX~3.1459. But it should need only
+ cosmetic changes to get them to work with other versions of \TeX3.
+
+ To make the change files for \TeX{} work, you have to apply the change file
+ |pre.ch| first. I have only tried these files with |web2c|, and
+ for that you need to surround the |web2c| change file with |pre-web2c.ch| and
+ |post-web2c.ch|. You also need the additional change file
+ |margin-post-web2c.ch|. In the present form, |margin.ch| can only be
+ applied \emph{after} the changes for variable letter width in |hz.ch|.
+
+ All this boils down to the command line
+
+\begin{verbatim}
+mv tex.ch tex.ch.orig
+tie -c tex.ch tex.web pre.ch hz.ch \
+ margin.ch pre-web2c.ch \
+ tex.ch.orig post-web2c.ch \
+ hz-post-web2c.ch \
+ margin-post-web2c.ch
+\end{verbatim}
+
+ \makesignature
+
+ \bibliographystyle{plain}
+ \bibliography{etex}
+
+\end{document}
+
diff --git a/systems/tex-extensions/clasen/math/accent.ch b/systems/tex-extensions/clasen/math/accent.ch
new file mode 100644
index 0000000000..be9ba91347
--- /dev/null
+++ b/systems/tex-extensions/clasen/math/accent.ch
@@ -0,0 +1,251 @@
+@x
+@d normal=0 {the most common case when several cases are named}
+@y
+@d normal=0 {the most common case when several cases are named}
+@d under_accent=2 {|subtype| of under math accents}
+@d nesting=1 {add this to an accent |subtype| to make it nesting}
+@z
+
+@x
+primitive("mathaccent",math_accent,0);@/
+@!@:math_accent_}{\.{\\mathaccent} primitive@>
+@y
+primitive("mathaccent",math_accent,normal);@/
+@!@:math_accent_}{\.{\\mathaccent} primitive@>
+primitive("nestingmathaccent",math_accent,normal+nesting);@/
+@!@:nesting_math_accent_}{\.{\\nestingmathaccent} primitive@>
+primitive("mathunderaccent",math_accent,under_accent);@/
+@!@:math_under_accent_}{\.{\\mathunderaccent} primitive@>
+primitive("nestingmathunderaccent",math_accent,under_accent+nesting);@/
+@!@:nesting_math_under_accent_}{\.{\\nestingmathunderaccent} primitive@>
+@z
+
+@x
+math_accent: print_esc("mathaccent");
+@y
+math_accent: case chr_code of
+ normal: print_esc("mathaccent");
+ normal+nesting: print_esc("nestingmathaccent");
+ under_accent: print_esc("mathunderaccent");
+ under_accent+nesting:print_esc("nestingmathunderaccent");
+ othercases print("Unknown accent!")
+endcases;
+@z
+
+@x
+accent_noad: make_math_accent(q);
+@y
+accent_noad: if subtype(q)<under_accent then make_math_accent(q)
+ else make_math_under_accent(q);
+@z
+
+@x
+procedure make_math_accent(@!q:pointer);
+label done,done1;
+var p,@!x,@!y:pointer; {temporary registers for box construction}
+@y
+procedure horizontally_stack_into_box(@!b:pointer;@!f:internal_font_number;@!c:quarterword);
+var p:pointer; {new node placed into |b|}
+begin
+ p:=char_box(f,c); link(p):=list_ptr(b); list_ptr(b):=p;
+ width(b):=width(b)+width(p);
+end;
+
+procedure make_math_under_accent(@!q:pointer);
+label done,done1,done2,done3;
+var p,qq,@!x,@!y:pointer; {temporary registers for box construction}
+@!a:integer; {address of lig/kern instruction}
+@!c:quarterword; {accent character}
+@!f:internal_font_number; {its font}
+@!i,ii:four_quarters; {its |char_info|}
+@!s:scaled; {amount to skew the accent to the right}
+@!h:scaled; {height of character being accented}
+@!delta,sep:scaled; {space to insert between accentee and accent}
+@!w,v,u:scaled; {width of the accentee, not including sub/superscripts}
+@!t:four_quarters;
+@!m,n:integer;
+@!hd:eight_bits;
+begin fetch(accent_chr(q));
+if char_exists(cur_i) then
+ begin i:=cur_i; c:=cur_c; f:=cur_f;@/
+ @<Compute under accent skew@>;
+ @<Compute separation for under accent@>;
+ x:=clean_box(nucleus(q),cur_style); w:=width(x); h:=height(x);
+ @<Switch to a larger accent if available and appropriate@>;
+ if (math_type(supscr(q))<>empty)or(math_type(subscr(q))<>empty) then
+ if math_type(nucleus(q))=math_char then
+ @<Swap the subscript and superscript into box |x|@>;
+ shift_amount(y):=half(w-width(y))-s; width(y):=0;
+ p:=new_kern(sep); link(x):=p; link(p):=y;
+ p:=new_kern(-sep-x_height(f)); link(y):=p;
+ y:=vpack(x,natural); width(y):=w;
+ depth(y):=depth(y)+height(y)-h; height(y):=h;
+ info(nucleus(q)):=y; math_type(nucleus(q)):=sub_box;
+ end;
+end;
+
+procedure make_math_accent(@!q:pointer);
+label done,done1,done2;
+var p,qq,@!x,@!y:pointer; {temporary registers for box construction}
+@z
+
+@x
+@!w:scaled; {width of the accentee, not including sub/superscripts}
+@y
+@!w,v,u:scaled; {width of the accentee, not including sub/superscripts}
+@!t:four_quarters;
+@!m,n:integer;
+@!hd:eight_bits;
+@z
+
+@x
+ y:=char_box(f,c);
+@y
+@z
+
+@x
+@ @<Switch to a larger accent if available and appropriate@>=
+loop@+ begin if char_tag(i)<>list_tag then goto done;
+ y:=rem_byte(i);
+ i:=char_info(f)(y);
+ if not char_exists(i) then goto done;
+ if char_width(f)(i)>w then goto done;
+ c:=y;
+ end;
+done:
+@y
+@ @<Switch to a larger accent if available and appropriate@>=
+loop@+ begin
+ if char_tag(i)=ext_tag then begin
+ y:=new_null_box;
+ type(y):=hlist_node;
+ i:=font_info[exten_base[f]+rem_byte(i)].qqqq;@/
+ c:=ext_rep(i); t:=char_info(f)(c); u:=char_width(f)(t); v:=0;
+ hd:=height_depth(t); height(y):=char_height(f)(hd); depth(y):=char_depth(f)(hd);
+ c:=ext_bot(i); t:=char_info(f)(c); @+if c<>min_quarterword then v:=v+char_width(f)(t);
+ c:=ext_mid(i); t:=char_info(f)(c); @+if c<>min_quarterword then v:=v+char_width(f)(t);
+ c:=ext_top(i); t:=char_info(f)(c); @+if c<>min_quarterword then v:=v+char_width(f)(t);
+ n:=0;
+ if u>0 then while v<w do begin
+ v:=v+u; incr(n);
+ if ext_mid(i)<>min_quarterword then v:=v+u;
+ end;
+ c:=ext_bot(i);
+ if c<>min_quarterword then horizontally_stack_into_box(y,f,c);
+ c:=ext_rep(i);
+ for m:=1 to n do horizontally_stack_into_box(y,f,c);
+ c:=ext_mid(i);
+ if c<>min_quarterword then begin
+ horizontally_stack_into_box(y,f,c);
+ c:=ext_rep(i);
+ for m:=1 to n do horizontally_stack_into_box(y,f,c);
+ end;
+ c:=ext_top(i);
+ if c<>min_quarterword then horizontally_stack_into_box(y,f,c);
+ goto done2;
+ end;
+ if char_tag(i)<>list_tag then goto done;
+ y:=rem_byte(i);
+ i:=char_info(f)(y);
+ if not char_exists(i) then goto done;
+ if char_width(f)(i)>w then goto done;
+ c:=y;
+end;
+done:
+ y:=char_box(f,c);
+done2:
+@z
+
+%
+% Here is the logic for finding the accentee:
+% We pass by accent_noads as long as they are of the opposite kind
+% or of same kind and also nesting. This logic is necessary to make
+% \Hat{\uhat{\hat A}} align the two hats properly.
+
+@x
+@ @<Compute the amount of skew@>=
+s:=0;
+if math_type(nucleus(q))=math_char then
+ begin fetch(nucleus(q));
+@y
+@ @<Compute under accent skew@>=
+s:=0;
+qq:=q;
+if odd(subtype(q)) then
+ while (math_type(nucleus(qq))=sub_mlist)and
+ (type(info(nucleus(qq)))=accent_noad)and
+ ((subtype(qq)=subtype(q))or(subtype(qq) div 2<>subtype(q) div 2)) do
+ qq:=info(nucleus(qq));
+if math_type(nucleus(qq))=math_char then
+ begin fetch(nucleus(qq));
+ ii:=char_info(cur_f)(skew_char[cur_f]);
+ if char_tag(ii)=lig_tag then
+ begin a:=lig_kern_start(cur_f)(ii);
+ ii:=font_info[a].qqqq;
+ if skip_byte(ii)>stop_flag then
+ begin a:=lig_kern_restart(cur_f)(ii);
+ ii:=font_info[a].qqqq;
+ end;
+ loop@+ begin if qo(next_char(ii))=cur_c then
+ begin if op_byte(ii)>=kern_flag then
+ if skip_byte(ii)<=stop_flag then s:=char_kern(cur_f)(ii);
+ goto done1;
+ end;
+ if skip_byte(ii)>=stop_flag then goto done1;
+ a:=a+qo(skip_byte(ii))+1;
+ ii:=font_info[a].qqqq;
+ end;
+ end;
+ end;
+done1:
+
+@ @<Compute separation for under accent@>=
+ sep:=0;
+ ii:=i;
+ if char_tag(ii)=lig_tag then
+ begin a:=lig_kern_start(f)(ii);
+ ii:=font_info[a].qqqq;
+ if skip_byte(ii)>stop_flag then
+ begin a:=lig_kern_restart(f)(ii);
+ ii:=font_info[a].qqqq;
+ end;
+ loop@+ begin if qo(next_char(ii))=c then
+ begin if op_byte(ii)>=kern_flag then
+ if skip_byte(ii)<=stop_flag then sep:=char_kern(f)(ii);
+ goto done3;
+ end;
+ if skip_byte(ii)>=stop_flag then goto done3;
+ a:=a+qo(skip_byte(ii))+1;
+ ii:=font_info[a].qqqq;
+ end;
+ end;
+done3:
+
+@ @<Compute the amount of skew@>=
+s:=0;
+qq:=q;
+{while odd(subtype(qq))and(math_type(nucleus(qq))=sub_mlist)and
+ (type(info(nucleus(qq)))=accent_noad) do}
+if odd(subtype(q)) then
+ while (math_type(nucleus(qq))=sub_mlist)and
+ (type(info(nucleus(qq)))=accent_noad)and
+ ((subtype(qq)=subtype(q))or(subtype(qq) div 2<>subtype(q) div 2)) do
+ qq:=info(nucleus(qq));
+if math_type(nucleus(qq))=math_char then
+ begin fetch(nucleus(qq));
+@z
+
+@x
+procedure math_ac;
+begin if cur_cmd=accent then
+ @<Complain that the user should have said \.{\\mathaccent}@>;
+tail_append(get_node(accent_noad_size));
+type(tail):=accent_noad; subtype(tail):=normal;
+@y
+procedure math_ac;
+begin if cur_cmd=accent then
+ @<Complain that the user should have said \.{\\mathaccent}@>;
+tail_append(get_node(accent_noad_size));
+type(tail):=accent_noad; subtype(tail):=cur_chr;
+@z
+
diff --git a/systems/tex-extensions/clasen/math/cramp.ch b/systems/tex-extensions/clasen/math/cramp.ch
new file mode 100644
index 0000000000..57231a383f
--- /dev/null
+++ b/systems/tex-extensions/clasen/math/cramp.ch
@@ -0,0 +1,48 @@
+@x
+begin case c div 2 of
+0: print_esc("displaystyle"); {|display_style=0|}
+1: print_esc("textstyle"); {|text_style=2|}
+2: print_esc("scriptstyle"); {|script_style=4|}
+3: print_esc("scriptscriptstyle"); {|script_script_style=6|}
+othercases print("Unknown style!")
+@y
+begin case c of
+display_style: print_esc("displaystyle");
+display_style+cramped: print_esc("crampeddisplaystyle");
+text_style: print_esc("textstyle");
+text_style+cramped: print_esc("crampedtextstyle");
+script_style: print_esc("scriptstyle");
+script_style+cramped: print_esc("crampedscriptstyle");
+script_script_style: print_esc("scriptscriptstyle");
+script_script_style+cramped: print_esc("crampedscriptscriptstyle");
+othercases print("Unknown style!")
+@z
+@x
+primitive("displaystyle",math_style,display_style);
+@!@:display_style_}{\.{\\displaystyle} primitive@>
+primitive("textstyle",math_style,text_style);
+@!@:text_style_}{\.{\\textstyle} primitive@>
+primitive("scriptstyle",math_style,script_style);
+@!@:script_style_}{\.{\\scriptstyle} primitive@>
+primitive("scriptscriptstyle",math_style,script_script_style);
+@!@:script_script_style_}{\.{\\scriptscriptstyle} primitive@>
+@y
+primitive("displaystyle",math_style,display_style);
+@!@:display_style_}{\.{\\displaystyle} primitive@>
+primitive("crampeddisplaystyle",math_style,display_style+cramped);
+@!@:cramped_display_style_}{\.{\\crampeddisplaystyle} primitive@>
+primitive("textstyle",math_style,text_style);
+@!@:text_style_}{\.{\\textstyle} primitive@>
+primitive("crampedtextstyle",math_style,text_style+cramped);
+@!@:cramped_text_style_}{\.{\\crampedtextstyle} primitive@>
+primitive("scriptstyle",math_style,script_style);
+@!@:script_style_}{\.{\\scriptstyle} primitive@>
+primitive("crampedscriptstyle",math_style,script_style+cramped);
+@!@:cramped_script_style_}{\.{\\crampedscriptstyle} primitive@>
+primitive("scriptscriptstyle",math_style,script_script_style);
+@!@:script_script_style_}{\.{\\scriptscriptstyle} primitive@>
+primitive("crampedscriptscriptstyle",math_style,script_script_style+cramped);
+@!@:cramped_script_script_style_}{\.{\\crampedscriptscriptstyle} primitive@>
+@z
+
+
diff --git a/systems/tex-extensions/clasen/math/fraction.ch b/systems/tex-extensions/clasen/math/fraction.ch
new file mode 100644
index 0000000000..ab27046166
--- /dev/null
+++ b/systems/tex-extensions/clasen/math/fraction.ch
@@ -0,0 +1,355 @@
+% idea: keep track of math style in integer parameter
+% \mathstyle *while scanning the formula*. To be able
+% to do this, we need to keep track of
+%
+% \overline
+% ^
+% _
+% \mathaccent
+% style atoms
+% \fraction{...\over...}
+%
+% Change necessary: \mathstyle is *not* an ordinary
+% integer parameter, since math style doesn't obey
+% grouping. Try ${\scriptscriptstyle 1}2$.
+% Therefore it should be a special readonly parameter and
+% a \cramp primitive should be separately added.
+
+@x l.8392
+@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
+@d badness_code=glue_val+2 {code for \.{\\badness}}
+@y
+@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
+@d badness_code=glue_val+2 {code for \.{\\badness}}
+@d math_style_code=glue_val+3 {code for \.{\\mathstyle}}
+@z
+
+@x l.8420
+primitive("badness",last_item,badness_code);
+@!@:badness_}{\.{\\badness} primitive@>
+@y
+primitive("badness",last_item,badness_code);
+@!@:badness_}{\.{\\badness} primitive@>
+primitive("mathstyle",last_item,math_style_code);
+@!@:mathstyle_}{\.{\\mathstyle} primitive@>
+@z
+
+@x l.8435
+ input_line_no_code: print_esc("inputlineno");
+ othercases print_esc("badness")
+@y
+ input_line_no_code: print_esc("inputlineno");
+ badness_code: print_esc("badness");
+ math_style_code: print_esc("mathstyle");
+ othercases confusion("last_item")
+@:this can't happen last_item}{\quad last_item@>
+@z
+
+%
+% \mathstyle returns -1 if used outside math mode.
+%
+
+@x l.8504
+if cur_chr>glue_val then
+ begin if cur_chr=input_line_no_code then cur_val:=line
+ else cur_val:=last_badness; {|cur_chr=badness_code|}
+ cur_val_level:=int_val;
+ end
+@y
+if cur_chr>glue_val then
+ begin if cur_chr=input_line_no_code then cur_val:=line
+ else if cur_chr=math_style_code then begin
+ if abs(mode)=mmode then cur_val:=mathstyle
+ else cur_val:=-1;
+ end else cur_val:=last_badness;
+ cur_val_level:=int_val;
+ end
+@z
+
+@x l.14108
+@!cur_style:small_number; {style code at current place in the list}
+@y
+@!cur_style,mathstyle:small_number; {style code at current place in the list}
+@z
+
+@x l.21649
+begin push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1);
+if every_math<>null then begin_token_list(every_math,every_math_text);
+@y
+begin mathstyle:=text_style;
+push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1);
+if every_math<>null then begin_token_list(every_math,every_math_text);
+@z
+
+@x l.21700
+push_math(math_shift_group); mode:=mmode;
+eq_word_define(int_base+cur_fam_code,-1);@/
+@y
+mathstyle:=display_style;
+push_math(math_shift_group); mode:=mmode;
+eq_word_define(int_base+cur_fam_code,-1);@/
+@z
+
+@x l.21798
+mmode+left_brace: begin tail_append(new_noad);
+ back_input; scan_math(nucleus(tail));
+@y
+mmode+left_brace: begin tail_append(new_noad);
+ back_input; scan_math(nucleus(tail),mathstyle);
+@z
+
+%
+% we change scan_math to expect one additional parameter,
+% the mathstyle for the next math atom. There are two
+% cases here:
+% - simple atom: use local var stack to hold old style
+% and restore it from there
+% - subformula: use save stack to hold old style and
+% restore it when reading `}'
+%
+
+@x l.21810
+procedure scan_math(@!p:pointer);
+label restart,reswitch,exit;
+var c:integer; {math character code}
+begin restart:@<Get the next non-blank non-relax...@>;
+reswitch:case cur_cmd of
+letter,other_char,char_given: begin c:=ho(math_code(cur_chr));
+ if c=@'100000 then
+ begin @<Treat |cur_chr| as an active character@>;
+ goto restart;
+ end;
+ end;
+char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given;
+ goto reswitch;
+ end;
+math_char_num: begin scan_fifteen_bit_int; c:=cur_val;
+ end;
+math_given: c:=cur_chr;
+delim_num: begin scan_twenty_seven_bit_int; c:=cur_val div @'10000;
+ end;
+othercases @<Scan a subformula enclosed in braces and |return|@>
+endcases;@/
+math_type(p):=math_char; character(p):=qi(c mod 256);
+if (c>=var_code)and fam_in_range then fam(p):=cur_fam
+else fam(p):=(c div 256) mod 16;
+exit:end;
+@y
+procedure scan_math(@!p:pointer;s:small_number);
+label restart,reswitch,exit;
+var c:integer; {math character code}
+ savedstyle:small_number;
+begin
+savedstyle:=mathstyle; mathstyle:=s;
+restart:@<Get the next non-blank non-relax...@>;
+reswitch:case cur_cmd of
+letter,other_char,char_given: begin c:=ho(math_code(cur_chr));
+ if c=@'100000 then
+ begin @<Treat |cur_chr| as an active character@>;
+ goto restart;
+ end;
+ end;
+char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given;
+ goto reswitch;
+ end;
+math_char_num: begin scan_fifteen_bit_int; c:=cur_val;
+ end;
+math_given: c:=cur_chr;
+delim_num: begin scan_twenty_seven_bit_int; c:=cur_val div @'10000;
+ end;
+othercases @<Scan a subformula enclosed in braces and |return|@>
+endcases;@/
+math_type(p):=math_char; character(p):=qi(c mod 256);
+if (c>=var_code)and fam_in_range then fam(p):=cur_fam
+else fam(p):=(c div 256) mod 16;
+mathstyle:=savedstyle;
+exit:
+end;
+@z
+
+@x l.21848
+begin back_input; scan_left_brace;@/
+saved(0):=p; incr(save_ptr); push_math(math_group); return;
+@y
+begin back_input; scan_left_brace;@/
+saved(0):=p; incr(save_ptr); saved(0):=savedstyle; incr(save_ptr);
+push_math(math_group); return;
+@z
+
+@x l.21944
+mmode+math_comp: begin tail_append(new_noad);
+ type(tail):=cur_chr; scan_math(nucleus(tail));
+@y
+mmode+math_comp: begin tail_append(new_noad);
+ type(tail):=cur_chr;
+ case type(tail) of
+ over_noad: scan_math(nucleus(tail),cramped_style(mathstyle));
+ othercases scan_math(nucleus(tail),mathstyle);
+ endcases;
+@z
+
+%@x l.21999
+%scan_delimiter(left_delimiter(tail),true);
+%if t=1 then scan_delimiter(right_delimiter(tail),true)
+%else mem[right_delimiter(tail)].qqqq:=null_delimiter;
+%scan_math(nucleus(tail));
+%end;
+%@y
+%scan_delimiter(left_delimiter(tail),true);
+%if t=1 then scan_delimiter(right_delimiter(tail),true)
+%else mem[right_delimiter(tail)].qqqq:=null_delimiter;
+%scan_math(nucleus(tail),cramped_style(mathstyle));
+%end;
+%@z
+
+@x
+{before |scan_math| in |math_radical|}
+scan_math(nucleus(tail));
+@y
+{before |scan_math| in |math_radical|}
+scan_math(nucleus(tail),cramped_style(mathstyle));
+@z
+
+@x l.22012
+if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam
+else fam(accent_chr(tail)):=(cur_val div 256) mod 16;
+scan_math(nucleus(tail));
+end;
+@y
+if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam
+else fam(accent_chr(tail)):=(cur_val div 256) mod 16;
+scan_math(nucleus(tail),cramped_style(mathstyle));
+end;
+@z
+
+@x l.22066
+mmode+math_style: tail_append(new_style(cur_chr));
+@y
+mmode+math_style: begin tail_append(new_style(cur_chr));
+ mathstyle:=cur_chr;
+end;
+@z
+
+@x l.22076
+procedure append_choices;
+begin tail_append(new_choice); incr(save_ptr); saved(-1):=0;
+push_math(math_choice_group); scan_left_brace;
+@y
+procedure append_choices;
+begin tail_append(new_choice);
+incr(save_ptr); saved(-1):=mathstyle;
+incr(save_ptr); saved(-1):=0;
+push_math(math_choice_group); scan_left_brace;
+mathstyle:=display_style;
+@z
+
+@x l.22094
+3:begin script_script_mlist(tail):=p; decr(save_ptr); return;
+ end;
+end; {there are no other cases}
+incr(saved(-1)); push_math(math_choice_group); scan_left_brace;
+@y
+3:begin script_script_mlist(tail):=p; decr(save_ptr);
+ mathstyle:=saved(-1); decr(save_ptr);
+ return;
+ end;
+end; {there are no other cases}
+incr(saved(-1)); push_math(math_choice_group); scan_left_brace;
+mathstyle:=2*saved(-1);
+@z
+
+@x l.22109
+procedure sub_sup;
+var t:small_number; {type of previous sub/superscript}
+@!p:pointer; {field to be filled by |scan_math|}
+begin t:=empty; p:=null;
+if tail<>head then if scripts_allowed(tail) then
+ begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|}
+ t:=math_type(p);
+ end;
+if (p=null)or(t<>empty) then @<Insert a dummy noad to be sub/superscripted@>;
+scan_math(p);
+end;
+@y
+procedure sub_sup;
+var t:small_number; {type of previous sub/superscript}
+@!p:pointer; {field to be filled by |scan_math|}
+begin t:=empty; p:=null;
+if tail<>head then if scripts_allowed(tail) then
+ begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|}
+ t:=math_type(p);
+ end;
+if (p=null)or(t<>empty) then @<Insert a dummy noad to be sub/superscripted@>;
+if cur_cmd=sup_mark then scan_math(p,sup_style(mathstyle))
+else scan_math(p,sub_style(mathstyle));
+end;
+@z
+
+@x l.22149
+@d delimited_code=3 { `\.{\\abovewithdelims}', etc.}
+@y
+@d delimited_code=3 { `\.{\\abovewithdelims}', etc.}
+@d fraction_code=6 { `\.{\\fraction}', etc.}
+@z
+
+@x l.22162
+primitive("atopwithdelims",above,delimited_code+atop_code);
+@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@>
+@y
+primitive("atopwithdelims",above,delimited_code+atop_code);
+@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@>
+primitive("fraction",above,fraction_code);
+@!@:fraction_}{\.{\\fraction} primitive@>
+@z
+
+@x l.22171
+ delimited_code+atop_code:print_esc("atopwithdelims");
+ othercases print_esc("above")
+@y
+ delimited_code+atop_code:print_esc("atopwithdelims");
+ fraction_code:print_esc("fraction");
+ othercases print_esc("above")
+@z
+
+% We handle \fraction{...\over...} here, by scanning away
+% the left brace and then doing the same as for
+% mmode+left_brace
+% The point is that we have a handle to update the
+% math_style variable properly here.
+% We do scan_left_brace followed by back_input to
+% force the left brace to be there
+
+@x l.22176
+mmode+above: math_fraction;
+@y
+mmode+above: if cur_chr=fraction_code then begin
+ scan_left_brace; tail_append(new_noad);
+ back_input;
+ scan_math(nucleus(tail),num_style(mathstyle));
+end else begin
+ math_fraction;
+end;
+@z
+
+@x
+procedure math_fraction;
+var c:small_number; {the type of generalized fraction we are scanning}
+begin c:=cur_chr;
+@y
+procedure math_fraction;
+var c:small_number; {the type of generalized fraction we are scanning}
+begin c:=cur_chr;
+mathstyle:=denom_style(save_stack[cur_boundary-1].int);
+@z
+
+@x l.22258
+math_group: begin unsave; decr(save_ptr);@/
+ math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); info(saved(0)):=p;
+@y
+math_group: begin unsave; decr(save_ptr);@/
+ mathstyle:=saved(0); decr(save_ptr);
+ math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); info(saved(0)):=p;
+@z
+
+
+
diff --git a/systems/tex-extensions/clasen/math/math.ch b/systems/tex-extensions/clasen/math/math.ch
new file mode 100644
index 0000000000..2fbe62230e
--- /dev/null
+++ b/systems/tex-extensions/clasen/math/math.ch
@@ -0,0 +1,683 @@
+@x
+@d normal=0 {the most common case when several cases are named}
+@y
+@d normal=0 {the most common case when several cases are named}
+@d under_accent=2 {|subtype| of under math accents}
+@d nesting=1 {add this to an accent |subtype| to make it nesting}
+@z
+
+@x
+primitive("mathaccent",math_accent,0);@/
+@!@:math_accent_}{\.{\\mathaccent} primitive@>
+@y
+primitive("mathaccent",math_accent,normal);@/
+@!@:math_accent_}{\.{\\mathaccent} primitive@>
+primitive("nestingmathaccent",math_accent,normal+nesting);@/
+@!@:nesting_math_accent_}{\.{\\nestingmathaccent} primitive@>
+primitive("mathunderaccent",math_accent,under_accent);@/
+@!@:math_under_accent_}{\.{\\mathunderaccent} primitive@>
+primitive("nestingmathunderaccent",math_accent,under_accent+nesting);@/
+@!@:nesting_math_under_accent_}{\.{\\nestingmathunderaccent} primitive@>
+@z
+
+@x
+primitive("radical",radical,0);@/
+@!@:radical_}{\.{\\radical} primitive@>
+@y
+primitive("radical",radical,0);@/
+@!@:radical_}{\.{\\radical} primitive@>
+primitive("genradical",radical,1);@/
+@!@:genradical_}{\.{\\genradical} primitive@>
+@z
+
+@x
+math_accent: print_esc("mathaccent");
+@y
+math_accent: case chr_code of
+ normal: print_esc("mathaccent");
+ normal+nesting: print_esc("nestingmathaccent");
+ under_accent: print_esc("mathunderaccent");
+ under_accent+nesting:print_esc("nestingmathunderaccent");
+ othercases print("Unknown accent!")
+endcases;
+@z
+
+@x
+radical: print_esc("radical");
+@y
+radical: if chr_code=0 then print_esc("radical") else print_esc("genradical");
+@z
+
+@x
+@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
+@d badness_code=glue_val+2 {code for \.{\\badness}}
+@y
+@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
+@d badness_code=glue_val+2 {code for \.{\\badness}}
+@d math_style_code=glue_val+3 {code for \.{\\mathstyle}}
+@z
+
+@x
+primitive("badness",last_item,badness_code);
+@!@:badness_}{\.{\\badness} primitive@>
+@y
+primitive("badness",last_item,badness_code);
+@!@:badness_}{\.{\\badness} primitive@>
+primitive("mathstyle",last_item,math_style_code);
+@!@:mathstyle_}{\.{\\mathstyle} primitive@>
+@z
+
+@x
+ input_line_no_code: print_esc("inputlineno");
+ othercases print_esc("badness")
+@y
+ input_line_no_code: print_esc("inputlineno");
+ badness_code: print_esc("badness");
+ math_style_code: print_esc("mathstyle");
+ othercases confusion("last_item")
+@:this can't happen last_item}{\quad last_item@>
+@z
+
+@x
+if cur_chr>glue_val then
+ begin if cur_chr=input_line_no_code then cur_val:=line
+ else cur_val:=last_badness; {|cur_chr=badness_code|}
+ cur_val_level:=int_val;
+ end
+@y
+if cur_chr>glue_val then
+ begin if cur_chr=input_line_no_code then cur_val:=line
+ else if cur_chr=math_style_code then begin
+ if abs(mode)=mmode then cur_val:=mathstyle
+ else cur_val:=-1;
+ end else cur_val:=last_badness;
+ cur_val_level:=int_val;
+ end
+@z
+
+@x
+@d radical_noad_size=5 {number of |mem| words in a radical noad}
+@y
+@d radical_noad_size=6 {number of |mem| words in a radical noad}
+@d is_null_delimiter(#) ==
+ ((mem[#].qqqq.b0=0) and (mem[#].qqqq.b1=min_quarterword) and
+ (mem[#].qqqq.b2=0) and (mem[#].qqqq.b3=min_quarterword))
+@z
+
+@x
+begin case c div 2 of
+0: print_esc("displaystyle"); {|display_style=0|}
+1: print_esc("textstyle"); {|text_style=2|}
+2: print_esc("scriptstyle"); {|script_style=4|}
+3: print_esc("scriptscriptstyle"); {|script_script_style=6|}
+othercases print("Unknown style!")
+@y
+begin case c of
+display_style: print_esc("displaystyle");
+display_style+cramped: print_esc("crampeddisplaystyle");
+text_style: print_esc("textstyle");
+text_style+cramped: print_esc("crampedtextstyle");
+script_style: print_esc("scriptstyle");
+script_style+cramped: print_esc("crampedscriptstyle");
+script_script_style: print_esc("scriptscriptstyle");
+script_script_style+cramped: print_esc("crampedscriptscriptstyle");
+othercases print("Unknown style!")
+@z
+
+@x
+radical_noad: begin print_esc("radical"); print_delimiter(left_delimiter(p));
+ end;
+@y
+radical_noad: if subtype(p)=normal then begin
+ print_esc("radical"); print_delimiter(left_delimiter(p));
+ end else begin
+ print_esc("genradical"); print_delimiter(left_delimiter(p));
+ print_delimiter(right_delimiter(p));
+ end;
+@z
+
+@x
+@!cur_style:small_number; {style code at current place in the list}
+@y
+@!cur_style,mathstyle:small_number; {style code at current place in the list}
+@z
+
+@x
+accent_noad: make_math_accent(q);
+@y
+accent_noad: if subtype(q)<under_accent then make_math_accent(q)
+ else make_math_under_accent(q);
+@z
+
+@x
+procedure make_radical(@!q:pointer);
+var x,@!y:pointer; {temporary registers for box construction}
+@!delta,@!clr:scaled; {dimensions involved in the calculation}
+begin x:=clean_box(nucleus(q),cramped_style(cur_style));
+if cur_style<text_style then {display style}
+ clr:=default_rule_thickness+(abs(math_x_height(cur_size)) div 4)
+else begin clr:=default_rule_thickness; clr:=clr + (abs(clr) div 4);
+ end;
+y:=var_delimiter(left_delimiter(q),cur_size,height(x)+depth(x)+clr+
+ default_rule_thickness);
+delta:=depth(y)-(height(x)+depth(x)+clr);
+if delta>0 then clr:=clr+half(delta); {increase the actual clearance}
+shift_amount(y):=-(height(x)+clr);
+link(y):=overbar(x,clr,height(y));
+info(nucleus(q)):=hpack(y,natural); math_type(nucleus(q)):=sub_box;
+end;
+@y
+procedure make_radical(@!q:pointer);
+var x,@!y,z:pointer; {temporary registers for box construction}
+@!delta,@!clr,ht:scaled; {dimensions involved in the calculation}
+begin x:=clean_box(nucleus(q),cramped_style(cur_style));
+if cur_style<text_style then {display style}
+ clr:=default_rule_thickness+(abs(math_x_height(cur_size)) div 4)
+else begin clr:=default_rule_thickness; clr:=clr + (abs(clr) div 4);
+ end;
+y:=var_delimiter(left_delimiter(q),cur_size,height(x)+depth(x)+clr+
+ default_rule_thickness);
+delta:=depth(y)-(height(x)+depth(x)+clr);
+if delta>0 then clr:=clr+half(delta); {increase the actual clearance}
+shift_amount(y):=-(height(x)+clr);
+ht:=height(y);
+if subtype(q)=normal then link(y):=overbar(x,clr,ht)
+else begin
+ z:=var_delimiter(right_delimiter(q),cur_size,height(x)+depth(x)+clr+
+ default_rule_thickness);
+ shift_amount(z):=-(height(x)+clr);
+ if height(z)>ht then ht:=height(z);
+ link(y):=overbar(x,clr,ht);
+ link(link(y)):=z;
+end;
+info(nucleus(q)):=hpack(y,natural); math_type(nucleus(q)):=sub_box;
+end;
+@z
+
+@x
+procedure make_math_accent(@!q:pointer);
+label done,done1;
+var p,@!x,@!y:pointer; {temporary registers for box construction}
+@y
+procedure horizontally_stack_into_box(@!b:pointer;@!f:internal_font_number;@!c:quarterword);
+var p:pointer; {new node placed into |b|}
+begin
+ p:=char_box(f,c); link(p):=list_ptr(b); list_ptr(b):=p;
+ width(b):=width(b)+width(p);
+end;
+
+procedure make_math_under_accent(@!q:pointer);
+label done,done1,done2,done3;
+var p,qq,@!x,@!y:pointer; {temporary registers for box construction}
+@!a:integer; {address of lig/kern instruction}
+@!c:quarterword; {accent character}
+@!f:internal_font_number; {its font}
+@!i,ii:four_quarters; {its |char_info|}
+@!s:scaled; {amount to skew the accent to the right}
+@!h:scaled; {height of character being accented}
+@!delta,sep:scaled; {space to insert between accentee and accent}
+@!w,v,u:scaled; {width of the accentee, not including sub/superscripts}
+@!t:four_quarters;
+@!m,n:integer;
+@!hd:eight_bits;
+begin fetch(accent_chr(q));
+if char_exists(cur_i) then
+ begin i:=cur_i; c:=cur_c; f:=cur_f;@/
+ @<Compute under accent skew@>;
+ @<Compute separation for under accent@>;
+ x:=clean_box(nucleus(q),cur_style); w:=width(x); h:=height(x);
+ @<Switch to a larger accent if available and appropriate@>;
+ if (math_type(supscr(q))<>empty)or(math_type(subscr(q))<>empty) then
+ if math_type(nucleus(q))=math_char then
+ @<Swap the subscript and superscript into box |x|@>;
+ shift_amount(y):=half(w-width(y))-s; width(y):=0;
+ p:=new_kern(sep); link(x):=p; link(p):=y;
+ p:=new_kern(-sep-x_height(f)); link(y):=p;
+ y:=vpack(x,natural); width(y):=w;
+ depth(y):=depth(y)+height(y)-h; height(y):=h;
+ info(nucleus(q)):=y; math_type(nucleus(q)):=sub_box;
+ end;
+end;
+
+procedure make_math_accent(@!q:pointer);
+label done,done1,done2;
+var p,qq,@!x,@!y:pointer; {temporary registers for box construction}
+@z
+
+@x
+@!w:scaled; {width of the accentee, not including sub/superscripts}
+@y
+@!w,v,u:scaled; {width of the accentee, not including sub/superscripts}
+@!t:four_quarters;
+@!m,n:integer;
+@!hd:eight_bits;
+@z
+
+@x
+ y:=char_box(f,c);
+@y
+@z
+
+@x
+@ @<Switch to a larger accent if available and appropriate@>=
+loop@+ begin if char_tag(i)<>list_tag then goto done;
+ y:=rem_byte(i);
+ i:=char_info(f)(y);
+ if not char_exists(i) then goto done;
+ if char_width(f)(i)>w then goto done;
+ c:=y;
+ end;
+done:
+@y
+@ @<Switch to a larger accent if available and appropriate@>=
+loop@+ begin
+ if char_tag(i)=ext_tag then begin
+ y:=new_null_box;
+ type(y):=hlist_node;
+ i:=font_info[exten_base[f]+rem_byte(i)].qqqq;@/
+ c:=ext_rep(i); t:=char_info(f)(c); u:=char_width(f)(t); v:=0;
+ hd:=height_depth(t); height(y):=char_height(f)(hd); depth(y):=char_depth(f)(hd);
+ c:=ext_bot(i); t:=char_info(f)(c); @+if c<>min_quarterword then v:=v+char_width(f)(t);
+ c:=ext_mid(i); t:=char_info(f)(c); @+if c<>min_quarterword then v:=v+char_width(f)(t);
+ c:=ext_top(i); t:=char_info(f)(c); @+if c<>min_quarterword then v:=v+char_width(f)(t);
+ n:=0;
+ if u>0 then while v<w do begin
+ v:=v+u; incr(n);
+ if ext_mid(i)<>min_quarterword then v:=v+u;
+ end;
+ c:=ext_bot(i);
+ if c<>min_quarterword then horizontally_stack_into_box(y,f,c);
+ c:=ext_rep(i);
+ for m:=1 to n do horizontally_stack_into_box(y,f,c);
+ c:=ext_mid(i);
+ if c<>min_quarterword then begin
+ horizontally_stack_into_box(y,f,c);
+ c:=ext_rep(i);
+ for m:=1 to n do horizontally_stack_into_box(y,f,c);
+ end;
+ c:=ext_top(i);
+ if c<>min_quarterword then horizontally_stack_into_box(y,f,c);
+ goto done2;
+ end;
+ if char_tag(i)<>list_tag then goto done;
+ y:=rem_byte(i);
+ i:=char_info(f)(y);
+ if not char_exists(i) then goto done;
+ if char_width(f)(i)>w then goto done;
+ c:=y;
+end;
+done:
+ y:=char_box(f,c);
+done2:
+@z
+
+@x
+@ @<Compute the amount of skew@>=
+s:=0;
+if math_type(nucleus(q))=math_char then
+ begin fetch(nucleus(q));
+@y
+@ @<Compute under accent skew@>=
+s:=0;
+qq:=q;
+if odd(subtype(q)) then
+ while (math_type(nucleus(qq))=sub_mlist)and
+ (type(info(nucleus(qq)))=accent_noad)and
+ ((subtype(qq)=subtype(q))or(subtype(qq) div 2<>subtype(q) div 2)) do
+ qq:=info(nucleus(qq));
+if math_type(nucleus(qq))=math_char then
+ begin fetch(nucleus(qq));
+ ii:=char_info(cur_f)(skew_char[cur_f]);
+ if char_tag(ii)=lig_tag then
+ begin a:=lig_kern_start(cur_f)(ii);
+ ii:=font_info[a].qqqq;
+ if skip_byte(ii)>stop_flag then
+ begin a:=lig_kern_restart(cur_f)(ii);
+ ii:=font_info[a].qqqq;
+ end;
+ loop@+ begin if qo(next_char(ii))=cur_c then
+ begin if op_byte(ii)>=kern_flag then
+ if skip_byte(ii)<=stop_flag then s:=char_kern(cur_f)(ii);
+ goto done1;
+ end;
+ if skip_byte(ii)>=stop_flag then goto done1;
+ a:=a+qo(skip_byte(ii))+1;
+ ii:=font_info[a].qqqq;
+ end;
+ end;
+ end;
+done1:
+
+@ @<Compute separation for under accent@>=
+ sep:=0;
+ ii:=i;
+ if char_tag(ii)=lig_tag then
+ begin a:=lig_kern_start(f)(ii);
+ ii:=font_info[a].qqqq;
+ if skip_byte(ii)>stop_flag then
+ begin a:=lig_kern_restart(f)(ii);
+ ii:=font_info[a].qqqq;
+ end;
+ loop@+ begin if qo(next_char(ii))=c then
+ begin if op_byte(ii)>=kern_flag then
+ if skip_byte(ii)<=stop_flag then sep:=char_kern(f)(ii);
+ goto done3;
+ end;
+ if skip_byte(ii)>=stop_flag then goto done3;
+ a:=a+qo(skip_byte(ii))+1;
+ ii:=font_info[a].qqqq;
+ end;
+ end;
+done3:
+
+@ @<Compute the amount of skew@>=
+s:=0;
+qq:=q;
+{while odd(subtype(qq))and(math_type(nucleus(qq))=sub_mlist)and
+ (type(info(nucleus(qq)))=accent_noad) do}
+if odd(subtype(q)) then
+ while (math_type(nucleus(qq))=sub_mlist)and
+ (type(info(nucleus(qq)))=accent_noad)and
+ ((subtype(qq)=subtype(q))or(subtype(qq) div 2<>subtype(q) div 2)) do
+ qq:=info(nucleus(qq));
+if math_type(nucleus(qq))=math_char then
+ begin fetch(nucleus(qq));
+@z
+
+@x
+begin push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1);
+if every_math<>null then begin_token_list(every_math,every_math_text);
+@y
+begin mathstyle:=text_style;
+push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1);
+if every_math<>null then begin_token_list(every_math,every_math_text);
+@z
+
+@x
+push_math(math_shift_group); mode:=mmode;
+eq_word_define(int_base+cur_fam_code,-1);@/
+@y
+mathstyle:=display_style;
+push_math(math_shift_group); mode:=mmode;
+eq_word_define(int_base+cur_fam_code,-1);@/
+@z
+
+@x
+mmode+left_brace: begin tail_append(new_noad);
+ back_input; scan_math(nucleus(tail));
+@y
+mmode+left_brace: begin tail_append(new_noad);
+ back_input; scan_math(nucleus(tail),mathstyle);
+@z
+
+@x
+procedure scan_math(@!p:pointer);
+label restart,reswitch,exit;
+var c:integer; {math character code}
+begin restart:@<Get the next non-blank non-relax...@>;
+reswitch:case cur_cmd of
+letter,other_char,char_given: begin c:=ho(math_code(cur_chr));
+ if c=@'100000 then
+ begin @<Treat |cur_chr| as an active character@>;
+ goto restart;
+ end;
+ end;
+char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given;
+ goto reswitch;
+ end;
+math_char_num: begin scan_fifteen_bit_int; c:=cur_val;
+ end;
+math_given: c:=cur_chr;
+delim_num: begin scan_twenty_seven_bit_int; c:=cur_val div @'10000;
+ end;
+othercases @<Scan a subformula enclosed in braces and |return|@>
+endcases;@/
+math_type(p):=math_char; character(p):=qi(c mod 256);
+if (c>=var_code)and fam_in_range then fam(p):=cur_fam
+else fam(p):=(c div 256) mod 16;
+exit:end;
+@y
+procedure scan_math(@!p:pointer;s:small_number);
+label restart,reswitch,exit;
+var c:integer; {math character code}
+ savedstyle:small_number;
+begin
+savedstyle:=mathstyle; mathstyle:=s;
+restart:@<Get the next non-blank non-relax...@>;
+reswitch:case cur_cmd of
+letter,other_char,char_given: begin c:=ho(math_code(cur_chr));
+ if c=@'100000 then
+ begin @<Treat |cur_chr| as an active character@>;
+ goto restart;
+ end;
+ end;
+char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given;
+ goto reswitch;
+ end;
+math_char_num: begin scan_fifteen_bit_int; c:=cur_val;
+ end;
+math_given: c:=cur_chr;
+delim_num: begin scan_twenty_seven_bit_int; c:=cur_val div @'10000;
+ end;
+othercases @<Scan a subformula enclosed in braces and |return|@>
+endcases;@/
+math_type(p):=math_char; character(p):=qi(c mod 256);
+if (c>=var_code)and fam_in_range then fam(p):=cur_fam
+else fam(p):=(c div 256) mod 16;
+mathstyle:=savedstyle;
+exit:
+end;
+@z
+
+@x
+begin back_input; scan_left_brace;@/
+saved(0):=p; incr(save_ptr); push_math(math_group); return;
+@y
+begin back_input; scan_left_brace;@/
+saved(0):=p; incr(save_ptr); saved(0):=savedstyle; incr(save_ptr);
+push_math(math_group); return;
+@z
+
+@x
+mmode+math_comp: begin tail_append(new_noad);
+ type(tail):=cur_chr; scan_math(nucleus(tail));
+@y
+mmode+math_comp: begin tail_append(new_noad);
+ type(tail):=cur_chr;
+ case type(tail) of
+ over_noad: scan_math(nucleus(tail),cramped_style(mathstyle));
+ othercases scan_math(nucleus(tail),mathstyle);
+ endcases;
+@z
+
+@x
+type(tail):=radical_noad; subtype(tail):=normal;
+@y
+type(tail):=radical_noad; subtype(tail):=cur_chr;
+@z
+
+@x
+{before |scan_math| in |math_radical|}
+scan_math(nucleus(tail));
+@y
+if subtype(tail)=normal then mem[right_delimiter(tail)].qqqq:=null_delimiter
+else scan_delimiter(right_delimiter(tail),true);
+{before |scan_math| in |math_radical|}
+scan_math(nucleus(tail),cramped_style(mathstyle));
+@z
+
+@x
+procedure math_ac;
+begin if cur_cmd=accent then
+ @<Complain that the user should have said \.{\\mathaccent}@>;
+tail_append(get_node(accent_noad_size));
+type(tail):=accent_noad; subtype(tail):=normal;
+@y
+procedure math_ac;
+begin if cur_cmd=accent then
+ @<Complain that the user should have said \.{\\mathaccent}@>;
+tail_append(get_node(accent_noad_size));
+type(tail):=accent_noad; subtype(tail):=cur_chr;
+@z
+
+@x
+if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam
+else fam(accent_chr(tail)):=(cur_val div 256) mod 16;
+scan_math(nucleus(tail));
+end;
+@y
+if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam
+else fam(accent_chr(tail)):=(cur_val div 256) mod 16;
+scan_math(nucleus(tail),cramped_style(mathstyle));
+end;
+@z
+
+@x
+primitive("displaystyle",math_style,display_style);
+@!@:display_style_}{\.{\\displaystyle} primitive@>
+primitive("textstyle",math_style,text_style);
+@!@:text_style_}{\.{\\textstyle} primitive@>
+primitive("scriptstyle",math_style,script_style);
+@!@:script_style_}{\.{\\scriptstyle} primitive@>
+primitive("scriptscriptstyle",math_style,script_script_style);
+@!@:script_script_style_}{\.{\\scriptscriptstyle} primitive@>
+@y
+primitive("displaystyle",math_style,display_style);
+@!@:display_style_}{\.{\\displaystyle} primitive@>
+primitive("crampeddisplaystyle",math_style,display_style+cramped);
+@!@:cramped_display_style_}{\.{\\crampeddisplaystyle} primitive@>
+primitive("textstyle",math_style,text_style);
+@!@:text_style_}{\.{\\textstyle} primitive@>
+primitive("crampedtextstyle",math_style,text_style+cramped);
+@!@:cramped_text_style_}{\.{\\crampedtextstyle} primitive@>
+primitive("scriptstyle",math_style,script_style);
+@!@:script_style_}{\.{\\scriptstyle} primitive@>
+primitive("crampedscriptstyle",math_style,script_style+cramped);
+@!@:cramped_script_style_}{\.{\\crampedscriptstyle} primitive@>
+primitive("scriptscriptstyle",math_style,script_script_style);
+@!@:script_script_style_}{\.{\\scriptscriptstyle} primitive@>
+primitive("crampedscriptscriptstyle",math_style,script_script_style+cramped);
+@!@:cramped_script_script_style_}{\.{\\crampedscriptscriptstyle} primitive@>
+@z
+
+@x
+mmode+math_style: tail_append(new_style(cur_chr));
+@y
+mmode+math_style: begin tail_append(new_style(cur_chr));
+ mathstyle:=cur_chr;
+end;
+@z
+
+@x
+procedure append_choices;
+begin tail_append(new_choice); incr(save_ptr); saved(-1):=0;
+push_math(math_choice_group); scan_left_brace;
+@y
+procedure append_choices;
+begin tail_append(new_choice);
+incr(save_ptr); saved(-1):=mathstyle;
+incr(save_ptr); saved(-1):=0;
+push_math(math_choice_group); scan_left_brace;
+mathstyle:=display_style;
+@z
+
+@x
+3:begin script_script_mlist(tail):=p; decr(save_ptr); return;
+ end;
+end; {there are no other cases}
+incr(saved(-1)); push_math(math_choice_group); scan_left_brace;
+@y
+3:begin script_script_mlist(tail):=p; decr(save_ptr);
+ mathstyle:=saved(-1); decr(save_ptr);
+ return;
+ end;
+end; {there are no other cases}
+incr(saved(-1)); push_math(math_choice_group); scan_left_brace;
+mathstyle:=2*saved(-1);
+@z
+
+@x
+procedure sub_sup;
+var t:small_number; {type of previous sub/superscript}
+@!p:pointer; {field to be filled by |scan_math|}
+begin t:=empty; p:=null;
+if tail<>head then if scripts_allowed(tail) then
+ begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|}
+ t:=math_type(p);
+ end;
+if (p=null)or(t<>empty) then @<Insert a dummy noad to be sub/superscripted@>;
+scan_math(p);
+end;
+@y
+procedure sub_sup;
+var t:small_number; {type of previous sub/superscript}
+@!p:pointer; {field to be filled by |scan_math|}
+begin t:=empty; p:=null;
+if tail<>head then if scripts_allowed(tail) then
+ begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|}
+ t:=math_type(p);
+ end;
+if (p=null)or(t<>empty) then @<Insert a dummy noad to be sub/superscripted@>;
+if cur_cmd=sup_mark then scan_math(p,sup_style(mathstyle))
+else scan_math(p,sub_style(mathstyle));
+end;
+@z
+
+@x
+@d delimited_code=3 { `\.{\\abovewithdelims}', etc.}
+@y
+@d delimited_code=3 { `\.{\\abovewithdelims}', etc.}
+@d fraction_code=6 { `\.{\\fraction}', etc.}
+@z
+
+@x
+primitive("atopwithdelims",above,delimited_code+atop_code);
+@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@>
+@y
+primitive("atopwithdelims",above,delimited_code+atop_code);
+@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@>
+primitive("fraction",above,fraction_code);
+@!@:fraction_}{\.{\\fraction} primitive@>
+@z
+
+@x
+ delimited_code+atop_code:print_esc("atopwithdelims");
+ othercases print_esc("above")
+@y
+ delimited_code+atop_code:print_esc("atopwithdelims");
+ fraction_code:print_esc("fraction");
+ othercases print_esc("above")
+@z
+
+@x
+mmode+above: math_fraction;
+@y
+mmode+above: if cur_chr=fraction_code then begin
+ scan_left_brace; tail_append(new_noad);
+ back_input;
+ scan_math(nucleus(tail),num_style(mathstyle));
+end else begin
+ math_fraction;
+end;
+@z
+
+@x
+procedure math_fraction;
+var c:small_number; {the type of generalized fraction we are scanning}
+begin c:=cur_chr;
+@y
+procedure math_fraction;
+var c:small_number; {the type of generalized fraction we are scanning}
+begin c:=cur_chr;
+mathstyle:=denom_style(save_stack[cur_boundary-1].int);
+@z
+
+@x
+math_group: begin unsave; decr(save_ptr);@/
+ math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); info(saved(0)):=p;
+@y
+math_group: begin unsave; decr(save_ptr);@/
+ mathstyle:=saved(0); decr(save_ptr);
+ math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); info(saved(0)):=p;
+@z
+
diff --git a/systems/tex-extensions/clasen/math/math.tex b/systems/tex-extensions/clasen/math/math.tex
new file mode 100644
index 0000000000..1ce32accbc
--- /dev/null
+++ b/systems/tex-extensions/clasen/math/math.tex
@@ -0,0 +1,130 @@
+\documentclass[preprint]{ltugboat}
+\usepackage{shortvrb}
+\usepackage{url}
+\usepackage{booktabs}
+
+\providecommand{\meta}[1]{\ensuremath{\langle\textit{#1}\rangle}}
+\makeatletter
+\providecommand{\eTeX}{$\m@th\varepsilon$-\TeX}
+\makeatother
+\hyphenation{pa-ra-me-ter}
+
+\emergencystretch=4mm
+\overfullrule=0pt
+\title{Extending \TeX's mathematical typography}
+\author{Matthias Clasen}
+%\address{}
+\netaddress{maclas@gmx.de}
+\setcounter{page}{1}
+
+\begin{document}
+\maketitle
+\MakeShortVerb{\|}
+
+\section{Introduction}
+
+One of the reasons why \TeX\ is still in use is that its abilities
+in setting mathematical formulas are still unsurmounted. But there
+are some nits to pick.
+
+I propose a small set of extensions to \TeX\ to remove some deficiencies
+in its handling of formulas.
+
+\section{Implementation}
+
+The implementation is split into a series of change files:
+
+|accent.ch| implements three new primitives for nestable accents and
+ under accents. To some extent these can be implemented in \TeX\ itself (see
+ \AmSLaTeX), but macro solutions are complicated, slow and error-prone.
+ \begin{description}
+ \item[]|\mathaccent|\meta{15-bit number}\meta{math field} can now
+ grok an extensible recipe at the end of a charlist. The extensible
+ recipe is used to construct longer variants of an accent (in analogy
+ to growing delimiters).
+ \item[]|\nestingmathaccent|\meta{15-bit number}\meta{math field} is
+ like |\math|\-|accent|, but it follows a chain of
+ |\nesting|\-|math|\-|accent| or |\nesting|\-|math|\-|under|\-|accent|
+ primitives to determine its accentee and the appropriate skew.
+ \item[]|\mathunderaccent|\meta{15-bit number}\meta{math field}\\
+ places an accent \emph{under} the \meta{math field}. It uses the
+ \meta{accent}--\meta{accent} kerning to determine the vertical space
+ between the \meta{math field} and the \meta{accent} and the
+ \meta{skewchar}--\meta{accentee} kerning to determine the appropriate
+ skew to the left.
+ \item[]|\nestingmathunderaccent|\meta{15-bit number}%
+ $\langle$\textit{math}\\\null\hfill\textit{field}$\rangle$\\
+ is a variant of |\math|\-|under|\-|accent| which
+ respects the nesting of accents.
+ \end{description}
+
+|cramp.ch| complements the |\display|\-|style|, \dots,
+|\script|\-|script|\-|style| style-changing primitives by
+|\cramped|\-|display|\-|style|, \dots, |\cramped|\-|script|\-|script|\-|style|
+which change to the cramped styles.
+
+|fraction.ch| continues to improve the math style-handling. It
+ adds the following:
+ \begin{description}
+ \item[]|\mathstyle| is a special readonly integer parameter
+ corresponding to the current math style according to the
+ following table:
+
+ \begin{tabular}{cc}
+ \toprule
+ math style&|\mathstyle|\\
+ \midrule
+ none& \llap{${}<{}$}0\\
+ D&0\\
+ D'&1\\
+ T&2\\
+ T'&3\\
+ S&4\\
+ S'&5\\
+ SS&6\\
+ SS'&7\\
+ \bottomrule
+ \end{tabular}
+
+ \item[]|\fraction|\{\meta{math field}\} can be used to surround
+ fractions. Its sole purpose is that |\mathstyle| reports the correct
+ values in a subformula like |\fraction{...\over...}| while it fails to
+ do so in |{...\over...}|.
+ \end{description}
+
+|radical.ch| implements the following new primitive:
+ \begin{description}
+ \item[]|\genradical|\meta{27-bit number}\meta{27-bit number}%
+ $\langle$\textit{math}\\\null\hfill\textit{field}$\rangle$\\
+ creates a radical with delimiters on both sides. By
+ specifiying a nonexisting left delimiter, you can also create a
+ right radical.
+ \end{description}
+
+\section{Installation}
+
+ The change files are written for \TeX~3.1459. But it should need only
+ cosmetic changes to get them to work with other versions of \TeX3.
+
+ To make the change files for \TeX{} work, you have to apply the change file
+ |pre.ch| first. I have only tried these files with |web2c|, and
+ for that you need to surround the |web2c| change file with |pre-web2c.ch| and
+ |post-web2c.ch|.
+
+ All this boils down to the command line
+
+\begin{verbatim}
+mv tex.ch tex.ch.orig
+tie -c tex.ch tex.web pre.ch accent.ch \
+ cramp.ch fraction.ch radical.ch \
+ pre-web2c.ch tex.ch.orig \
+ post-web2c.ch
+\end{verbatim}
+
+ \makesignature
+
+ \bibliographystyle{plain}
+ \bibliography{etex}
+
+\end{document}
+
diff --git a/systems/tex-extensions/clasen/math/radical.ch b/systems/tex-extensions/clasen/math/radical.ch
new file mode 100644
index 0000000000..757652cecd
--- /dev/null
+++ b/systems/tex-extensions/clasen/math/radical.ch
@@ -0,0 +1,99 @@
+@x
+primitive("radical",radical,0);@/
+@!@:radical_}{\.{\\radical} primitive@>
+@y
+primitive("radical",radical,0);@/
+@!@:radical_}{\.{\\radical} primitive@>
+primitive("genradical",radical,1);@/
+@!@:genradical_}{\.{\\genradical} primitive@>
+@z
+
+@x
+radical: print_esc("radical");
+@y
+radical: if chr_code=0 then print_esc("radical") else print_esc("genradical");
+@z
+
+@x
+@d radical_noad_size=5 {number of |mem| words in a radical noad}
+@y
+@d radical_noad_size=6 {number of |mem| words in a radical noad}
+@d is_null_delimiter(#) ==
+ ((mem[#].qqqq.b0=0) and (mem[#].qqqq.b1=min_quarterword) and
+ (mem[#].qqqq.b2=0) and (mem[#].qqqq.b3=min_quarterword))
+@z
+@x
+radical_noad: begin print_esc("radical"); print_delimiter(left_delimiter(p));
+ end;
+@y
+radical_noad: if subtype(p)=normal then begin
+ print_esc("radical"); print_delimiter(left_delimiter(p));
+ end else begin
+ print_esc("genradical"); print_delimiter(left_delimiter(p));
+ print_delimiter(right_delimiter(p));
+ end;
+@z
+
+@x
+procedure make_radical(@!q:pointer);
+var x,@!y:pointer; {temporary registers for box construction}
+@!delta,@!clr:scaled; {dimensions involved in the calculation}
+begin x:=clean_box(nucleus(q),cramped_style(cur_style));
+if cur_style<text_style then {display style}
+ clr:=default_rule_thickness+(abs(math_x_height(cur_size)) div 4)
+else begin clr:=default_rule_thickness; clr:=clr + (abs(clr) div 4);
+ end;
+y:=var_delimiter(left_delimiter(q),cur_size,height(x)+depth(x)+clr+
+ default_rule_thickness);
+delta:=depth(y)-(height(x)+depth(x)+clr);
+if delta>0 then clr:=clr+half(delta); {increase the actual clearance}
+shift_amount(y):=-(height(x)+clr);
+link(y):=overbar(x,clr,height(y));
+info(nucleus(q)):=hpack(y,natural); math_type(nucleus(q)):=sub_box;
+end;
+@y
+procedure make_radical(@!q:pointer);
+var x,@!y,z:pointer; {temporary registers for box construction}
+@!delta,@!clr,ht:scaled; {dimensions involved in the calculation}
+begin x:=clean_box(nucleus(q),cramped_style(cur_style));
+if cur_style<text_style then {display style}
+ clr:=default_rule_thickness+(abs(math_x_height(cur_size)) div 4)
+else begin clr:=default_rule_thickness; clr:=clr + (abs(clr) div 4);
+ end;
+y:=var_delimiter(left_delimiter(q),cur_size,height(x)+depth(x)+clr+
+ default_rule_thickness);
+delta:=depth(y)-(height(x)+depth(x)+clr);
+if delta>0 then clr:=clr+half(delta); {increase the actual clearance}
+shift_amount(y):=-(height(x)+clr);
+ht:=height(y);
+if subtype(q)=normal then link(y):=overbar(x,clr,ht)
+else begin
+ z:=var_delimiter(right_delimiter(q),cur_size,height(x)+depth(x)+clr+
+ default_rule_thickness);
+ shift_amount(z):=-(height(x)+clr);
+ if height(z)>ht then ht:=height(z);
+ link(y):=overbar(x,clr,ht);
+ link(link(y)):=z;
+end;
+info(nucleus(q)):=hpack(y,natural); math_type(nucleus(q)):=sub_box;
+end;
+@z
+
+@x
+type(tail):=radical_noad; subtype(tail):=normal;
+@y
+type(tail):=radical_noad; subtype(tail):=cur_chr;
+@z
+
+@x
+{before |scan_math| in |math_radical|}
+@y
+if subtype(tail)=normal then mem[right_delimiter(tail)].qqqq:=null_delimiter
+else scan_delimiter(right_delimiter(tail),true);
+{before |scan_math| in |math_radical|}
+@z
+
+
+
+
+
diff --git a/systems/tex-extensions/clasen/post-web2c.ch b/systems/tex-extensions/clasen/post-web2c.ch
new file mode 100644
index 0000000000..a81770b73a
--- /dev/null
+++ b/systems/tex-extensions/clasen/post-web2c.ch
@@ -0,0 +1,4 @@
+@x
+@d int_pars=58 {total number of integer parameters}
+@y
+@z
diff --git a/systems/tex-extensions/clasen/pre-web2c.ch b/systems/tex-extensions/clasen/pre-web2c.ch
new file mode 100644
index 0000000000..2cef3fe138
--- /dev/null
+++ b/systems/tex-extensions/clasen/pre-web2c.ch
@@ -0,0 +1,9 @@
+% Since the web2c change file includes MLTeX and thus
+% messes around with int_pars, we have to do some extra
+% work. Not nice.
+
+@x l.4954
+{MLTEX int_pars go here}
+@y
+@d int_pars=55 {total number of integer parameters}
+@z
diff --git a/systems/tex-extensions/clasen/pre.ch b/systems/tex-extensions/clasen/pre.ch
new file mode 100644
index 0000000000..7633320760
--- /dev/null
+++ b/systems/tex-extensions/clasen/pre.ch
@@ -0,0 +1,41 @@
+@x l.187
+@d banner=='This is TeX, Version 3.14159' {printed when \TeX\ starts}
+@y
+@d banner=='This is TeX, Version 3.14159 (with experimental extensions)'
+ {printed when \TeX\ starts}
+@z
+
+%
+% Since it is next to impossible to add integer parameters one by one
+% and still keep the change files modular, I decided to add more than
+% enough room for new integer parameters here.
+%
+
+@x l.4954
+@d int_pars=55 {total number of integer parameters}
+@y
+{MLTEX int_pars go here}
+{hyphen classes int_pars go here}
+{hyphen count int_pars go here}
+{math int_pars go here}
+{hz int_pars go here}
+{margin int_pars go here}
+{skyline int_pars go here}
+@d int_pars=100 {upper bound for the total number of integer parameters}
+@z
+
+%
+% We need to mark some places so that change files can
+% independently add things there
+%
+
+@x l.22005
+mem[supscr(tail)].hh:=empty_field;
+scan_delimiter(left_delimiter(tail),true); scan_math(nucleus(tail));
+@y
+mem[supscr(tail)].hh:=empty_field;
+scan_delimiter(left_delimiter(tail),true);
+{before |scan_math| in |math_radical|}
+scan_math(nucleus(tail));
+@z
+
diff --git a/systems/tex-extensions/clasen/tight2.patch b/systems/tex-extensions/clasen/tight2.patch
new file mode 100644
index 0000000000..d9a15af1f9
--- /dev/null
+++ b/systems/tex-extensions/clasen/tight2.patch
@@ -0,0 +1,1461 @@
+*** tex.web.orig Mon Sep 14 23:03:05 1998
+--- tex.web Sun Sep 20 10:00:49 1998
+***************
+*** 184,190 ****
+ known as `\TeX' [cf.~Stanford Computer Science report CS1027,
+ November 1984].
+
+! @d banner=='This is TeX, Version 3.14159' {printed when \TeX\ starts}
+
+ @ Different \PASCAL s have slightly different conventions, and the present
+ @!@:PASCAL H}{\ph@>
+--- 184,190 ----
+ known as `\TeX' [cf.~Stanford Computer Science report CS1027,
+ November 1984].
+
+! @d banner=='This is *not* TeX, Version 3.14159' {printed when \TeX\ starts}
+
+ @ Different \PASCAL s have slightly different conventions, and the present
+ @!@:PASCAL H}{\ph@>
+***************
+*** 4951,4957 ****
+ @d right_hyphen_min_code=52 {minimum right hyphenation fragment size}
+ @d holding_inserts_code=53 {do not remove insertion nodes from \.{\\box255}}
+ @d error_context_lines_code=54 {maximum intermediate line pairs shown}
+! @d int_pars=55 {total number of integer parameters}
+ @d count_base=int_base+int_pars {256 user \.{\\count} registers}
+ @d del_code_base=count_base+256 {256 delimiter code mappings}
+ @d dimen_base=del_code_base+256 {beginning of region 6}
+--- 4951,4961 ----
+ @d right_hyphen_min_code=52 {minimum right hyphenation fragment size}
+ @d holding_inserts_code=53 {do not remove insertion nodes from \.{\\box255}}
+ @d error_context_lines_code=54 {maximum intermediate line pairs shown}
+! @d glue_overshrink_code=55 { 1000 times the amount by which to overshrink}
+! @d extra_adj_demerits_code=56 { additional demerits for jumping > 2 }
+! @d font_demerits_code=57
+! @d extra_font_demerits_code=58
+! @d int_pars=59 {total number of integer parameters}
+ @d count_base=int_base+int_pars {256 user \.{\\count} registers}
+ @d del_code_base=count_base+256 {256 delimiter code mappings}
+ @d dimen_base=del_code_base+256 {beginning of region 6}
+***************
+*** 5014,5019 ****
+--- 5018,5028 ----
+ @d right_hyphen_min==int_par(right_hyphen_min_code)
+ @d holding_inserts==int_par(holding_inserts_code)
+ @d error_context_lines==int_par(error_context_lines_code)
++ @d glue_overshrink==int_par(glue_overshrink_code)
++ @d extra_adj_demerits==int_par(extra_adj_demerits_code)
++ @d font_demerits==int_par(font_demerits_code)
++ @d extra_font_demerits==int_par(extra_font_demerits_code)
++
+
+ @<Assign the values |depth_threshold:=show_box_depth|...@>=
+ depth_threshold:=show_box_depth;
+***************
+*** 5078,5083 ****
+--- 5087,5096 ----
+ right_hyphen_min_code:print_esc("righthyphenmin");
+ holding_inserts_code:print_esc("holdinginserts");
+ error_context_lines_code:print_esc("errorcontextlines");
++ glue_overshrink_code:print_esc("glueovershrink");
++ extra_adj_demerits_code:print_esc("extraadjdemerits");
++ font_demerits_code:print_esc("fontdemerits");
++ extra_font_demerits_code:print_esc("extrafontdemerits");
+ othercases print("[unknown integer parameter!]")
+ endcases;
+ end;
+***************
+*** 5198,5203 ****
+--- 5211,5224 ----
+ @!@:holding_inserts_}{\.{\\holdinginserts} primitive@>
+ primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/
+ @!@:error_context_lines_}{\.{\\errorcontextlines} primitive@>
++ primitive("glueovershrink",assign_int,int_base+glue_overshrink_code);@/
++ @!@:glue_overshrink_}{\.{\\glueovershrink} primitive@>
++ primitive("extraadjdemerits",assign_int,int_base+extra_adj_demerits_code);@/
++ @!@:extra_adj_demerits_}{\.{\\extraadjdemerits} primitive@>
++ primitive("fontdemerits",assign_int,int_base+font_demerits_code);@/
++ @!@:font_demerits_}{\.{\\fontdemerits} primitive@>
++ primitive("extrafontdemerits",assign_int,int_base+extra_font_demerits_code);@/
++ @!@:extra_font_demerits_}{\.{\\extrafontdemerits} primitive@>
+
+ @ @<Cases of |print_cmd_chr|...@>=
+ assign_int: if chr_code<count_base then print_param(chr_code-int_base)
+***************
+*** 5658,5663 ****
+--- 5679,5686 ----
+ @!@:expand_after_}{\.{\\expandafter} primitive@>
+ primitive("font",def_font,0);@/
+ @!@:font_}{\.{\\font} primitive@>
++ primitive("fontvariant",def_font,1);@/
++ @!@:font_variant_}{\.{\\fontvariant} primitive@>
+ primitive("fontdimen",assign_font_dimen,0);@/
+ @!@:font_dimen_}{\.{\\fontdimen} primitive@>
+ primitive("halign",halign,0);@/
+***************
+*** 5732,5738 ****
+ break_penalty: print_esc("penalty");
+ char_num: print_esc("char");
+ cs_name: print_esc("csname");
+! def_font: print_esc("font");
+ delim_num: print_esc("delimiter");
+ divide: print_esc("divide");
+ end_cs_name: print_esc("endcsname");
+--- 5755,5761 ----
+ break_penalty: print_esc("penalty");
+ char_num: print_esc("char");
+ cs_name: print_esc("csname");
+! def_font: if chr_code=0 then print_esc("font") else print_esc("fontvariant");
+ delim_num: print_esc("delimiter");
+ divide: print_esc("divide");
+ end_cs_name: print_esc("endcsname");
+***************
+*** 8376,8384 ****
+ end;
+ scanned_result(equiv(m))(tok_val);
+ end
+! else begin back_input; scan_font_ident;
+ scanned_result(font_id_base+cur_val)(ident_val);
+! end
+
+ @ Users refer to `\.{\\the\\spacefactor}' only in horizontal
+ mode, and to `\.{\\the\\prevdepth}' only in vertical mode; so we put the
+--- 8399,8411 ----
+ end;
+ scanned_result(equiv(m))(tok_val);
+ end
+! else if m=0 then begin
+! back_input; scan_font_ident;
+ scanned_result(font_id_base+cur_val)(ident_val);
+! end else begin
+! print_err("Improper "); print_cmd_chr(def_font, m);
+! error;
+! end
+
+ @ Users refer to `\.{\\the\\spacefactor}' only in horizontal
+ mode, and to `\.{\\the\\prevdepth}' only in vertical mode; so we put the
+***************
+*** 10672,10677 ****
+--- 10699,10706 ----
+ @<Types...@>=
+ @!internal_font_number=font_base..font_max; {|font| in a |char_node|}
+ @!font_index=0..font_mem_size; {index into |font_info|}
++ @!four_fonts = packed array[0..3] of quarterword;
++ {a version of |four_quarters| with addressable quarters}
+
+ @ Here now is the (rather formidable) array of font arrays.
+
+***************
+*** 10709,10714 ****
+--- 10738,10745 ----
+ {right boundary character, |non_char| if there is none}
+ @!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
++ @!font_variants:array[internal_font_number] of four_fonts;
++ {we use four variants per font}
+
+ @ Besides the arrays just enumerated, we have directory arrays that make it
+ easy to get at the individual entries in |font_info|. For example, the
+***************
+*** 10760,10765 ****
+--- 10791,10797 ----
+ font_glue[null_font]:=null; font_params[null_font]:=7;
+ param_base[null_font]:=-1;
+ for k:=0 to 6 do font_info[k].sc:=0;
++ for k:=0 to 3 do font_variants[null_font][k]:=null_font;
+
+ @ @<Put each...@>=
+ primitive("nullfont",set_font,null_font);
+***************
+*** 12854,12865 ****
+
+ @< Glob...@>=
+ @!adjust_tail:pointer; {tail of adjustment list}
+
+ @ @<Set init...@>=adjust_tail:=null; last_badness:=0;
+
+ @ Here now is |hpack|, which contains few if any surprises.
+
+! @p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
+ label reswitch, common_ending, exit;
+ var r:pointer; {the box node that will be returned}
+ @!q:pointer; {trails behind |p|}
+--- 12886,12905 ----
+
+ @< Glob...@>=
+ @!adjust_tail:pointer; {tail of adjustment list}
++ @!line_font_variant:small_number; {used for communication between
++ |line_break| and |hpack|}
+
+ @ @<Set init...@>=adjust_tail:=null; last_badness:=0;
+
+ @ Here now is |hpack|, which contains few if any surprises.
+
+! @p function effective_glue_overshrink : integer;
+! begin
+! if glue_overshrink<1000 then effective_glue_overshrink:=1000
+! else effective_glue_overshrink:=glue_overshrink;
+! end;
+!
+! function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
+ label reswitch, common_ending, exit;
+ var r:pointer; {the box node that will be returned}
+ @!q:pointer; {trails behind |p|}
+***************
+*** 12870,12875 ****
+--- 12910,12916 ----
+ @!f:internal_font_number; {the font in a |char_node|}
+ @!i:four_quarters; {font information about a |char_node|}
+ @!hd:eight_bits; {height and depth indices for a character}
++ @!max_shrink:scaled;
+ begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node;
+ subtype(r):=min_quarterword; shift_amount(r):=0;
+ q:=r+list_offset; link(q):=p;@/
+***************
+*** 12937,12945 ****
+ character of text to the user's input will cause each of these instructions
+ to be exercised one more time.
+ @^inner loop@>
+
+ @<Incorporate character dimensions into the dimensions of the hbox...@>=
+! begin f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i);
+ x:=x+char_width(f)(i);@/
+ s:=char_height(f)(hd);@+if s>h then h:=s;
+ s:=char_depth(f)(hd);@+if s>d then d:=s;
+--- 12978,12998 ----
+ character of text to the user's input will cause each of these instructions
+ to be exercised one more time.
+ @^inner loop@>
++ This is also the place where the proper font variants are selected.
++
++ @d very_condensed_font=0
++ @d condensed_font=1
++ @d normal_font=2
++ @d extended_font=3
++ @d very_extended_font=4
+
+ @<Incorporate character dimensions into the dimensions of the hbox...@>=
+! begin
+! if line_font_variant<normal_font then
+! font(p):=font_variants[font(p)][line_font_variant]
+! else if line_font_variant>normal_font then
+! font(p):=font_variants[font(p)][line_font_variant-1];
+! f:=font(p); i:=char_info(f)(character(p)); hd:=height_depth(i);
+ x:=x+char_width(f)(i);@/
+ s:=char_height(f)(hd);@+if s>h then h:=s;
+ s:=char_depth(f)(hd);@+if s>d then d:=s;
+***************
+*** 13036,13049 ****
+ pack_begin_line:=0;
+
+ @ @<Finish issuing a diagnostic message for an overfull or underfull hbox@>=
+! if output_active then print(") has occurred while \output is active")
+ else begin if pack_begin_line<>0 then
+! begin if pack_begin_line>0 then print(") in paragraph at lines ")
+! else print(") in alignment at lines ");
+ print_int(abs(pack_begin_line));
+ print("--");
+ end
+! else print(") detected at line ");
+ print_int(line);
+ end;
+ print_ln;@/
+--- 13089,13109 ----
+ pack_begin_line:=0;
+
+ @ @<Finish issuing a diagnostic message for an overfull or underfull hbox@>=
+! case line_font_variant of
+! very_condensed_font: print(") (very condensed)");
+! condensed_font: print(") (condensed)");
+! normal_font: print(") (normal)");
+! extended_font: print(") (extended)");
+! very_extended_font: print(") (very extended)");
+! endcases;
+! if output_active then print(" has occurred while \output is active")
+ else begin if pack_begin_line<>0 then
+! begin if pack_begin_line>0 then print(" in paragraph at lines ")
+! else print(" in alignment at lines ");
+ print_int(abs(pack_begin_line));
+ print("--");
+ end
+! else print(" detected at line ");
+ print_int(line);
+ end;
+ print_ln;@/
+***************
+*** 13058,13066 ****
+ else begin glue_sign(r):=normal;
+ set_glue_ratio_zero(glue_set(r)); {there's nothing to shrink}
+ end;
+! if (total_shrink[o]<-x)and(o=normal)and(list_ptr(r)<>null) then
+ begin last_badness:=1000000;
+! set_glue_ratio_one(glue_set(r)); {use the maximum shrinkage}
+ @<Report an overfull hbox and |goto common_ending|, if this box
+ is sufficiently bad@>;
+ end
+--- 13118,13127 ----
+ else begin glue_sign(r):=normal;
+ set_glue_ratio_zero(glue_set(r)); {there's nothing to shrink}
+ end;
+! max_shrink:=xn_over_d(total_shrink[o],effective_glue_overshrink,1000);
+! if (max_shrink<-x)and(o=normal)and(list_ptr(r)<>null) then
+ begin last_badness:=1000000;
+! glue_set(r):=unfloat(effective_glue_overshrink/1000);
+ @<Report an overfull hbox and |goto common_ending|, if this box
+ is sufficiently bad@>;
+ end
+***************
+*** 13077,13091 ****
+ else o:=normal
+
+ @ @<Report an overfull hbox and |goto common_ending|, if...@>=
+! if (-x-total_shrink[normal]>hfuzz)or(hbadness<100) then
+! begin if (overfull_rule>0)and(-x-total_shrink[normal]>hfuzz) then
+ begin while link(q)<>null do q:=link(q);
+ link(q):=new_rule;
+ width(link(q)):=overfull_rule;
+ end;
+ print_ln; print_nl("Overfull \hbox (");
+ @.Overfull \\hbox...@>
+! print_scaled(-x-total_shrink[normal]); print("pt too wide");
+ goto common_ending;
+ end
+
+--- 13138,13152 ----
+ else o:=normal
+
+ @ @<Report an overfull hbox and |goto common_ending|, if...@>=
+! if (-x-max_shrink>hfuzz)or(hbadness<100) then
+! begin if (overfull_rule>0)and(-x-max_shrink>hfuzz) then
+ begin while link(q)<>null do q:=link(q);
+ link(q):=new_rule;
+ width(link(q)):=overfull_rule;
+ end;
+ print_ln; print_nl("Overfull \hbox (");
+ @.Overfull \\hbox...@>
+! print_scaled(-x-max_shrink); print("pt too wide");
+ goto common_ending;
+ end
+
+***************
+*** 16038,16056 ****
+ @ When looking for optimal line breaks, \TeX\ creates a ``break node'' for
+ each break that is {\sl feasible}, in the sense that there is a way to end
+ a line at the given place without requiring any line to stretch more than
+! a given tolerance. A break node is characterized by three things: the position
+ of the break (which is a pointer to a |glue_node|, |math_node|, |penalty_node|,
+ or |disc_node|); the ordinal number of the line that will follow this
+! breakpoint; and the fitness classification of the line that has just
+! ended, i.e., |tight_fit|, |decent_fit|, |loose_fit|, or |very_loose_fit|.
+!
+! @d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their
+ shrinkability}
+! @d loose_fit=1 {fitness classification for lines stretching 0.5 to 1.0 of their
+ stretchability}
+! @d very_loose_fit=0 {fitness classification for lines stretching more than
+ their stretchability}
+! @d decent_fit=2 {fitness classification for all other lines}
+
+ @ The algorithm essentially determines the best possible way to achieve
+ each feasible combination of position, line, and fitness. Thus, it answers
+--- 16099,16124 ----
+ @ When looking for optimal line breaks, \TeX\ creates a ``break node'' for
+ each break that is {\sl feasible}, in the sense that there is a way to end
+ a line at the given place without requiring any line to stretch more than
+! a given tolerance. A break node is characterized by four things: the position
+ of the break (which is a pointer to a |glue_node|, |math_node|, |penalty_node|,
+ or |disc_node|); the ordinal number of the line that will follow this
+! breakpoint, the fitness classification of the line that has just
+! ended, i.e., |very_tight_fit|, |tight_fit|, |decent_fit|,
+! |loose_fit|, |very_loose_fit|, or |extremely_loose_fit|, and the font variant
+! to be used, |very_condensed_font|, |condensed_font|, |normal_font|,
+! |extended_font| or |very_extended_font|.
+!
+! @d very_tight_fit=5 {fitness classification for lines shrinking more than their
+! shrinkability}
+! @d tight_fit=4 {fitness classification for lines shrinking 0.5 to 1.0 of their
+ shrinkability}
+! @d decent_fit=3 {fitness classification for all other lines}
+! @d loose_fit=2 {fitness classification for lines stretching 0.5 to 1.0 of their
+ stretchability}
+! @d very_loose_fit=1 {fitness classification for lines stretching 1.0 to 2.0 of
+ their stretchability}
+! @d extremely_loose_fit=0 {fitness classification for lines stretching more
+! than 2.0 of their stretchability}
+
+ @ The algorithm essentially determines the best possible way to achieve
+ each feasible combination of position, line, and fitness. Thus, it answers
+***************
+*** 16063,16069 ****
+
+ An ``active node'' and a ``passive node'' are created in |mem| for each
+ feasible breakpoint that needs to be considered. Active nodes are three
+! words long and passive nodes are two words long. We need active nodes only
+ for breakpoints near the place in the paragraph that is currently being
+ examined, so they are recycled within a comparatively short time after
+ they are created.
+--- 16131,16137 ----
+
+ An ``active node'' and a ``passive node'' are created in |mem| for each
+ feasible breakpoint that needs to be considered. Active nodes are three
+! words long and passive nodes are too. We need active nodes only
+ for breakpoints near the place in the paragraph that is currently being
+ examined, so they are recycled within a comparatively short time after
+ they are created.
+***************
+*** 16095,16101 ****
+ to each other.
+
+ @d active_node_size=3 {number of words in active nodes}
+! @d fitness==subtype {|very_loose_fit..tight_fit| on final line for this break}
+ @d break_node==rlink {pointer to the corresponding passive node}
+ @d line_number==llink {line that begins at this breakpoint}
+ @d total_demerits(#)==mem[#+2].int {the quantity that \TeX\ minimizes}
+--- 16163,16170 ----
+ to each other.
+
+ @d active_node_size=3 {number of words in active nodes}
+! @d fitness==subtype {|extremely_loose_fit..very_tight_fit| on final line for this
+! break}
+ @d break_node==rlink {pointer to the corresponding passive node}
+ @d line_number==llink {line that begins at this breakpoint}
+ @d total_demerits(#)==mem[#+2].int {the quantity that \TeX\ minimizes}
+***************
+*** 16107,16113 ****
+ type(last_active):=hyphenated; line_number(last_active):=max_halfword;
+ subtype(last_active):=0; {the |subtype| is never examined by the algorithm}
+
+! @ The passive node for a given breakpoint contains only four fields:
+
+ \yskip\hang|link| points to the passive node created just before this one,
+ if any, otherwise it is |null|.
+--- 16176,16182 ----
+ type(last_active):=hyphenated; line_number(last_active):=max_halfword;
+ subtype(last_active):=0; {the |subtype| is never examined by the algorithm}
+
+! @ The passive node for a given breakpoint contains only five fields:
+
+ \yskip\hang|link| points to the passive node created just before this one,
+ if any, otherwise it is |null|.
+***************
+*** 16122,16137 ****
+ one created during the current pass. (This field is used only when
+ printing out detailed statistics about the line-breaking calculations.)
+
+ \yskip\noindent
+ There is a global variable called |passive| that points to the most
+ recently created passive node. Another global variable, |printed_node|,
+ is used to help print out the paragraph when detailed information about
+ the line-breaking computation is being displayed.
+
+! @d passive_node_size=2 {number of words in passive nodes}
+ @d cur_break==rlink {in passive node, points to position of this breakpoint}
+ @d prev_break==llink {points to passive node that should precede this one}
+ @d serial==info {serial number for symbolic identification}
+
+ @<Glob...@>=
+ @!passive:pointer; {most recent node on passive list}
+--- 16191,16211 ----
+ one created during the current pass. (This field is used only when
+ printing out detailed statistics about the line-breaking calculations.)
+
++ \yskip\hang|condensedness| is the font variant to be used. We store this
++ information in passive nodes rather than active ones, since it has to
++ stay around till the packaging, when all active nodes are long gone.
++
+ \yskip\noindent
+ There is a global variable called |passive| that points to the most
+ recently created passive node. Another global variable, |printed_node|,
+ is used to help print out the paragraph when detailed information about
+ the line-breaking computation is being displayed.
+
+! @d passive_node_size=3 {number of words in passive nodes}
+ @d cur_break==rlink {in passive node, points to position of this breakpoint}
+ @d prev_break==llink {points to passive node that should precede this one}
+ @d serial==info {serial number for symbolic identification}
++ @d condensedness(#)==mem[#+2].int
+
+ @<Glob...@>=
+ @!passive:pointer; {most recent node on passive list}
+***************
+*** 16153,16183 ****
+ pt, fil, fill, and filll appear in |mem[q+2..q+5].sc|; and the shrink difference
+ appears in |mem[q+6].sc|. The |subtype| field of a delta node is not used.
+
+! @d delta_node_size=7 {number of words in a delta node}
+ @d delta_node=2 {|type| field in a delta node}
+
+! @ As the algorithm runs, it maintains a set of six delta-like registers
+ for the length of the line following the first active breakpoint to the
+ current position in the given hlist. When it makes a pass through the
+! active list, it also maintains a similar set of six registers for the
+ length following the active breakpoint of current interest. A third set
+ holds the length of an empty line (namely, the sum of \.{\\leftskip} and
+ \.{\\rightskip}); and a fourth set is used to create new delta nodes.
+
+ When we pass a delta node we want to do operations like
+ $$\hbox{\ignorespaces|for
+! k:=1 to 6 do cur_active_width[k]:=cur_active_width[k]+mem[q+k].sc|};$$ and we
+! want to do this without the overhead of |for| loops. The |do_all_six|
+! macro makes such six-tuples convenient.
+
+ @d do_all_six(#)==#(1);#(2);#(3);#(4);#(5);#(6)
+
+ @<Glo...@>=
+! @!active_width:array[1..6] of scaled;
+ {distance from first active node to~|cur_p|}
+! @!cur_active_width:array[1..6] of scaled; {distance from current active node}
+! @!background:array[1..6] of scaled; {length of an ``empty'' line}
+! @!break_width:array[1..6] of scaled; {length being computed after current break}
+
+ @ Let's state the principles of the delta nodes more precisely and concisely,
+ so that the following programs will be less obscure. For each legal
+--- 16227,16261 ----
+ pt, fil, fill, and filll appear in |mem[q+2..q+5].sc|; and the shrink difference
+ appears in |mem[q+6].sc|. The |subtype| field of a delta node is not used.
+
+! Delta nodes have four additional fields keeping track of the
+! difference in natural width for the font variants.
+!
+! @d delta_node_size=11 {number of words in a delta node}
+ @d delta_node=2 {|type| field in a delta node}
+
+! @ As the algorithm runs, it maintains a set of ten delta-like registers
+ for the length of the line following the first active breakpoint to the
+ current position in the given hlist. When it makes a pass through the
+! active list, it also maintains a similar set of ten registers for the
+ length following the active breakpoint of current interest. A third set
+ holds the length of an empty line (namely, the sum of \.{\\leftskip} and
+ \.{\\rightskip}); and a fourth set is used to create new delta nodes.
+
+ When we pass a delta node we want to do operations like
+ $$\hbox{\ignorespaces|for
+! k:=1 to 10 do cur_active_width[k]:=cur_active_width[k]+mem[q+k].sc|};$$ and we
+! want to do this without the overhead of |for| loops. The |do_all_ten|
+! macro makes such ten-tuples convenient. |do_all_six| is also needed.
+
+ @d do_all_six(#)==#(1);#(2);#(3);#(4);#(5);#(6)
++ @d do_all_ten(#)==#(1);#(2);#(3);#(4);#(5);#(6);#(7);#(8);#(9);#(10)
+
+ @<Glo...@>=
+! @!active_width:array[1..10] of scaled;
+ {distance from first active node to~|cur_p|}
+! @!cur_active_width:array[1..10] of scaled; {distance from current active node}
+! @!background:array[1..10] of scaled; {length of an ``empty'' line}
+! @!break_width:array[1..10] of scaled; {length being computed after current break}
+
+ @ Let's state the principles of the delta nodes more precisely and concisely,
+ so that the following programs will be less obscure. For each legal
+***************
+*** 16258,16263 ****
+--- 16336,16345 ----
+ background[2+stretch_order(q)]:=stretch(q);@/
+ background[2+stretch_order(r)]:=@|background[2+stretch_order(r)]+stretch(r);@/
+ background[6]:=shrink(q)+shrink(r);
++ background[7]:=0;
++ background[8]:=0;
++ background[9]:=0;
++ background[10]:=0;
+
+ @ A pointer variable |cur_p| runs through the given horizontal list as we look
+ for breakpoints. This variable is global, since it is used both by |line_break|
+***************
+*** 16316,16322 ****
+ @<Other local variables for |try_break|@>@;
+ begin @<Make sure that |pi| is in the proper range@>;
+ no_break_yet:=true; prev_r:=active; old_l:=0;
+! do_all_six(copy_to_cur_active);
+ loop@+ begin continue: r:=link(prev_r);
+ @<If node |r| is of type |delta_node|, update |cur_active_width|,
+ set |prev_r| and |prev_prev_r|, then |goto continue|@>;
+--- 16398,16404 ----
+ @<Other local variables for |try_break|@>@;
+ begin @<Make sure that |pi| is in the proper range@>;
+ no_break_yet:=true; prev_r:=active; old_l:=0;
+! do_all_ten(copy_to_cur_active);
+ loop@+ begin continue: r:=link(prev_r);
+ @<If node |r| is of type |delta_node|, update |cur_active_width|,
+ set |prev_r| and |prev_prev_r|, then |goto continue|@>;
+***************
+*** 16341,16348 ****
+ @!f:internal_font_number; {used in character width calculation}
+ @!l:halfword; {line number of current active node}
+ @!node_r_stays_active:boolean; {should node |r| remain in the active list?}
+ @!line_width:scaled; {the current line will be justified to this width}
+! @!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line}
+ @!b:halfword; {badness of test line}
+ @!d:integer; {demerits of test line}
+ @!artificial_demerits:boolean; {has |d| been forced to zero?}
+--- 16423,16435 ----
+ @!f:internal_font_number; {used in character width calculation}
+ @!l:halfword; {line number of current active node}
+ @!node_r_stays_active:boolean; {should node |r| remain in the active list?}
++ @!do_not_consider:boolean;
+ @!line_width:scaled; {the current line will be justified to this width}
+! @!fit_class:extremely_loose_fit..very_tight_fit; {possible fitness class of
+! test line}
+! @!condensed_class,prev_cc:very_condensed_font..very_extended_font;
+! @!cw:scaled;
+! @!j:small_number;
+ @!b:halfword; {badness of test line}
+ @!d:integer; {demerits of test line}
+ @!artificial_demerits:boolean; {has |d| been forced to zero?}
+***************
+*** 16362,16368 ****
+ @<If node |r|...@>=
+ @^inner loop@>
+ if type(r)=delta_node then
+! begin do_all_six(update_width);
+ prev_prev_r:=prev_r; prev_r:=r; goto continue;
+ end
+
+--- 16449,16455 ----
+ @<If node |r|...@>=
+ @^inner loop@>
+ if type(r)=delta_node then
+! begin do_all_ten(update_width);
+ prev_prev_r:=prev_r; prev_r:=r; goto continue;
+ end
+
+***************
+*** 16381,16401 ****
+ @d awful_bad==@'7777777777 {more than a billion demerits}
+
+ @<Global...@>=
+! @!minimal_demerits:array[very_loose_fit..tight_fit] of integer; {best total
+! demerits known for current line class and position, given the fitness}
+ @!minimum_demerits:integer; {best total demerits known for current line class
+ and position}
+! @!best_place:array[very_loose_fit..tight_fit] of pointer; {how to achieve
+ |minimal_demerits|}
+! @!best_pl_line:array[very_loose_fit..tight_fit] of halfword; {corresponding
+ line number}
+
+ @ @<Get ready to start...@>=
+ minimum_demerits:=awful_bad;
+! minimal_demerits[tight_fit]:=awful_bad;
+! minimal_demerits[decent_fit]:=awful_bad;
+! minimal_demerits[loose_fit]:=awful_bad;
+! minimal_demerits[very_loose_fit]:=awful_bad;
+
+ @ The first part of the following code is part of \TeX's inner loop, so
+ we don't want to waste any time. The current active node, namely node |r|,
+--- 16468,16490 ----
+ @d awful_bad==@'7777777777 {more than a billion demerits}
+
+ @<Global...@>=
+! @!minimal_demerits:array[extremely_loose_fit..very_tight_fit,
+! very_condensed_font..very_extended_font] of integer; {best total
+! demerits known for current line class and position, given the fitness and condensedness}
+ @!minimum_demerits:integer; {best total demerits known for current line class
+ and position}
+! @!best_place:array[extremely_loose_fit..very_tight_fit,
+! very_condensed_font..very_extended_font] of pointer; {how to achieve
+ |minimal_demerits|}
+! @!best_pl_line:array[extremely_loose_fit..very_tight_fit,
+! very_condensed_font..very_extended_font] of halfword; {corresponding
+ line number}
+
+ @ @<Get ready to start...@>=
+ minimum_demerits:=awful_bad;
+! for l:=extremely_loose_fit to very_tight_fit do
+! for j:=very_condensed_font to very_extended_font do
+! minimal_demerits[l][j]:=awful_bad;
+
+ @ The first part of the following code is part of \TeX's inner loop, so
+ we don't want to waste any time. The current active node, namely node |r|,
+***************
+*** 16429,16439 ****
+ if abs(adj_demerits)>=awful_bad-minimum_demerits then
+ minimum_demerits:=awful_bad-1
+ else minimum_demerits:=minimum_demerits+abs(adj_demerits);
+! for fit_class:=very_loose_fit to tight_fit do
+! begin if minimal_demerits[fit_class]<=minimum_demerits then
+ @<Insert a new active node
+ from |best_place[fit_class]| to |cur_p|@>;
+! minimal_demerits[fit_class]:=awful_bad;
+ end;
+ minimum_demerits:=awful_bad;
+ @<Insert a delta node to prepare for the next active node@>;
+--- 16518,16529 ----
+ if abs(adj_demerits)>=awful_bad-minimum_demerits then
+ minimum_demerits:=awful_bad-1
+ else minimum_demerits:=minimum_demerits+abs(adj_demerits);
+! for fit_class:=extremely_loose_fit to very_tight_fit do
+! for condensed_class:=very_condensed_font to very_extended_font do
+! begin if minimal_demerits[fit_class][condensed_class]<=minimum_demerits then
+ @<Insert a new active node
+ from |best_place[fit_class]| to |cur_p|@>;
+! minimal_demerits[fit_class][condensed_class]:=awful_bad;
+ end;
+ minimum_demerits:=awful_bad;
+ @<Insert a delta node to prepare for the next active node@>;
+***************
+*** 16461,16467 ****
+ @d set_break_width_to_background(#)==break_width[#]:=background[#]
+
+ @<Compute the values of |break...@>=
+! begin no_break_yet:=false; do_all_six(set_break_width_to_background);
+ s:=cur_p;
+ if break_type>unhyphenated then if cur_p<>null then
+ @<Compute the discretionary |break_width| values@>;
+--- 16551,16557 ----
+ @d set_break_width_to_background(#)==break_width[#]:=background[#]
+
+ @<Compute the values of |break...@>=
+! begin no_break_yet:=false; do_all_ten(set_break_width_to_background);
+ s:=cur_p;
+ if break_type>unhyphenated then if cur_p<>null then
+ @<Compute the discretionary |break_width| values@>;
+***************
+*** 16524,16536 ****
+ @<Subtract the width of node |v|...@>=
+ if is_char_node(v) then
+ begin f:=font(v);
+! break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(v)));
+! end
+! else case type(v) of
+ ligature_node: begin f:=font(lig_char(v));@/
+! break_width[1]:=@|break_width[1]-
+! char_width(f)(char_info(f)(character(lig_char(v))));
+! end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]-width(v);
+ othercases confusion("disc1")
+--- 16614,16638 ----
+ @<Subtract the width of node |v|...@>=
+ if is_char_node(v) then
+ begin f:=font(v);
+! cw:=char_width(f)(char_info(f)(character(v)));
+! break_width[1]:=break_width[1]-cw;
+! for j:=0 to 3 do
+! break_width[7+j]:=break_width[7+j]
+! -(char_width(font_variants[f][j])
+! (char_info(font_variants[f][j])
+! (character(v)))
+! -cw);
+! end else case type(v) of
+ ligature_node: begin f:=font(lig_char(v));@/
+! cw:=char_width(f)(char_info(f)(character(lig_char(v))));
+! break_width[1]:=@|break_width[1]-cw;
+! for j:=0 to 3 do
+! break_width[7+j]:=break_width[7+j]
+! -(char_width(font_variants[f][j])
+! (char_info(font_variants[f][j])
+! (character(lig_char(v))))
+! -cw);
+! end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]-width(v);
+ othercases confusion("disc1")
+***************
+*** 16540,16552 ****
+ @ @<Add the width of node |s| to |b...@>=
+ if is_char_node(s) then
+ begin f:=font(s);
+! break_width[1]:=@|break_width[1]+char_width(f)(char_info(f)(character(s)));
+! end
+! else case type(s) of
+ ligature_node: begin f:=font(lig_char(s));
+! break_width[1]:=break_width[1]+
+! char_width(f)(char_info(f)(character(lig_char(s))));
+! end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]+width(s);
+ othercases confusion("disc2")
+--- 16642,16666 ----
+ @ @<Add the width of node |s| to |b...@>=
+ if is_char_node(s) then
+ begin f:=font(s);
+! cw:=char_width(f)(char_info(f)(character(s)));
+! break_width[1]:=@|break_width[1]+cw;
+! for j:=0 to 3 do
+! break_width[7+j]:=break_width[7+j]
+! +(char_width(font_variants[f][j])
+! (char_info(font_variants[f][j])
+! (character(s)))
+! -cw);
+! end else case type(s) of
+ ligature_node: begin f:=font(lig_char(s));
+! cw:=char_width(f)(char_info(f)(character(lig_char(s))));
+! break_width[1]:=break_width[1]+cw;
+! for j:=0 to 3 do
+! break_width[7+j]:=break_width[7+j]
+! +(char_width(font_variants[f][j])
+! (char_info(font_variants[f][j])
+! (character(lig_char(s))))
+! -cw);
+! end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]+width(s);
+ othercases confusion("disc2")
+***************
+*** 16564,16577 ****
+
+ @<Insert a delta node to prepare for breaks at |cur_p|@>=
+ if type(prev_r)=delta_node then {modify an existing delta node}
+! begin do_all_six(convert_to_break_width);
+ end
+ else if prev_r=active then {no delta node needed at the beginning}
+! begin do_all_six(store_break_width);
+ end
+ else begin q:=get_node(delta_node_size); link(q):=r; type(q):=delta_node;@/
+ subtype(q):=0; {the |subtype| is not used}
+! do_all_six(new_delta_to_break_width);
+ link(prev_r):=q; prev_prev_r:=prev_r; prev_r:=q;
+ end
+
+--- 16678,16691 ----
+
+ @<Insert a delta node to prepare for breaks at |cur_p|@>=
+ if type(prev_r)=delta_node then {modify an existing delta node}
+! begin do_all_ten(convert_to_break_width);
+ end
+ else if prev_r=active then {no delta node needed at the beginning}
+! begin do_all_ten(store_break_width);
+ end
+ else begin q:=get_node(delta_node_size); link(q):=r; type(q):=delta_node;@/
+ subtype(q):=0; {the |subtype| is not used}
+! do_all_ten(new_delta_to_break_width);
+ link(prev_r):=q; prev_prev_r:=prev_r; prev_r:=q;
+ end
+
+***************
+*** 16585,16591 ****
+ if r<>last_active then
+ begin q:=get_node(delta_node_size); link(q):=r; type(q):=delta_node;@/
+ subtype(q):=0; {the |subtype| is not used}
+! do_all_six(new_delta_from_break_width);
+ link(prev_r):=q; prev_prev_r:=prev_r; prev_r:=q;
+ end
+
+--- 16699,16705 ----
+ if r<>last_active then
+ begin q:=get_node(delta_node_size); link(q):=r; type(q):=delta_node;@/
+ subtype(q):=0; {the |subtype| is not used}
+! do_all_ten(new_delta_from_break_width);
+ link(prev_r):=q; prev_prev_r:=prev_r; prev_r:=q;
+ end
+
+***************
+*** 16596,16606 ****
+ begin q:=get_node(passive_node_size);
+ link(q):=passive; passive:=q; cur_break(q):=cur_p;
+ @!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/
+! prev_break(q):=best_place[fit_class];@/
+ q:=get_node(active_node_size); break_node(q):=passive;
+! line_number(q):=best_pl_line[fit_class]+1;
+ fitness(q):=fit_class; type(q):=break_type;
+! total_demerits(q):=minimal_demerits[fit_class];
+ link(q):=r; link(prev_r):=q; prev_r:=q;
+ @!stat if tracing_paragraphs>0 then
+ @<Print a symbolic description of the new break node@>;
+--- 16710,16721 ----
+ begin q:=get_node(passive_node_size);
+ link(q):=passive; passive:=q; cur_break(q):=cur_p;
+ @!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/
+! condensedness(q):=condensed_class;
+! prev_break(q):=best_place[fit_class][condensed_class];@/
+ q:=get_node(active_node_size); break_node(q):=passive;
+! line_number(q):=best_pl_line[fit_class][condensed_class]+1;
+ fitness(q):=fit_class; type(q):=break_type;
+! total_demerits(q):=minimal_demerits[fit_class][condensed_class];
+ link(q):=r; link(prev_r):=q; prev_r:=q;
+ @!stat if tracing_paragraphs>0 then
+ @<Print a symbolic description of the new break node@>;
+***************
+*** 16612,16617 ****
+--- 16727,16733 ----
+ @.\AT!\AT!@>
+ print(": line "); print_int(line_number(q)-1);
+ print_char("."); print_int(fit_class);
++ print_char("."); print_int(condensed_class);
+ if break_type=hyphenated then print_char("-");
+ print(" t="); print_int(total_demerits(q));
+ print(" -> @@@@");
+***************
+*** 16703,16727 ****
+ We also deactivate node~|r| when a break at~|cur_p| is forced, since future
+ breaks must go through a forced break.
+
+ @<Consider the demerits for a line from |r| to |cur_p|...@>=
+ begin artificial_demerits:=false;@/
+ @^inner loop@>
+! shortfall:=line_width-cur_active_width[1]; {we're this much too short}
+! if shortfall>0 then
+! @<Set the value of |b| to the badness for stretching the line,
+! and compute the corresponding |fit_class|@>
+! else @<Set the value of |b| to the badness for shrinking the line,
+! and compute the corresponding |fit_class|@>;
+! if (b>inf_bad)or(pi=eject_penalty) then
+! @<Prepare to deactivate node~|r|, and |goto deactivate| unless
+! there is a reason to consider lines of text from |r| to |cur_p|@>
+! else begin prev_r:=r;
+! if b>threshold then goto continue;
+! node_r_stays_active:=true;
+! end;
+! @<Record a new feasible break@>;
+! if node_r_stays_active then goto continue; {|prev_r| has been set to |r|}
+! deactivate: @<Deactivate node |r|@>;
+ end
+
+ @ When a line must stretch, the available stretchability can be found in the
+--- 16819,16859 ----
+ We also deactivate node~|r| when a break at~|cur_p| is forced, since future
+ breaks must go through a forced break.
+
++ The program logic in this section is really f***ed up!!!
++
+ @<Consider the demerits for a line from |r| to |cur_p|...@>=
+ begin artificial_demerits:=false;@/
+ @^inner loop@>
+! node_r_stays_active:=false;
+! for condensed_class:=very_condensed_font to very_extended_font do begin
+! do_not_consider:=false;
+! shortfall:=line_width-cur_active_width[1];
+! case condensed_class of
+! very_condensed_font:shortfall:=shortfall-cur_active_width[7];
+! condensed_font: shortfall:=shortfall-cur_active_width[8];
+! extended_font: shortfall:=shortfall-cur_active_width[9];
+! very_extended_font: shortfall:=shortfall-cur_active_width[10];
+! endcases;
+! if shortfall>0 then
+! @<Set the value of |b| to the badness for stretching the line,
+! and compute the corresponding |fit_class|@>
+! else
+! @<Set the value of |b| to the badness for shrinking the line,
+! and compute the corresponding |fit_class|@>;
+! if (b>inf_bad)or(pi=eject_penalty) then begin
+! if final_pass and (minimum_demerits=awful_bad) and@|
+! (link(r)=last_active) and
+! (prev_r=active) then
+! artificial_demerits:=true {set demerits zero, this break is forced}
+! else if b>threshold then do_not_consider:=true;
+! end else begin
+! node_r_stays_active:=true;
+! if b>threshold then do_not_consider:=true;
+! end;
+! if not do_not_consider then @<Record a new feasible break@>
+! end;
+! if node_r_stays_active then prev_r:=r
+! else @<Deactivate node |r|@>;
+ end
+
+ @ When a line must stretch, the available stretchability can be found in the
+***************
+*** 16738,16789 ****
+ (cur_active_width[5]<>0) then
+ begin b:=0; fit_class:=decent_fit; {infinite stretch}
+ end
+! else begin if shortfall>7230584 then if cur_active_width[2]<1663497 then
+! begin b:=inf_bad; fit_class:=very_loose_fit; goto done1;
+! end;
+ b:=badness(shortfall,cur_active_width[2]);
+ if b>12 then
+! if b>99 then fit_class:=very_loose_fit
+ else fit_class:=loose_fit
+ else fit_class:=decent_fit;
+- done1:
+ end
+
+ @ Shrinkability is never infinite in a paragraph;
+ we can shrink the line from |r| to |cur_p| by at most |cur_active_width[6]|.
+
+ @<Set the value of |b| to the badness for shrinking...@>=
+! begin if -shortfall>cur_active_width[6] then b:=inf_bad+1
+ else b:=badness(-shortfall,cur_active_width[6]);
+! if b>12 then fit_class:=tight_fit@+else fit_class:=decent_fit;
+! end
+!
+! @ During the final pass, we dare not lose all active nodes, lest we lose
+! touch with the line breaks already found. The code shown here makes sure
+! that such a catastrophe does not happen, by permitting overfull boxes as
+! a last resort. This particular part of \TeX\ was a source of several subtle
+! bugs before the correct program logic was finally discovered; readers
+! who seek to ``improve'' \TeX\ should therefore think thrice before daring
+! to make any changes here.
+! @^overfull boxes@>
+!
+! @<Prepare to deactivate node~|r|, and |goto deactivate| unless...@>=
+! begin if final_pass and (minimum_demerits=awful_bad) and@|
+! (link(r)=last_active) and
+! (prev_r=active) then
+! artificial_demerits:=true {set demerits zero, this break is forced}
+! else if b>threshold then goto deactivate;
+! node_r_stays_active:=false;
+ end
+
+ @ When we get to this part of the code, the line from |r| to |cur_p| is
+ feasible, its badness is~|b|, and its fitness classification is |fit_class|.
+ We don't want to make an active node for this break yet, but we will
+ compute the total demerits and record them in the |minimal_demerits| array,
+ if such a break is the current champion among all ways to get to |cur_p|
+ in a given line-number class and fitness class.
+
+ @<Record a new feasible break@>=
+ if artificial_demerits then d:=0
+ else @<Compute the demerits, |d|, from |r| to |cur_p|@>;
+ @!stat if tracing_paragraphs>0 then
+--- 16870,16906 ----
+ (cur_active_width[5]<>0) then
+ begin b:=0; fit_class:=decent_fit; {infinite stretch}
+ end
+! else begin
+ b:=badness(shortfall,cur_active_width[2]);
+ if b>12 then
+! if b>99 then
+! if b>799 then fit_class:=extremely_loose_fit
+! else fit_class:=very_loose_fit
+ else fit_class:=loose_fit
+ else fit_class:=decent_fit;
+ end
+
+ @ Shrinkability is never infinite in a paragraph;
+ we can shrink the line from |r| to |cur_p| by at most |cur_active_width[6]|.
+
+ @<Set the value of |b| to the badness for shrinking...@>=
+! begin
+! if xn_over_d(-shortfall,1000,effective_glue_overshrink)>cur_active_width[6] then b:=inf_bad+1
+ else b:=badness(-shortfall,cur_active_width[6]);
+! if b>100 then fit_class:= very_tight_fit
+! else if b>12 then fit_class:=tight_fit@+else fit_class:=decent_fit;
+ end
+
+ @ When we get to this part of the code, the line from |r| to |cur_p| is
+ feasible, its badness is~|b|, and its fitness classification is |fit_class|.
++ And its condensedness classification is |condensed_class|.
+ We don't want to make an active node for this break yet, but we will
+ compute the total demerits and record them in the |minimal_demerits| array,
+ if such a break is the current champion among all ways to get to |cur_p|
+ in a given line-number class and fitness class.
+
+ @<Record a new feasible break@>=
++ begin
+ if artificial_demerits then d:=0
+ else @<Compute the demerits, |d|, from |r| to |cur_p|@>;
+ @!stat if tracing_paragraphs>0 then
+***************
+*** 16791,16801 ****
+ tats@;@/
+ d:=d+total_demerits(r); {this is the minimum total demerits
+ from the beginning to |cur_p| via |r|}
+! if d<=minimal_demerits[fit_class] then
+! begin minimal_demerits[fit_class]:=d;
+! best_place[fit_class]:=break_node(r); best_pl_line[fit_class]:=l;
+ if d<minimum_demerits then minimum_demerits:=d;
+ end
+
+ @ @<Print a symbolic description of this feasible break@>=
+ begin if printed_node<>cur_p then
+--- 16908,16920 ----
+ tats@;@/
+ d:=d+total_demerits(r); {this is the minimum total demerits
+ from the beginning to |cur_p| via |r|}
+! if d<=minimal_demerits[fit_class][condensed_class] then
+! begin minimal_demerits[fit_class][condensed_class]:=d;
+! best_place[fit_class][condensed_class]:=break_node(r);
+! best_pl_line[fit_class][condensed_class]:=l;
+ if d<minimum_demerits then minimum_demerits:=d;
+ end
++ end
+
+ @ @<Print a symbolic description of this feasible break@>=
+ begin if printed_node<>cur_p then
+***************
+*** 16818,16823 ****
+--- 16937,16945 ----
+ @.*\relax@>
+ print(" p="); print_int(pi); print(" d=");
+ if artificial_demerits then print_char("*")@+else print_int(d);
++ print(" "); print_int(fit_class);
++ print("."); print_int(condensed_class);
++ print(" t="); print_int(d+total_demerits(r));
+ end
+
+ @ @<Print the list between |printed_node| and |cur_p|...@>=
+***************
+*** 16852,16858 ****
+ if (break_type=hyphenated)and(type(r)=hyphenated) then
+ if cur_p<>null then d:=d+double_hyphen_demerits
+ else d:=d+final_hyphen_demerits;
+! if abs(fit_class-fitness(r))>1 then d:=d+adj_demerits;
+ end
+
+ @ When an active node disappears, we must delete an adjacent delta node if the
+--- 16974,16991 ----
+ if (break_type=hyphenated)and(type(r)=hyphenated) then
+ if cur_p<>null then d:=d+double_hyphen_demerits
+ else d:=d+final_hyphen_demerits;
+! case abs(fit_class-fitness(r)) of
+! 0,1: do_nothing;
+! 2: d:=d+adj_demerits;
+! othercases d:=d+adj_demerits+extra_adj_demerits;
+! endcases;
+! if break_node(r)=null then prev_cc:=normal_font
+! else prev_cc:=condensedness(break_node(r));
+! case abs(condensed_class-prev_cc) of
+! 0,1: do_nothing;
+! 2: d:=d+font_demerits;
+! othercases d:=d+font_demerits+extra_font_demerits;
+! endcases;
+ end
+
+ @ When an active node disappears, we must delete an adjacent delta node if the
+***************
+*** 16866,16887 ****
+ mem[prev_r+#].sc
+
+ @<Deactivate node |r|@>=
+ link(prev_r):=link(r); free_node(r,active_node_size);
+ if prev_r=active then @<Update the active widths, since the first active
+ node has been deleted@>
+ else if type(prev_r)=delta_node then
+ begin r:=link(prev_r);
+ if r=last_active then
+! begin do_all_six(downdate_width);
+ link(prev_prev_r):=last_active;
+ free_node(prev_r,delta_node_size); prev_r:=prev_prev_r;
+ end
+ else if type(r)=delta_node then
+! begin do_all_six(update_width);
+! do_all_six(combine_two_deltas);
+ link(prev_r):=link(r); free_node(r,delta_node_size);
+ end;
+ end
+
+ @ The following code uses the fact that |type(last_active)<>delta_node|. If the
+ active list has just become empty, we do not need to update the
+--- 16999,17022 ----
+ mem[prev_r+#].sc
+
+ @<Deactivate node |r|@>=
++ begin
+ link(prev_r):=link(r); free_node(r,active_node_size);
+ if prev_r=active then @<Update the active widths, since the first active
+ node has been deleted@>
+ else if type(prev_r)=delta_node then
+ begin r:=link(prev_r);
+ if r=last_active then
+! begin do_all_ten(downdate_width);
+ link(prev_prev_r):=last_active;
+ free_node(prev_r,delta_node_size); prev_r:=prev_prev_r;
+ end
+ else if type(r)=delta_node then
+! begin do_all_ten(update_width);
+! do_all_ten(combine_two_deltas);
+ link(prev_r):=link(r); free_node(r,delta_node_size);
+ end;
+ end
++ end
+
+ @ The following code uses the fact that |type(last_active)<>delta_node|. If the
+ active list has just become empty, we do not need to update the
+***************
+*** 16893,16900 ****
+ @<Update the active widths,...@>=
+ begin r:=link(active);
+ if type(r)=delta_node then
+! begin do_all_six(update_active);
+! do_all_six(copy_to_cur_active);
+ link(active):=link(r); free_node(r,delta_node_size);
+ end;
+ end
+--- 17028,17035 ----
+ @<Update the active widths,...@>=
+ begin r:=link(active);
+ if type(r)=delta_node then
+! begin do_all_ten(update_active);
+! do_all_ten(copy_to_cur_active);
+ link(active):=link(r); free_node(r,delta_node_size);
+ end;
+ end
+***************
+*** 16921,16929 ****
+--- 17056,17066 ----
+
+ @<Local variables for line breaking@>=
+ @!auto_breaking:boolean; {is node |cur_p| outside a formula?}
++ @!cw:scaled;
+ @!prev_p:pointer; {helps to determine when glue nodes are breakpoints}
+ @!q,@!r,@!s,@!prev_s:pointer; {miscellaneous nodes of temporary interest}
+ @!f:internal_font_number; {used when calculating character widths}
++ @!l:small_number;
+
+ @ The `\ignorespaces|loop|\unskip' in the following code is performed at most
+ thrice per call of |line_break|, since it is actually a pass over the
+***************
+*** 16978,16984 ****
+ type(q):=unhyphenated; fitness(q):=decent_fit;
+ link(q):=last_active; break_node(q):=null;
+ line_number(q):=prev_graf+1; total_demerits(q):=0; link(active):=q;
+! do_all_six(store_background);@/
+ passive:=null; printed_node:=temp_head; pass_number:=0;
+ font_in_short_display:=null_font
+
+--- 17115,17121 ----
+ type(q):=unhyphenated; fitness(q):=decent_fit;
+ link(q):=last_active; break_node(q):=null;
+ line_number(q):=prev_graf+1; total_demerits(q):=0; link(active):=q;
+! do_all_ten(store_background);@/
+ passive:=null; printed_node:=temp_head; pass_number:=0;
+ font_in_short_display:=null_font
+
+***************
+*** 17024,17031 ****
+ kern_node: if subtype(cur_p)=explicit then kern_break
+ else act_width:=act_width+width(cur_p);
+ ligature_node: begin f:=font(lig_char(cur_p));
+! act_width:=act_width+char_width(f)(char_info(f)(character(lig_char(cur_p))));
+! end;
+ disc_node: @<Try to break after a discretionary fragment, then |goto done5|@>;
+ math_node: begin auto_breaking:=(subtype(cur_p)=after); kern_break;
+ end;
+--- 17161,17175 ----
+ kern_node: if subtype(cur_p)=explicit then kern_break
+ else act_width:=act_width+width(cur_p);
+ ligature_node: begin f:=font(lig_char(cur_p));
+! cw:=char_width(f)(char_info(f)(character(lig_char(cur_p))));
+! act_width:=act_width+cw;
+! for j:=0 to 3 do
+! active_width[7+j]:=active_width[7+j]
+! +(char_width(font_variants[f][j])
+! (char_info(font_variants[f][j])
+! (character(lig_char(cur_p))))
+! -cw);
+! end;
+ disc_node: @<Try to break after a discretionary fragment, then |goto done5|@>;
+ math_node: begin auto_breaking:=(subtype(cur_p)=after); kern_break;
+ end;
+***************
+*** 17047,17053 ****
+ @<Advance \(c)|cur_p| to the node following the present string...@>=
+ begin prev_p:=cur_p;
+ repeat f:=font(cur_p);
+! act_width:=act_width+char_width(f)(char_info(f)(character(cur_p)));
+ cur_p:=link(cur_p);
+ until not is_char_node(cur_p);
+ end
+--- 17191,17204 ----
+ @<Advance \(c)|cur_p| to the node following the present string...@>=
+ begin prev_p:=cur_p;
+ repeat f:=font(cur_p);
+! cw:=char_width(f)(char_info(f)(character(cur_p)));
+! act_width:=act_width+cw;
+! for j:=0 to 3 do
+! active_width[7+j]:=active_width[7+j]
+! +(char_width(font_variants[f][j])
+! (char_info(font_variants[f][j])
+! (character(cur_p)))
+! -cw);
+ cur_p:=link(cur_p);
+ until not is_char_node(cur_p);
+ end
+***************
+*** 17378,17384 ****
+ else begin cur_width:=mem[par_shape_ptr+2*cur_line].sc;
+ cur_indent:=mem[par_shape_ptr+2*cur_line-1].sc;
+ end;
+! adjust_tail:=adjust_head; just_box:=hpack(q,cur_width,exactly);
+ shift_amount(just_box):=cur_indent
+
+ @ Penalties between the lines of a paragraph come from club and widow lines,
+--- 17529,17538 ----
+ else begin cur_width:=mem[par_shape_ptr+2*cur_line].sc;
+ cur_indent:=mem[par_shape_ptr+2*cur_line-1].sc;
+ end;
+! adjust_tail:=adjust_head;
+! line_font_variant:=condensedness(cur_p);
+! just_box:=hpack(q,cur_width,exactly);
+! line_font_variant:=normal_font;
+ shift_amount(just_box):=cur_indent
+
+ @ Penalties between the lines of a paragraph come from club and widow lines,
+***************
+*** 23263,23271 ****
+ @ Here is where the information for a new font gets loaded.
+
+ @<Assignments@>=
+! def_font: new_font(a);
+!
+ @ @<Declare subprocedures for |prefixed_command|@>=
+ procedure new_font(@!a:small_number);
+ label common_ending;
+ var u:pointer; {user's font identifier}
+--- 23417,23441 ----
+ @ Here is where the information for a new font gets loaded.
+
+ @<Assignments@>=
+! def_font: if cur_chr=0 then new_font(a) else
+! set_font_variant(a);
+!
+ @ @<Declare subprocedures for |prefixed_command|@>=
++ procedure set_font_variant(@!a:small_number);
++ var
++ s:integer;
++ begin
++ scan_int; s:=cur_val;
++ if (s<0)or(s>3) then begin
++ print_err("Bad font variant number");
++ help2("A font variant number must be between 0 and 3.")@/
++ ("I changed this one to zero."); int_error(s); s:=0;
++ end;
++ scan_font_ident; f:=cur_val;
++ scan_optional_equals; scan_font_ident;
++ font_variants[f][s]:=cur_val;
++ end;
++
+ procedure new_font(@!a:small_number);
+ label common_ending;
+ var u:pointer; {user's font identifier}
+***************
+*** 23274,23279 ****
+--- 23444,23450 ----
+ @!t:str_number; {name for the frozen font identifier}
+ @!old_setting:0..max_selector; {holds |selector| setting}
+ @!flushable_string:str_number; {string not yet referenced}
++ @!k:small_number;
+ begin if job_name=0 then open_log_file;
+ {avoid confusing \.{texput} with the font name}
+ @.texput@>
+***************
+*** 23292,23297 ****
+--- 23463,23469 ----
+ font number and |goto common_ending|@>;
+ f:=read_font_info(u,cur_name,cur_area,s);
+ common_ending: equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t;
++ for k:=0 to 3 do font_variants[f][k]:=f;
+ end;
+
+ @ @<Scan the font size specification@>=
+*** tex.ch.orig Wed Sep 16 22:54:44 1998
+--- tex.ch Sun Sep 20 10:03:52 1998
+***************
+*** 1200,1211 ****
+ @z
+
+ @x [17.236] l.4954 - MLTeX: \charsubdefmax and \tracingcharsubdef
+! @d int_pars=55 {total number of integer parameters}
+ @y
+! @d char_sub_def_min_code=55 {smallest value in the charsubdef list}
+! @d char_sub_def_max_code=56 {largest value in the charsubdef list}
+! @d tracing_char_sub_def_code=57 {traces changes to a charsubdef def}
+! @d int_pars=58 {total number of integer parameters}
+ @z
+
+ @x [17.236] l.5016 - MLTeX: \charsubdefmax and \tracingcharsubdef
+--- 1200,1211 ----
+ @z
+
+ @x [17.236] l.4954 - MLTeX: \charsubdefmax and \tracingcharsubdef
+! @d int_pars=59 {total number of integer parameters}
+ @y
+! @d char_sub_def_min_code=59 {smallest value in the charsubdef list}
+! @d char_sub_def_max_code=60 {largest value in the charsubdef list}
+! @d tracing_char_sub_def_code=61 {traces changes to a charsubdef def}
+! @d int_pars=62 {total number of integer parameters}
+ @z
+
+ @x [17.236] l.5016 - MLTeX: \charsubdefmax and \tracingcharsubdef
+***************
+*** 1752,1757 ****
+--- 1752,1759 ----
+ {right boundary character, |non_char| if there is none}
+ @!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
++ @!font_variants:array[internal_font_number] of four_fonts;
++ {we use four variants per font}
+ @y
+ @!font_info: ^fmemory_word;
+ {the big collection of font data}
+***************
+*** 1783,1788 ****
+--- 1785,1791 ----
+ {right boundary character, |non_char| if there is none}
+ @!font_false_bchar: ^nine_bits;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
++ @!font_variants: ^four_fonts;
+ @z
+
+ @x [30.550] l.10723 - texarray
+***************
+*** 1845,1850 ****
+--- 1848,1854 ----
+ font_glue[null_font]:=null; font_params[null_font]:=7;
+ param_base[null_font]:=-1;
+ for k:=0 to 6 do font_info[k].sc:=0;
++ for k:=0 to 3 do font_variants[null_font][k]:=null_font;
+ @y
+ @z
+
+***************
+*** 2176,2184 ****
+ @z
+
+ @x [38.859] l.16855 - Fix a casting/expression evaluation problem.
+! if abs(fit_class-fitness(r))>1 then d:=d+adj_demerits;
+ @y
+! if abs(toint(fit_class)-toint(fitness(r)))>1 then d:=d+adj_demerits;
+ @z
+
+ @x [39.875] l.17170 - Another casting problem.
+--- 2180,2188 ----
+ @z
+
+ @x [38.859] l.16855 - Fix a casting/expression evaluation problem.
+! case abs(fit_class-fitness(r)) of
+ @y
+! case abs(toint(fit_class)-toint(fitness(r))) of
+ @z
+
+ @x [39.875] l.17170 - Another casting problem.
+***************
+*** 3197,3202 ****
+--- 3201,3207 ----
+ dump_things(exten_base[null_font], font_ptr+1-null_font);
+ dump_things(param_base[null_font], font_ptr+1-null_font);
+ dump_things(font_glue[null_font], font_ptr+1-null_font);
++ dump_things(font_variants[null_font], font_ptr+1-null_font);
+ dump_things(bchar_label[null_font], font_ptr+1-null_font);
+ dump_things(font_bchar[null_font], font_ptr+1-null_font);
+ dump_things(font_false_bchar[null_font], font_ptr+1-null_font);
+***************
+*** 3264,3269 ****
+--- 3269,3275 ----
+ xmalloc_array(kern_base, font_max);
+ xmalloc_array(exten_base, font_max);
+ xmalloc_array(param_base, font_max);
++ xmalloc_array(font_variants, font_max);
+
+ undump_things(font_check[null_font], font_ptr+1-null_font);
+ undump_things(font_size[null_font], font_ptr+1-null_font);
+***************
+*** 3290,3295 ****
+--- 3296,3302 ----
+ undump_things(param_base[null_font], font_ptr+1-null_font);
+ undump_checked_things(min_halfword, lo_mem_max,
+ font_glue[null_font], font_ptr+1-null_font);
++ undump_things(font_variants[null_font], font_ptr+1-null_font);
+ undump_checked_things(0, fmem_ptr-1,
+ bchar_label[null_font], font_ptr+1-null_font);
+ undump_checked_things(min_quarterword, non_char,
+***************
+*** 3705,3710 ****
+--- 3712,3718 ----
+ xmalloc_array(kern_base, font_max);
+ xmalloc_array(exten_base, font_max);
+ xmalloc_array(param_base, font_max);
++ xmalloc_array(font_variants, font_max);
+
+ font_ptr:=null_font; fmem_ptr:=7;
+ font_name[null_font]:="nullfont"; font_area[null_font]:="";
+***************
+*** 3720,3725 ****
+--- 3728,3734 ----
+ font_glue[null_font]:=null; font_params[null_font]:=7;
+ param_base[null_font]:=-1;
+ for font_k:=0 to 6 do font_info[font_k].sc:=0;
++ for font_k:=0 to 3 do font_variants[null_font][font_k]:=null_font;
+ end;
+ tini@/
+
diff --git a/systems/tex-extensions/clasen/vftovp.patch b/systems/tex-extensions/clasen/vftovp.patch
new file mode 100644
index 0000000000..d787940b02
--- /dev/null
+++ b/systems/tex-extensions/clasen/vftovp.patch
@@ -0,0 +1,119 @@
+Wouldn't it be a good idea if *all* programs which read
+tfm files would use the mktextfm mechanism ? vftovp is an
+example of a program which doesn't with web2c 7.2. The
+patch below corrects this.
+
+
+
+--- web2c/common.defines Sun Aug 9 23:31:38 1998
++++ web2c/common.defines2 Sun Aug 9 23:32:45 1998
+@@ -81,6 +81,7 @@
+ @define const VFTOVPHELP;
+ @define const VPTOVFHELP;
+ @define const WEAVEHELP;
++@define const MAKETEXTFMBYDEFAULT; { added for vftovp }
+
+ @define function abs ();
+ @define function addressof ();
+@@ -133,6 +134,7 @@
+ @define function xrealloc ();
+ @define function xstrdup ();
+ @define function XTALLOC ();
++@define const kpsesrccompile; { added for vftovp }
+
+ @define procedure aclose ();
+ @define procedure BIBXRETALLOC (); {For BibTeX.}
+@@ -167,6 +169,7 @@
+ @define procedure writeln ();
+ @define procedure xfclose ();
+ @define procedure xfseek ();
++@define procedure kpsesetprogramenabled (); { added for vftovp }
+
+ @define type boolean = 0..1;
+ @define type cinttype;
+--- cpascal.h Mon Aug 10 00:23:57 1998
++++ cpascal.h.new Mon Aug 10 00:23:42 1998
+@@ -254,4 +254,13 @@
+ /* version.c */
+ extern string versionstring;
+
++#ifdef VFTOVP
++#include <kpathsea/tex-file.h>
++#include <c-auto.h>
++#define kpsesetprogramenabled kpse_set_program_enabled
++#define kpsesrccompile kpse_src_compile
++#define kpsemaketexoption kpse_maketex_option
++#define MAKETEXTFMBYDEFAULT MAKE_TEX_TFM_BY_DEFAULT
++#endif /* VFTOVP */
++
+ #endif /* not CPASCAL_H */
+--- vftovp.ch Sun Aug 9 23:34:01 1998
++++ vftovp.ch.new Mon Aug 10 00:15:23 1998
+@@ -22,6 +22,8 @@
+ kpse_set_progname (argv[0]);
+ kpse_init_prog ('VFTOVP', 0, nil, nil);
+ parse_arguments;
++ kpse_set_program_enabled (kpse_tfm_format, MAKE_TEX_TFM_BY_DEFAULT,
++ kpse_src_compile);
+ @z
+
+ % [4] No name_length.
+@@ -460,7 +462,7 @@
+
+ @<Define |parse_arguments|@> =
+ procedure parse_arguments;
+-const n_options = 4; {Pascal won't count array lengths for us.}
++const n_options = 6; {Pascal won't count array lengths for us.}
+ var @!long_options: array[0..n_options] of getopt_struct;
+ @!getopt_return_val: integer;
+ @!option_index: c_int_type;
+@@ -490,6 +492,12 @@
+ else
+ write_ln (stderr, 'Bad character code format', optarg, '.');
+
++ end else if argument_is ('mktex') then begin
++ kpse_maketex_option (optarg, true);
++
++ end else if argument_is ('no-mktex') then begin
++ kpse_maketex_option (optarg, false);
++
+ end; {Else it was a flag; |getopt| has already done the assignment.}
+ until getopt_return_val = -1;
+
+@@ -539,6 +547,24 @@
+ long_options[current_option].has_arg := 0;
+ long_options[current_option].flag := address_of (verbose);
+ long_options[current_option].val := 1;
++incr (current_option);
++
++@ Enable mktextfm?
++
++@<Define the option...@> =
++long_options[current_option].name := 'mktex';
++long_options[current_option].has_arg := 1;
++long_options[current_option].flag := 0;
++long_options[current_option].val := 0;
++incr (current_option);
++
++@ Disable mktextfm?
++
++@<Define the option...@> =
++long_options[current_option].name := 'no-mktex';
++long_options[current_option].has_arg := 1;
++long_options[current_option].flag := 0;
++long_options[current_option].val := 0;
+ incr (current_option);
+
+ @ The global variable |verbose| determines whether or not we print
+--- help.h Mon Aug 10 00:22:06 1998
++++ help.h.new Mon Aug 10 00:21:22 1998
+@@ -527,7 +527,8 @@
+ -charcode-format=TYPE output character codes according to TYPE,\n\
+ either `octal' or `ascii'; default is ascii for\n\
+ letters and digits, octal for all else\n\
+--help display this help and exit\n\
++[-no]-mktex=FMT disable/enable mktexFMT generation (FMT=tfm)\n\
++-help display this help and exit\n\
+ -verbose display progress reports\n\
+ -version output version information and exit\n"
+ #endif /* VFTOVP */