# MF hackery (arrow kit) + CM design questions

• To: math-font-discuss@cogs.susx.ac.uk
• Subject: MF hackery (arrow kit) + CM design questions
• From: Ulrik Vieth <vieth@thphy.uni-duesseldorf.de>
• Date: Thu, 30 Oct 1997 16:53:11 +0100

Last night, I only wanted to investigate why the triple arrows in the
MS2 arrow kit were turning out bolder than the single and double ones,
but I eventually ended up applying lots of minor corrections and
improvements throughout al of the MF sources for the arrow kit,
resulting in one big patch attached below:

Changes include:

using |rule_thickness| instead of |bar| or |1.5bar|.

* all characters: added or updated |penlabels| to get points numbered
in the GFtoDVI proof sheets.

get width characters boxes fixed properly.

* many characters: adjusted lft/rt positioning of control points.
In general, the tips of arrowheads are positioned with lft/rt
while overshooting ends for extensible arrows are centered on
the middle of the control points, i.e. without using lft/rt.

* dashed arrows and arrow extension pieces: improved the code using
for-loops instead of tedious repetions of |drawdot|.

* changed the width of arrow extension pieces to 12u# (equivalent
to 2/3 of 1em) instead of 14u#, and use a factor of 3/2 instead
of 4/3 for the wide extension pieces, so that they end up being
exactly 18u# wide (equivalent to 1em) instead of 18.66u#.

Remaining problems:

* The construction of zero-width characters is different from
that of Knuth's mapstochar.  Instead of directly specifying
a width of 0pt#, he first used a non-zero width, followed
by |adjust_fit(0,0)| and a call to |zero_width|.  Is there
any difference other than correctly setting the width of the
proof-sheet box?  The problem is that calling |adjust_fit(0,0)|
after specifying a width of 0pt# gives a division-by-zero error.

* The gaped squiggly arrows produce some stray pixes within the
are that should be erased.  Anyone knows how to fix this???

* There are still a few remaining inconsistencies as to when
points are positioned at hround(w-u) or hround(w-u-eps), etc.

* I haven't yet tested if the dot separation of dashed arrowheads
and arrow extension pieces fits smoothly.  With 8 dots per 12u#
the dot separation would be 1.5u# and the first dot would have
to be positioned at 0.5dot_sep (or 0.75u#) from the edges of
the character box.  I hope this will be satisfied in all cases.

* I haven't yet checked if all the arrows (apparently assembled
from various sources) follow the design principles of Knuth's
latest sources or if some of them are still based on old CM.

* It is unclear to me why there is an |italcorr| specification
for some of the arrow extension pieces.  I presume this would
be totally unecessary in an unslanted symbol font anyway.

So long, Ulrik.

P.S. Another unrelated MF problem: It appears that the vector
accent from cmmi has a slanted arrowhead, while the reversevector
and doublevector form ymc are upright.  Would you agree that all
three  of them should be the same style (preferably upright)?

P.P.S.  Another one: The CM square brackets from punct.mf have
a width of 5u# (and relatively little side-bearings), while the
floor/ceiling bracktes from symbol.mf have a width of 8u# (with
wider side-bearings and rounded corners at the end of strokes).
Now the big square brackets have a width of 6u, 6.5u, 7u, 7.5u,
while the big floor/ceilings have a width of 7u, 7.5u, 8u, 8.5u,
and both of the share the same set of extensible modules.

Would it seem reasonable that all of them should have consistent
widths or is there a good design reason why floors/ceilings are
a little wider?  I suppose that even if we consider this a bug,
we will have to keep the old widths for metrics compatibility
in the CM implementation, although it might also be interesting
to provide an alternative optimized version as well.  Opions?

diff -u ORIG/ymedel.mf ./ymedel.mf
--- ORIG/ymedel.mf	Thu Oct  2 20:42:07 1997
+++ ./ymedel.mf	Wed Oct 29 23:00:25 1997
@@ -16,7 +16,7 @@
x4=x3; y4=y1; z5=.5[z1,z4]; z6=.5[z2,z3];
draw z5--z6;
draw z4--z1--z2--z3;  % stem and bar
-labels(1,2,3); endchar;
+labels(1,2,3,4,5,6); endchar;

cmchar "Left multiset bracket";
beginchar(slot_multisetbracketleft,9u#,body_height#,paren_depth#);
diff -u ORIG/ymearr.mf ./ymearr.mf
--- ORIG/ymearr.mf	Thu Oct  2 21:02:54 1997
+++ ./ymearr.mf	Thu Oct 30 04:37:47 1997
@@ -1,6 +1,10 @@
+% experimental changes:
+%
+% arrow_ext_width#:=12u#;	(was: 14u#)
+% 3/2arrow_ext_width#:=18u#;	(was: 4/3x, 18.66u#)

-arrow_ratio:=14/9;
-arrow_ext_width#:=14u#;
+arrow_ratio:=12/9;
+arrow_ext_width#:=12u#;
arrow_overshoot:=u-eps;

@@ -25,24 +29,25 @@
...z5{z6-z4}...z6{up}...z7{z8-z6}...cycle;  % circle and interior
enddef;

-% 8 control glyphs
+% 8 control glyphs

-cmchar "Single left end";
+cmchar "Single left arrow end";
-y0=y1=math_axis; x1=hround(w+arrow_overshoot); lft x0=hround u;
-draw z0--z1; endchar;
+lft x1=hround u; x2=hround(w+arrow_overshoot);
+y1=y2=math_axis;
+draw z1--z2;
+penlabels(1,2); endchar;

cmchar "Single arrow extension";
beginchar(slot_singleext,arrow_ext_width#,single_height);
-pickup rule.nib;
-lft x1=hround(0-arrow_overshoot);
-x2=w-x1;
+x1=hround(0-arrow_overshoot); x2=w-x1;
y1=y2=math_axis;
draw z1--z2;  % bar
-labels(1,2); endchar;
+penlabels(1,2); endchar;

cmchar "Single arrow negation";
@@ -57,55 +62,51 @@
cmchar "Single arrow negated extension";
beginchar(slot_NEGEXT,arrow_ext_width#,single_height);
-pickup rule.nib;
-lft x1=hround 0 - arrow_overshoot; x2=w-x1; y1=y2=math_axis;
+x1=hround(0-arrow_overshoot); x2=w-x1;
+y1=y2=math_axis;
draw z1--z2;  % bar
y3-y1=.24asc_height+eps;
char_center(100); top y101=top y3; x101=x100+2u;
char_negate(100,101,102);
-labels(1,2); endchar;
-
-cmchar "Single gap";
-beginchar(slot_GAP,arrow_ext_width#/3,single_height);
-endchar;
+penlabels(1,2); endchar;

cmchar "Single arrow gaped extension";
-beginchar(slot_GAPEXT,4/3arrow_ext_width#,single_height);
-pickup rule.nib;
-lft x1=hround(0-arrow_overshoot);
+beginchar(slot_GAPEXT,3/2arrow_ext_width#,single_height);
+x1=hround(0-arrow_overshoot); x4=w-x1;
x2=hround (3/8w);
x3=hround (5/8w);
-x4=w-x1;
y1=y2=y3=y4=math_axis;
draw z1--z2;  % bar
draw z3--z4;
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Squiggly arrow extension";
beginchar(slot_SQUIG,arrow_ext_width#,single_height);
y2=y4; y1=y3=y5; y3-y4=.24asc_height+eps;
.5[y3,y4]=math_axis;
x2-x1=x3-x2=x4-x3=x5-x4;
x1=0; x5=w;
pickup pencircle scaled rule_thickness;
draw z1{right}..z2{right}..z3{right}..z4{right}..{right}z5;
-endchar;
+penlabels(1,2,3,4,5); endchar;

-cmchar "Single arrow dashed extension";
+cmchar "Single dashed arrow extension";
beginchar(slot_DASH,arrow_ext_width#,single_height);
-pickup rule.nib;
+italcorr h#*slant-.5u#;
numeric dot_sep; dot_sep:=w/8;
-x0=0;
-y0=y1=y2=y3=y4=y5=y6=y7=y8=math_axis;
-2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
-drawdot z1; drawdot z2; drawdot z3; drawdot z4;
-drawdot z5; drawdot z6; drawdot z7; drawdot z8;
-labels(0,1,2,3,4,5,6,7,8); endchar;
+x0=0; y0=math_axis;
+2(x1-x0)=dot_sep; y1=y0; drawdot z1;
+for j=2 thru 8:
+  x[j]-x[j-1]=dot_sep; y[j]=y0; drawdot z[j];
+endfor
+penlabels(0,1,2,3,4,5,6,7,8); endchar;

@@ -115,7 +116,8 @@
pos1(rule_thickness,90); pos2(rule_thickness,90);
pos3(rule_thickness,0); pos4(rule_thickness,0);
-y0=y1=y2=math_axis; x1=hround(w); lft x0=hround u;
+y0=y1=y2=math_axis;
+lft x0=hround u; x1=hround(w+arrow_overshoot);
y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
x3=x4=x0+if monospace:3u else:4u fi+eps;
pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -132,10 +134,11 @@
-lft x7=hround u-eps; x8=x7; x1=x2=w+arrow_overshoot;
+lft x7=hround u-eps; x8=x7; x1=x2=hround(w+arrow_overshoot);
draw z1--z7; draw z2--z8;  % bars
-pickup crisp.nib; lft x0=hround u-eps; y0=good.y math_axis;
+pickup crisp.nib;
+lft x0=hround u-eps; y0=good.y math_axis;
pos3(rule_thickness,0); pos4(rule_thickness,0);
y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0+6u+eps;
pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -152,24 +155,26 @@
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0);
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
y0=y1=y2=math_axis; x1=hround(w+arrow_overshoot);
-lft x0=hround u; x0'=x0''=x0; x1'=x1''=x1;
-z0'--z1'; draw z0''--z1''; % draw bars
+lft x0=hround u-eps; x0'=x0''=x0; x1'=x1''=x1;
+pickup rule.nib;
+draw z0'--z1'; draw z0''--z1''; % draw bars
pickup crisp.nib;
y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0+6u+eps;
-pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0));
-z6l=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw
-z0..{z3-z9}z3--(0,y3)
- --(0,y4)--z4{z9-z4}..z0& cycle; numeric t; path p;
-p=z4r{z9-z4}..z6r; t=xpart(p
-intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(0,y3)
+ --(0,y4)--z4{z9-z4}..z0& cycle;
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
pickup rule.nib; draw z2--z1; pickup crisp.nib;
filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
-%--z2l---z1l..z1r---z2r
---subpath (t,0) of\\(z3r{z9-z3}..z5r)
+ --subpath (t,0) of\\(z3r{z9-z3}..z5r)
--z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
penlabels(0,1,2,3,4,5,6,9,0',0'',1',1''); endchar;

@@ -179,7 +184,7 @@
penpos1(.25rule_thickness,90); penpos2(.25rule_thickness,90); penpos3(bar,0);
penpos4(bar,0);
y0=y1=y2=math_axis; x0=hround 1.5u-eps;
-rt x1=w-(hround 0-arrow_overshoot);
+x1=(hround w+arrow_overshoot);
y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
penpos5(bar,angle(z4-z0)); z5l=z0; penpos6(bar,angle(z3-z0)); z6l=z0;
z9=.381966[.5[z3,z4],z0];
@@ -196,17 +201,13 @@
pos1(rule_thickness,90); pos2(rule_thickness,90);
pos3(bar,0); pos4(bar,0); y0=y1=y2=math_axis;
-x1=hround(w+arrow_overshoot); % x1+.5rule_thickness=hround(w-u);
-lft x0=hround u;
+x1=hround(w+arrow_overshoot); lft x0=hround u;
y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0));
z6l=z0; z9=.381966[.5[z3,z4],z0];
-numeric t; path p;
-p=z4r{z9-z4}..z6r;
-t=xpart(p intersectiontimes((0,y2l)--(w,y2l)));
-x2=xpart point t of p;
-path p; p=z0..{z4-z9}z4l--subpath (0,t)
-of\\(z4r{z9-z4}..z6r)
+numeric t; path p;  p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+path p; p=z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
--z2l--z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
--z3l{z9-z3}..z0 & cycle; % second arrowhead
filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
@@ -223,7 +224,7 @@
y1=y2=math_axis; y1-y3=y4-y1=.24asc_height+eps;
draw z3--z4;  % stem
draw z1--z2;  % bar stub
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Double left mapsto arrow head";
@@ -235,7 +236,7 @@
draw z3--z4;  % stem
draw z1--z2;  % bar stub
draw z5--z6;  % bar stub
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;

cmchar "Triple left mapsto arrow head";
@@ -248,7 +249,7 @@
draw z1--z2;  % bar stub
draw z5--z6;  % bar stub
draw z7--z8;  % bar stub
-labels(1,2,3,4,5,6,7,8); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;

cmchar "Left hook up";
@@ -258,7 +259,7 @@
x4=hround(w+arrow_overshoot);
draw z1{left}...z2{down}...z3{right}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Left hook down";
@@ -268,7 +269,7 @@
x4=hround(w+arrow_overshoot);
draw z1{left}...z2{up}...z3{right}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;

% 146: Left harpoon up
% 147: Left harpoon down
@@ -313,7 +314,8 @@
pos1(rule_thickness,90); pos2(rule_thickness,90);
pos3(rule_thickness,0); pos4(rule_thickness,0);
-y0=y1=y2=math_axis; x1=hround (0); rt x0=hround(w-u);
+y0=y1=y2=math_axis;
+rt x0=hround(w-u); x1=hround(0-arrow_overshoot);
y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
x3=x4=x0-if monospace:3u else:4u fi-eps;
pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -330,10 +332,11 @@
-lft x1=hround 0 - arrow_overshoot; x2=x1; x7=x8=w-hround u-eps;
+x1=x2=hround(0-arrow_overshoot); rt x7=w-hround u-eps; x8=x7;
draw z1--z7; draw z2--z8;  % bars
-pickup crisp.nib; rt x0=hround(w-u)+eps; y0=good.y math_axis;
+pickup crisp.nib;
+rt x0=hround(w-u)+eps; y0=good.y math_axis;
pos3(rule_thickness,0); pos4(rule_thickness,0);
y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0-6u-eps;
pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -350,24 +353,26 @@
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0);
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
y0=y1=y2=math_axis; x1=hround(0-arrow_overshoot);
-rt x0=hround (w-u); x0'=x0''=x0; x1'=x1''=x1;
+rt x0=hround(w-u)+eps; x0'=x0''=x0; x1'=x1''=x1;
+pickup rule.nib;
draw z0'--z1'; draw z0''--z1''; % draw bars
pickup crisp.nib;
y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0-6u-eps;
-penpos5(bar,angle(z0-z4)); z5r=z0; penpos6(bar,angle(z0-z3));
-z6r=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw
-z0..{z3-z9}z3--(w,y3)--(w,y4)--z4{z9-z4}..z0& cycle;
-numeric t; path p;
-p=z4l{z9-z4}..z6l; t=xpart(p intersectiontimes((0,y2l)--(w,y2l)));
-x2=xpart point t of p;
+pos5(rule_thickness,angle(z0-z4)); z5r=z0;
+pos6(rule_thickness,angle(z0-z3)); z6r=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(w,y3)
+ --(w,y4)--z4{z9-z4}..z0& cycle;
+ numeric t; path p; p=z4l{z9-z4}..z6l;
+ t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
pickup rule.nib; draw z2--z1; pickup crisp.nib;
filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6l)
-% --z2l---z1l..z1r---z2r
---subpath (t,0) of\\(z3l{z9-z3}..z5l)
+ --subpath (t,0) of\\(z3l{z9-z3}..z5l)
--z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
penlabels(0,1,2,3,4,5,6,9,0',0'',1',1''); endchar;

@@ -377,8 +382,8 @@
penpos1(.25rule_thickness,90); penpos2(.25rule_thickness,90); penpos3(bar,0);
penpos4(bar,0);
y0=y1=y2=math_axis;
-x1=hround 0 - arrow_overshoot;
-rt x0=w-(hround 1.5u-eps);
+x1=hround(0-arrow_overshoot);
+x0=w-(hround 1.5u-eps);
y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
penpos5(bar,angle(z4-z0)); z5l=z0; penpos6(bar,angle(z3-z0)); z6l=z0;
z9=.381966[.5[z3,z4],z0];
@@ -392,16 +397,18 @@
-pickup crisp.nib;  pos1(rule_thickness,90); pos2(rule_thickness,90);
-pos3(bar,0); pos4(bar,0);  y0=y1=y2=math_axis; x1=hround(0-arrow_overshoot);
-rt x0=hround(w-u); y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(bar,0); pos4(bar,0);  y0=y1=y2=math_axis;
+x1=hround(0-arrow_overshoot); rt x0=hround(w-u);
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
-z9=.381966[.5[z3,z4],z0]; numeric t; path p; p=z4l{z9-z4}..z6r;  t=xpart(p
-intersectiontimes((0,y2l)--(w,y2l)));  x2=xpart point t of p;  path p;
-p=z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4l{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l)));  x2=xpart point t of p;
+path p; p=z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
--z2l--z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
- --z3r{z9-z3}..z0 & cycle;
+ --z3r{z9-z3}..z0 & cycle; % second arrowhead
filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
--z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
--z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
@@ -412,37 +419,36 @@
-lft x1=hround(w-u); x2=hround(-arrow_overshoot); x3=x4=x1;
+rt x1=hround(w-u); x2=hround(-arrow_overshoot); x3=x4=x1;
y1=y2=math_axis; y1-y3=y4-y1=.24asc_height+eps;
draw z3--z4;  % stem
draw z1--z2;  % bar stub
-labels(1,2,3,4); endchar;
-
+penlabels(1,2,3,4); endchar;

-cmchar "Double right mapsto ";
+cmchar "Double right mapsto";
-lft x1=hround(w-u); x6=x2=hround(-arrow_overshoot); x5=x3=x4=x1;
+rt x1=hround(w-u); x6=x2=hround(-arrow_overshoot); x5=x3=x4=x1;
y1-y3=y4-y5=.24asc_height+eps;
draw z3--z4;  % stem
draw z1--z2;  % bar stub
draw z5--z6;  % bar stub
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;

cmchar "Triple right mapsto";
-lft x1=hround(w-u); x6=x8=x2=hround(-arrow_overshoot); x5=x7=x3=x4=x1;
+rt x1=hround(w-u); x6=x8=x2=hround(-arrow_overshoot); x5=x7=x3=x4=x1;
y3-y5=y7-y4=.24asc_height+eps;
draw z3--z4;  % stem
draw z1--z2;  % bar stub
draw z5--z6;  % bar stub
draw z7--z8;  % bar stub
-labels(1,2,3,4,5,6,7,8); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;

% 168: Right hook up
% 169: Right hook down
@@ -483,7 +489,7 @@

@@ -500,12 +506,10 @@
filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
--z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
--z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
-
x10=w; y10=math_axis+.12asc_height+eps;
-pickup pencircle scaled rule_thickness;
+pickup rule.nib;
draw z1{right}..z10{right};
-
-penlabels(0,1,2,3,4,5,6,9); endchar;
+penlabels(0,1,2,3,4,5,6,9,10); endchar;

cmchar "Single left dashed arrow head";
@@ -526,16 +530,16 @@
--z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
pickup rule.nib;
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y13=y12=y11=y10=y9; x10=hround(w-.5dot_sep);
-x11-x12=x12-x13=x10-x11=dot_sep;
+y13=y12=y11=y10=y0; x10=hround(w-.5dot_sep);
+x12-x13=x11-x12=x10-x11=dot_sep;
drawdot z10; drawdot z11; drawdot z12; drawdot z13;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13); endchar;

cmchar "Double left dashed arrow head";
-lft x7=hround u-eps; x8=x7; x1=x2=w+arrow_overshoot;
+lft x7=hround u-eps; x8=x7; x1=x2=hround(w+arrow_overshoot);

numeric dot_sep; dot_sep:=w/8*arrow_ratio;
@@ -546,7 +550,8 @@
drawdot z20; drawdot z21; drawdot z22;
drawdot z30; drawdot z31; drawdot z32;

-pickup crisp.nib; lft x0=hround u-eps; y0=good.y math_axis;
+pickup crisp.nib;
+lft x0=hround u-eps; y0=good.y math_axis;
pos3(rule_thickness,0); pos4(rule_thickness,0);
y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0+6u+eps;
pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -558,18 +563,20 @@
t=xpart(p intersectiontimes((0,y0)--(w,y0)));
filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
--subpath (t,0) of\\(z3r{z9-z3}..z5r)--z3l{z9-z3}..z0 & cycle;  % arrowhead
-penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+penlabels(0,1,2,3,4,5,6,7,8,9,20,21,22,30,31,32); endchar;

cmchar "Triple left dashed arrow head";
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1=x2+eps;
+lft x0=hround u-eps; x0'=x0''=x0; x1'=x1''=x1;
+
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0);
-y0=y1=y2=math_axis;
-lft x0=hround u; x0'=x0''=x0;
-x53=x53'=x53''=hround (w-.5dot_sep);
+x53=x53'=x53''=hround(w-.5dot_sep);
x51-x50=x52-x51=x53-x52=dot_sep;
x50=x50'=x50''; x51=x51'=x51''; x52=x52'=x52'';
y50=y51=y52=y53=math_axis;
@@ -578,15 +585,16 @@
drawdot z50; drawdot z51; drawdot z52; drawdot z53;
drawdot z50'; drawdot z51'; drawdot z52'; drawdot z53';
drawdot z50''; drawdot z51''; drawdot z52''; drawdot z53'';
-x1l:=x1r:=x1:=x2+eps;
+
pickup crisp.nib;
y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0+6u+eps;
-pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0));
-z6l=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw
-z0..{z3-z9}z3--(0,y3)
- --(0,y4)--z4{z9-z4}..z0& cycle; numeric t; path p;
-p=z4r{z9-z4}..z6r; t=xpart(p
-intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(0,y3)
+ --(0,y4)--z4{z9-z4}..z0& cycle;
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
--z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
--z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
@@ -611,12 +619,10 @@
filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
--z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
--z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
-
x10=0; y10=math_axis+.12asc_height+eps;
-pickup pencircle scaled rule_thickness;
+pickup rule.nib;
draw z10{right}..z1{right};
-
-penlabels(0,1,2,3,4,5,6,9); endchar;
+penlabels(0,1,2,3,4,5,6,9,10); endchar;

cmchar "Single right dashed arrow head";
@@ -637,16 +643,16 @@
--z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
pickup rule.nib;
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y13=y12=y11=y10=y9; x10=hround(.5dot_sep);
-x12-x11=x13-x12=x11-x10=dot_sep;
+y13=y12=y11=y10=y0; x10=hround(.5dot_sep);
+x13-x12=x12-x11=x11-x10=dot_sep;
drawdot z10; drawdot z11; drawdot z12; drawdot z13;
-penlabels(0,1,2,3,4,5,6,9,10,11,12); endchar;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13); endchar;

cmchar "Double right dashed arrow head";
-lft x1=hround 0 - arrow_overshoot; x2=x1; x7=x8=w-hround u-eps;
+x1=x2=hround(0-arrow_overshoot); rt x7=w-hround u-eps; x8=x7;

numeric dot_sep; dot_sep:=w/8*arrow_ratio;
@@ -657,7 +663,8 @@
drawdot z20; drawdot z21; drawdot z22;
drawdot z30; drawdot z31; drawdot z32;

-pickup crisp.nib; rt x0=hround(w-u)+eps; y0=good.y math_axis;
+pickup crisp.nib;
+rt x0=hround(w-u)+eps; y0=good.y math_axis;
pos3(rule_thickness,0); pos4(rule_thickness,0);
y3-y1=y2-y4=.24asc_height+eps; x3=x4=x0-6u-eps;
pos5(rule_thickness,angle(z4-z0)); z5l=z0;
@@ -669,17 +676,19 @@
t=xpart(p intersectiontimes((0,y0)--(w,y0)));
filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
--subpath (t,0) of\\(z3l{z9-z3}..z5r)--z3r{z9-z3}..z0 & cycle;  % arrowhead
-penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+penlabels(0,1,2,3,4,5,6,7,8,9,20,21,22,30,31,32); endchar;

cmchar "Triple right dashed arrow head";
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1=x2-eps;
+rt x0=hround(w-u)+eps; x0'=x0''=x0; x1'=x1''=x1;
+
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-penpos2(rule_thickness,90); penpos3(1.5bar,0); penpos4(1.5bar,0);
-y0=y1=y2=math_axis; x1=hround(0-arrow_overshoot);
-rt x0=hround (w-u); x0'=x0''=x0; x1'=x1''=x1;
x50=x50'=x50''=hround .5dot_sep;
x51-x50=x52-x51=x53-x52=dot_sep;
x51=x51'=x51'';x 52=x52'=x52''; x53=x53'=x53'';
@@ -689,15 +698,16 @@
drawdot z50; drawdot z51; drawdot z52; drawdot z53;
drawdot z50'; drawdot z51'; drawdot z52'; drawdot z53';
drawdot z50''; drawdot z51''; drawdot z52''; drawdot z53'';
-x1l:=x1r:=x2-eps;
+
pickup crisp.nib;
y3-y0'=y0''-y4=.24asc_height+eps; x3=x4=x0-6u-eps;
-penpos5(bar,angle(z0-z4)); z5r=z0; penpos6(bar,angle(z0-z3));
-z6r=z0; z9=.381966[.5[z3,z4],z0]; erase filldraw
-z0..{z3-z9}z3--(w,y3)--(w,y4)--z4{z9-z4}..z0& cycle;
-numeric t; path p;
-p=z4l{z9-z4}..z6l; t=xpart(p intersectiontimes((0,y2l)--(w,y2l)));
-x2=xpart point t of p;
+penpos5(bar,angle(z0-z4)); z5r=z0;
+penpos6(bar,angle(z0-z3)); z6r=z0;
+z9=.381966[.5[z3,z4],z0];
+erase filldraw z0..{z3-z9}z3--(w,y3)
+ --(w,y4)--z4{z9-z4}..z0& cycle;
+numeric t; path p; p=z4l{z9-z4}..z6l;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6l)
--z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5l)
--z3r{z9-z3}..z0 & cycle;  % arrowhead and stem
@@ -709,11 +719,10 @@
+lft x1=hround u; x1=x2; x7=x8=hround(w+arrow_overshoot);
-x7=hround(w+arrow_overshoot); lft x1=hround u;
-x7=x8; x1=x2;
draw z1--z7; draw z2--z8;  % bars
-endchar;
+penlabels(1,2,7,8); endchar;

cmchar "Wide double left arrow end";
@@ -722,9 +731,9 @@
y1=y2=math_axis+.24asc_height+eps;
y3=y4=math_axis-.24asc_height-eps;
x2=hround(w+arrow_overshoot); lft x1=hround u;
-x2=x4; x1=x3;
+x1=x3; x2=x4;
draw z1--z2; draw z3--z4;  % bars
-endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Triple left arrow end";
@@ -734,7 +743,7 @@
x7=hround(w+arrow_overshoot); lft x1=hround u;
x7=x8=x9; x1=x2=x3;
draw z1--z7; draw z2--z8; draw z3--z9; % bars
-endchar;
+penlabels(1,2,3,7,8,9); endchar;

cmchar "Left squiggly arrow end";
@@ -751,52 +760,48 @@
draw z1{left}..{left}z2;
acc_w:=acc_w+squig_u;
endfor
-endchar;
+penlabels(1,2,3); endchar;

cmchar "Single left dashed arrow end";
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10=math_axis; x10=hround(w-.5dot_sep);
-x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+x10=hround(w-.5dot_sep); y10=math_axis; drawdot z10;
+for j=11 thru 14:
+  x[j-1]-x[j]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+endfor
+penlabels(range 10 thru 14); endchar;

cmchar "Double left dashed arrow end";
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10; y25=y24=y23=y22=y21=y20;
-x15=x25; x14=x24; x13=x23; x12=x22; x11=x21; x10=x20;
-x10=hround(w-.5dot_sep); x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,20,21,22,23,24); endchar;
+x10=x20=hround(w-.5dot_sep);
+drawdot z10; drawdot z20;
+for j=11 thru 14:
+  x[j-1]-x[j]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]; y[j+10]=y[j+10-1]; drawdot z[j+10];
+endfor
+penlabels(range 10 thru 14,range 20 thru 24); endchar;

cmchar "Triple left dashed arrow end";
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10;
-y25=y24=y23=y22=y21=y20;
-y35=y34=y33=y32=y31=y30;
-x15=x25=x35;
-x14=x24=x34;
-x13=x23=x33;
-x12=x22=x32;
-x11=x21=x31;
-x10=x20=x30;
-x10=hround(w-.5dot_sep);
-x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24;
-drawdot z30; drawdot z31; drawdot z32; drawdot z33; drawdot z34;
-endchar;
+x10=x20=x30=hround(w-.5dot_sep);
+drawdot z10; drawdot z20; drawdot z30;
+for j=11 thru 14:
+  x[j-1]-x[j]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]=x[j+20];
+  y[j+10]=y[j+10-1]; drawdot z[j+10];
+  y[j+20]=y[j+20-1]; drawdot z[j+20];
+endfor
+penlabels(range 10 thru 14,range 20 thru 24,range 30 thru 34); endchar;

% 8 simple right arrow ends

@@ -804,18 +809,19 @@
-y0=y1=math_axis; x1=hround (0-arrow_overshoot); rt x0=hround(w-u);
-draw z0--z1; endchar;
+rt x1=hround(w-u); x2=hround(0-arrow_overshoot);
+y1=y2=math_axis;
+draw z1--z2;
+penlabels(1,2); endchar;

cmchar "Double right arrow end";
+rt x7=hround(w-u); x7=x8; x1=x2=hround(0-arrow_overshoot);
-lft x1=hround(0-arrow_overshoot); rt x7=hround(w-u);
-x7=x8; x1=x2;
draw z1--z7; draw z2--z8;  % bars
-endchar;
+penlabels(1,2,7,8); endchar;

cmchar "Wide double right arrow end";
@@ -823,20 +829,20 @@
y1=y2=math_axis+.24asc_height+eps;
y3=y4=math_axis-.24asc_height-eps;
-lft x1=hround(0-arrow_overshoot); rt x2=hround(w-u);
-x3=x1; x4=x2;
+x1=hround(0-arrow_overshoot); rt x2=hround(w-u);
+x1=x3; x2=x4;
draw z1--z2; draw z3--z4;  % bars
-endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Triple right arrow end";
-lft x1=hround(0-arrow_overshoot); rt x7=hround(w-u);
+x1=hround(0-arrow_overshoot); rt x7=hround(w-u);
x7=x8=x9; x1=x2=x3;
draw z1--z7; draw z2--z8; draw z3--z9; % bars
-endchar;
+penlabels(1,2,3,7,8,9); endchar;

cmchar "Right squiggly arrow end";
@@ -853,53 +859,48 @@
draw z1{right}..{right}z2;
acc_w:=acc_w+squig_u;
endfor
-endchar;
+penlabels(1,2,3); endchar;

cmchar "Single right dashed arrow end";
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10=math_axis; x10=hround(.5dot_sep);
-x15-x14=x14-x13=x12-x11=x13-x12=x11-x10=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+x10=hround(.5dot_sep); y10=math_axis; drawdot z10;
+for j=11 thru 14:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+endfor
+penlabels(range 10 thru 14); endchar;

cmchar "Double right dashed arrow end";
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10;
-y25=y24=y23=y22=y21=y20;
-x15=x25; x14=x24; x13=x23; x12=x22; x11=x21; x10=x20;
-x10=hround(.5dot_sep); x15-x14=x14-x13=x12-x11=x13-x12=x11-x10=dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,20,21,22,23,24); endchar;
+x10=x20=hround(.5dot_sep);
+drawdot z10; drawdot z20;
+for j=11 thru 14:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]; y[j+10]=y[j+10-1]; drawdot z[j+10];
+endfor
+penlabels(range 10 thru 14,range 20 thru 24); endchar;

cmchar "Triple right dashed arrow end";
numeric dot_sep; dot_sep:=w/8*arrow_ratio;
-y15=y14=y13=y12=y11=y10;
-y25=y24=y23=y22=y21=y20;
-y35=y34=y33=y32=y31=y30;
-x15=x25=x35;
-x14=x24=x34;
-x13=x23=x33;
-x12=x22=x32;
-x11=x21=x31;
-x10=x20=x30;
-x10=hround .5dot_sep;
-x14-x15=x13-x14=x11-x12=x12-x13=x10-x11=-dot_sep;
-drawdot z10; drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z20; drawdot z21; drawdot z22; drawdot z23; drawdot z24;
-drawdot z30; drawdot z31; drawdot z32; drawdot z33; drawdot z34;
-endchar;
+x10=x20=x30=hround(.5dot_sep);
+drawdot z10; drawdot z20; drawdot z30;
+for j=11 thru 14:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]=x[j+20];
+  y[j+10]=y[j+10-1]; drawdot z[j+10];
+  y[j+20]=y[j+20-1]; drawdot z[j+20];
+endfor
+penlabels(range 10 thru 14,range  20 thru 24,range  30 thru 34); endchar;

% 5 arrow extension pieces

@@ -914,7 +915,7 @@
draw z1--z2;  % upper bar
draw z3--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Wide double arrow extension";
@@ -928,7 +929,7 @@
y3=y4=math_axis-.24asc_height-eps;
draw z1--z2;  % upper bar
draw z3--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Triple arrow extension";
@@ -940,7 +941,7 @@
draw z1--z2;  % upper bar
draw z3--z4;  % lower bar
draw z5--z6;  % middle bar
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;

cmchar "Squiggly left gaped arrow extension";
@@ -953,7 +954,7 @@
pickup pencircle scaled rule_thickness;
draw z1{right}..z2{right}..z3{right}..z4{right}..{right}z5;
unfill (5/6w,-d)--(7/6w,-d)--(7/6w,h)--(5/6w,h)--cycle;
-endchar;
+penlabels(1,2,3,4,5); endchar;

cmchar "Squiggly right gaped arrow extension";
@@ -966,7 +967,7 @@
pickup pencircle scaled rule_thickness;
draw z1{right}..z2{right}..z3{right}..z4{right}..{right}z5;
unfill (1/6w,-d)--(-1/6w,-d)--(-1/6w,h)--(1/6w,h)--cycle;
-endchar;
+penlabels(1,2,3,4,5); endchar;

cmchar "Double dashed arrow extension";
@@ -974,17 +975,14 @@
italcorr h#*slant-.5u#;
numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8;
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-x0=0; x10=x0; x11=x1; x12=x2; x13=x3; x14=x4; x15=x5; x16=x6;
-x17=x7; x18=x8;
-2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
-drawdot z1; drawdot z2; drawdot z3; drawdot z4;
-drawdot z5; drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z15; drawdot z16; drawdot z17; drawdot z18;
-labels(1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18); endchar;
+2(x1-x0)=dot_sep; x1=x11; y1=y0; y11=y10;
+drawdot z1; drawdot z11;
+for j=2 thru 8:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]; y[j+10]=y[j+10-1]; drawdot z[j+10];
+endfor
+penlabels(range 1 thru 8,range 11 thru 18); endchar;

cmchar "Triple dash arrow extension";
@@ -992,20 +990,16 @@
italcorr h#*slant-.5u#;
numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8;
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-y20=y21=y22=y23=y24=y25=y26=y27=y28;
-x0=0; x10=x0; x21=x11=x1; x22=x12=x2; x23=x13=x3;
-x24=x14=x4; x25=x15=x5; x26=x16=x6; x27=x17=x7; x28=x18=x8;
-2(x1-x0)=x2-x1=x3-x2=x4-x3=x5-x4=x6-x5=x7-x6=x8-x7=dot_sep;
-drawdot z1; drawdot z2; drawdot z3; drawdot z4;
-drawdot z5; drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13; drawdot z14;
-drawdot z15; drawdot z16; drawdot z17; drawdot z18;
-drawdot z21; drawdot z22; drawdot z23; drawdot z24;
-drawdot z25; drawdot z26; drawdot z27; drawdot z28;
-labels(1,2,3,4,5,6); endchar;
+2(x1-x0)=dot_sep; x1=x11=x21; y1=y0; y11=y10; y21=y20;
+drawdot z1; drawdot z11; drawdot z21;
+for j=2 thru 8:
+  x[j]-x[j-1]=dot_sep; y[j]=y[j-1]; drawdot z[j];
+  x[j]=x[j+10]=x[j+20];
+  y[j+10]=y[j+10-1]; drawdot z[j+10];
+  y[j+20]=y[j+20-1]; drawdot z[j+20];
+endfor
+penlabels(range 1 thru 8,range 11 thru 18,range 21 thru 28); endchar;

% 7 arrow negation pieces

@@ -1091,7 +1085,7 @@
y5-y1=.24asc_height+eps;
char_center(100); top y101=top y5; x101=x100+2u;
char_negate(100,101,102);
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Wider double negated arrow extension";
@@ -1105,7 +1099,7 @@
y5-y1=.24asc_height+eps;
char_center(100); top y101=top y5; x101=x100+2u;
char_negate(100,101,102);
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Triple negated arrow extension";
@@ -1119,7 +1113,7 @@
y7-y1=.24asc_height+eps;
char_center(100); top y101=top y7; x101=x100+2u;
char_negate(100,101,102);
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6); endchar;

cmchar "Squiggly negated arrow extension";
@@ -1131,10 +1125,10 @@
x1=0; x5=w;
pickup pencircle scaled rule_thickness;
draw z1{right}..{right}z2..{right}z3..{right}z4..{right}z5;
-y3:=math_axis+.24asc_height+eps;
-char_center(100); top y101=top y3; x101=x100+2u;
+y6:=math_axis+.24asc_height+eps;
+char_center(100); top y101=top y6; x101=x100+2u;
char_negate(100,101,102);
-endchar;
+penlabels(1,2,3,4,5); endchar;

cmchar "Single dashed negated arrow extension";
@@ -1149,7 +1143,7 @@
y10-y1=.24asc_height+eps;
char_center(100); top y101=top y10; x101=x100+2u;
char_negate(100,101,102);
-labels(0,1,2,3,4,5,6,7,8,100); endchar;
+penlabels(range 1 thru 8); endchar;

cmchar "Double dashed negated arrow extension";
@@ -1170,7 +1164,7 @@
y9-y1=.24asc_height+eps;
char_center(100); top y101=top y9; x101=x100+2u;
char_negate(100,101,102);
-labels(1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18); endchar;
+penlabels(range 1 thru 8,range 11 thru 18); endchar;

cmchar "Triple dashed negated arrow extension";
@@ -1194,50 +1188,63 @@
y77-y1=.24asc_height+eps;
char_center(100); top y101=top y77; x101=x100+2u;
char_negate(100,101,102);
-labels(1,2,3,4,5,6); endchar;
+penlabels(range 1 thru 8,range 11 thru 18,range 21 thru 28); endchar;
+
+% 8 arrow gaps

-% 7 arrow gaps
+cmchar "Single gap";
+beginchar(slot_GAP,arrow_ext_width#/3,single_height);
+endchar;

cmchar "Double gap";
beginchar(slot_doublegap,arrow_ext_width#/3,double_height);
endchar;

cmchar "Wide double gap";
beginchar(slot_widedoublegap,arrow_ext_width#/3,wide_double_height);
endchar;

cmchar "Triple gap";
beginchar(slot_triplegap,arrow_ext_width#/3,triple_height);
endchar;

cmchar "Squiggly gap";
beginchar(slot_squiggap,arrow_ext_width#/3,single_height);
endchar;

cmchar "Single dashed gap";
beginchar(slot_dashgap,arrow_ext_width#/3,single_height);
endchar;

cmchar "Double dashed gap";
beginchar(slot_Dashgap,arrow_ext_width#/3,double_height);
endchar;

cmchar "Triple dashed gap";
beginchar(slot_DASHgap,arrow_ext_width#/3,triple_height);
endchar;

% 7 gap extensions

cmchar "Double gap extension";
-beginchar(slot_doublegapext,4/3arrow_ext_width#,double_height);
+beginchar(slot_doublegapext,3/2arrow_ext_width#,double_height);
italcorr h#*slant-.5u#;
lft x1=hround(0-arrow_overshoot);   % hround u-eps;
@@ -1248,11 +1255,11 @@
draw z1--z5; draw z7--z2;  % upper bar
draw z3--z6; draw z8--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;

cmchar "Wide double gap extension";
-beginchar(slot_widedoublegapext,4/3arrow_ext_width#,wide_double_height);
+beginchar(slot_widedoublegapext,3/2arrow_ext_width#,wide_double_height);
italcorr h#*slant-.5u#;
lft x1=hround (0 - arrow_overshoot);
@@ -1264,11 +1271,11 @@
y6=y8=y3=y4=math_axis-.24asc_height-eps;
draw z1--z5; draw z7--z2;  % upper bar
draw z3--z6; draw z8--z4;  % lower bar
-labels(1,2,3,4); endchar;
+penlabels(1,2,3,4,5,6,7,8); endchar;

cmchar "Triple gap extension";
-beginchar(slot_triplegapext,4/3arrow_ext_width#,triple_height);
+beginchar(slot_triplegapext,3/2arrow_ext_width#,triple_height);
italcorr h#*slant-.5u#;
lft x1=hround 0 - arrow_overshoot; x5=x3=x1; x6=x2=x4=w-x1;
@@ -1278,7 +1285,7 @@
draw z1--z7; draw z10--z2;  % upper bar
draw z3--z8; draw z11--z4;  % lower bar
draw z5--z9; draw z12--z6;  % middle bar
-labels(1,2,3,4,5,6); endchar;
+penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;

cmchar "Squiggly gap extension";
@@ -1290,60 +1297,65 @@
pickup pencircle scaled rule_thickness;
draw z1{right}..z2{right}..z3{right}..z4{right}..z5{right};
unfill (1/3w,-d)--(2/3w,-d)--(2/3w,h)--(1/3w,h)--cycle;
-endchar;
+penlabels(1,2,3,4,5); endchar;

cmchar "Single dash gap extension";
-beginchar(slot_dashgapext,4/3arrow_ext_width#,single_height);
-pickup rule.nib;
-numeric dot_sep; dot_sep:=3/32w;
-y0=y1=y2=y3=y4=y5=y6=y7=y8=math_axis;
-x0=0;
-2(x1-x0)=x2-x1=x3-x2=dot_sep;
-w-x6=x1; w-x7=x2; w-x8=x3;
-drawdot z1; drawdot z2; drawdot z3;
-drawdot z6; drawdot z7; drawdot z8;
-labels(0,1,2,3,4,5,6,7,8); endchar;
+beginchar(slot_dashgapext,3/2arrow_ext_width#,single_height);
+numeric dot_sep; dot_sep:=w/12;
+x0=0; y0=math_axis;
+2(x1-x0)=dot_sep; x1'=w-x1; y1'=y1=y0;
+drawdot z1; drawdot z1';
+for j=2 thru 4:
+  w-x[j]'=x[j]=x[j-1]+dot_sep; y[j]'=y[j]=y0;
+  drawdot z[j]; drawdot z[j]';
+endfor
+penlabels(1,2,3,4,1',2',3',4'); endchar;

cmchar "Double dash gap extension";
-beginchar(slot_Dashgapext,4/3arrow_ext_width#,double_height);
+beginchar(slot_Dashgapext,3/2arrow_ext_width#,double_height);
italcorr h#*slant-.5u#;
-numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8;
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-x11=x1; x12=x2; x13=x3; x16=x6; x17=x7; x18=x8;
-x0=0; 2(x1-x0)=x2-x1=x3-x2=dot_sep;
-w-x6=x1; w-x7=x2; w-x8=x3;
-drawdot z1; drawdot z2; drawdot z3;
-drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13;
-drawdot z16; drawdot z17; drawdot z18;
-labels(1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18); endchar;
+numeric dot_sep; dot_sep:=w/12;
+2(x1-x0)=dot_sep; x1=x11; x1'=x11'=w-x1;
+y1'=y1=y0; y11'=y11=y10;
+drawdot z1; drawdot z1';
+drawdot z11; drawdot z11';
+for j=2 thru 4:
+  w-x[j]'=x[j]=x[j-1]+dot_sep; y[j]'=y[j]=y0;
+  x[j]=x[j+10]; x[j]'=x[j+10]';
+  y[j+10]'=y[j+10]=y[j+10-1];
+  drawdot z[j]; drawdot z[j]';
+  drawdot z[j+10]; drawdot z[j+10]';
+endfor
+penlabels(1,2,3,4,11,12,13,14,1',2',3',4',11',12',13',14'); endchar;

cmchar "Triple dash gap extension";
-beginchar(slot_DASHgapext,4/3arrow_ext_width#,triple_height);
+beginchar(slot_DASHgapext,3/2arrow_ext_width#,triple_height);
italcorr h#*slant-.5u#;
-numeric dot_sep; dot_sep:=w/8;
-y0=y1=y2=y3=y4=y5=y6=y7=y8;
-y10=y11=y12=y13=y14=y15=y16=y17=y18;
-y20=y21=y22=y23=y24=y25=y26=y27=y28;
-x21=x11=x1; x22=x12=x2; x23=x13=x3;
-x26=x16=x6; x27=x17=x7; x28=x18=x8;
-x0=0; 2(x1-x0)=x2-x1=x3-x2=dot_sep;
-w-x6=x1; w-x7=x2; w-x8=x3;
-drawdot z1; drawdot z2; drawdot z3;
-drawdot z6; drawdot z7; drawdot z8;
-drawdot z11; drawdot z12; drawdot z13;
-drawdot z16; drawdot z17; drawdot z18;
-drawdot z21; drawdot z22; drawdot z23;
-drawdot z26; drawdot z27; drawdot z28;
-labels(1,2,3,4,5,6); endchar;
+numeric dot_sep; dot_sep:=w/12;
+2(x1-x0)=dot_sep; x1=x11=x21; x1'=x11'=x21'=w-x1;
+y1'=y1=y0; y11'=y11=y10; y21'=y21=y20;
+drawdot z1; drawdot z1';
+drawdot z11; drawdot z11';
+drawdot z21; drawdot z21';
+for j=2 thru 4:
+  w-x[j]'=x[j]=x[j-1]+dot_sep; y[j]'=y[j]=y0;
+  x[j]=x[j+10]=x[j+20]; x[j]'=x[j+10]'=x[j+20]';
+  y[j+10]'=y[j+10]=y[j+10-1];
+  y[j+20]'=y[j+20]=y[j+20-1];
+  drawdot z[j]; drawdot z[j]';
+  drawdot z[j+10]; drawdot z[j+10]';
+  drawdot z[j+20]; drawdot z[j+20]';
+endfor
+penlabels(1,2,3,4,11,12,13,14,21,22,23,24,
+  1',2',3',4',11',12',13',14',21',22',23',24'); endchar;

cmchar "Left harpoon up";
@@ -1489,7 +1501,7 @@
--z3l{z9-z3}..z0 & cycle;  % arrowhead and stem
path p;
p:=ldarr shifted (0,y2-y4+eps); filldraw p; % top arrow
-p:= ldarr shifted (0,y2-y3-eps); filldraw p; % bottom arrow
+p:=ldarr shifted (0,y2-y3-eps); filldraw p; % bottom arrow
endchar;

cmchar "Left arrows up";
@@ -1503,7 +1515,7 @@
y5:=y6:=math_axis-.24asc_height-eps;
x5=hround(w+arrow_overshoot); lft x6=hround u;
draw z5---z6;
-endchar;
+endchar;

cmchar "Left arrows down";
@@ -1516,7 +1528,7 @@
y5:=y6:=math_axis+.24asc_height+eps;
x5=hround(w+arrow_overshoot); lft x6=hround u;
draw z5---z6;
-endchar;
+endchar;

cmchar "Right arrows";
@@ -1581,7 +1593,7 @@
y11=y12=math_axis;
pickup rule.nib;
draw z11---z12;
-penlabels(0,1,2,3,4,5,6,9); endchar;
+endchar;

cmchar "Left feathers";
@@ -1592,7 +1604,7 @@
y11=y12=math_axis;
pickup rule.nib;
draw z11---z12;
-endchar;
+endchar;

cmchar "Right feather";
@@ -1603,7 +1615,7 @@
y11=y12=math_axis;
pickup rule.nib;
draw z11---z12;
-penlabels(0,1,2,3,4,5,6,9); endchar;
+endchar;

cmchar "Right feathers";
@@ -1614,7 +1626,7 @@
y11=y12=math_axis;
pickup rule.nib;
draw z11---z12;
-penlabels(0,1,2,3,4,5,6,9); endchar;
+endchar;

cmchar "Right hook up";
@@ -1624,7 +1636,7 @@
x4=hround(-arrow_overshoot);
draw z1{right}...z2{down}...z3{left}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Right hook down";
@@ -1634,7 +1646,7 @@
x4=hround(-arrow_overshoot);
draw z1{right}...z2{up}...z3{left}---z4;  % hook
-labels(1,2,3); endchar;
+penlabels(1,2,3,4); endchar;

cmchar "Right curly up";
@@ -1658,30 +1670,33 @@
q=z15--z10{right}..tension0.8..{up}z11..tension0.8..{left}z12
..tension0.8..{down}z13--z14;
draw q;
-penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14); endchar;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar;

cmchar "Right curly down";
pickup pencircle scaled rule_thickness;
-draw q; endchar;
+draw q;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar;

cmchar "Left curly down";
pickup pencircle scaled rule_thickness;
-draw q; endchar;
+draw q;
+penlabels(0,1,2,3,4,5,6,9,10,11,12,13,14,15); endchar;

cmchar "Left curly up";