% mapunct.mf 1.2.0 94/10/11 -- punctuation % Copyright 1991, 1993 P. Damian Cugley %%% @METAFONT-file { %%% filename = "mapunct.mf", %%% version = "1.2.0", %%% date = "1994/10/11", %%% package = "Malvern 1.2", %%% author = "P. Damian Cugley", %%% email = "damian.cugley@comlab.ox.ac.uk", %%% address = "Oxford University Computing Laboratory, %%% Parks Road, Oxford OX1 3QD, UK", %%% codetable = "USASCII", %%% keywords = "Malvern, METAFONT, font, typefont, TeX", %%% supported = "Maybe", %%% abstract = "Punctuation character programs for the Malvern %%% font family.", %%% dependencies = "other program files", %%% } % See the Malvern Handbook (maman.tex) for more info about Malvern. % This software is available freely but without warranty. % See the file COPYING for details. %{{{ mapunct.mf ang_brack_wd# := 1/2 * (brack_ht# + brack_dp# - pn.ht#) * hratio + pn.wd#; if testing: endinput; fi %{{{ Hyphen + dashes dash_ht# := golden_ratio*x_ht# + 1/2pn.ht#; def do_dash(expr code, w_sharp) = ma_char(code, w_sharp - 2/3sp#, dash_ht#, 0pt#)(1/3,1/3); draw (rt l, bot h) -- (lft r, bot h); set_ic_tr; endchar enddef; if known code.hyphen: "hyphen"; do_dash(code.hyphen, 4u#); fi if known code.dup.hyphen: "spare hyphen"; do_dash(code.dup.hyphen, 4u#); fi if known code.en_dash: "short dash"; do_dash(code.en_dash, 8u#); fi if known code.em_dash: "long dash"; do_dash(code.em_dash, 16u#); fi %}}} %{{{ Dots and commas %{{{ How to draw a comma or inverted comma comma_ht# := 3v#; comma_wd# := 1u#; define_whole_vertical_pixels(comma_ht); define_whole_pixels(comma_wd); vardef draw_comma@#(expr up_p) = pickup pencircle scaled comma.pn.th; z@#z = (hround x@#, vround y@#); % this makes z@#c good.x and z@#d good.y, because comma_wd integer if up_p: bot else: top fi z@#d = z@#z + comma_ht * if up_p: down else: up fi; y@#c = 1/2[y@#z, y@#d]; if up_p: rt else: lft fi x@#c = if up_p: x@#z + comma_wd else: x@#z - comma_wd fi; 1/2[z@#a, z@#b] = z@#z; z@#b = z@#a + (dot_wd - comma.pn.th) * if up_p: (hratio, 1) else: (-hratio, -1) fi; draw z@#d .. z@#c{if up_p: up else: down fi} .. z@#b{(z@#z - z@#c) xscaled 2} .. z@#a{(z@#c - z@#z) xscaled 2} .. z@#c{if up_p: down else: up fi} .. z@#d; draw z@#d .. z@#c{if up_p: up else: down fi} .. z@#z{(z@#z - z@#c) xscaled 2}; % fill in any hole in middle labels(@#z, @#a, @#b, @#c, @#d) enddef; comma_dp# := comma_ht# - dot_ht# + 2o#; %}}} %{{{ .,:; def do_semicolon(expr code, t_p, comma_p) = ma_char(code, if comma_p: comma_wd# + 1/2dot_wd# else: dot_wd# fi, if t_p: x_ht# else: dot_ht# - 2o# fi, if comma_p: comma_dp# else: 0pt# fi)(1,1); z1 = (l + 1/2dot_wd, 1/2dot_ht - o); if comma_p: draw_comma1(true) else: draw_dot1 fi; if t_p: z2 = (x1, h - 1/2dot_ht + o); draw_dot2; fi set_ic_tr; endchar enddef; if known code.full_stop: "full stop"; do_semicolon(code.full_stop, false, false); fi if known code.comma: "comma"; do_semicolon(code.comma, false, true); fi if known code.comma1: "spare comma"; do_semicolon(code.comma1, false, true); fi if known code.colon: "colon"; do_semicolon(code.colon, true, false); fi if known code.semicolon: "semicolon"; do_semicolon(code.semicolon, true, true); fi if known code.gr.question: "Greek question mark"; do_semicolon(code.gr.question, true, true); fi %}}} %{{{ quotes iff known code.apostrophe: "apostrophe"; ma_char(code.apostrophe, comma_wd# + 1/2dot_wd#, asc_ht#, 0pt#)(1,1); z1 = (l + 1/2dot_wd, h - 1/2dot_ht + o); draw_comma1(true); set_ic_tr; endchar; iff known code.inv.comma: "inverted comma"; ma_char(code.inv.comma, comma_wd# + 1/2dot_wd#, asc_ht#, 0pt#)(1,1); z1 = (r - 1/2dot_wd, h - comma_ht + o); draw_comma1(false); set_ic_tr; endchar; iff known code.dbl.inv.comma: "double inverted comma"; ma_char(code.dbl.inv.comma, 2comma_wd# + u# + dot_wd#, asc_ht#, 0pt#)(1,1); z1 = (r - 1/2dot_wd, h - comma_ht + o); draw_comma1(false); z2 = (x1 - comma_wd - 1/2dot_wd - u, y1); draw_comma2(false); set_ic_tr; endchar; iff known code.dbl.apostrophe: "double apostrophe"; ma_char(code.dbl.apostrophe, 2comma_wd# + u# + dot_wd#, asc_ht#, 0pt#)(1,1); z1 = (l + 1/2dot_wd, h - 1/2dot_ht + o); draw_comma1(true); z2 = (x1 + comma_wd + 1/2dot_wd + u, y1); draw_comma2(true); set_ic_tr; endchar; iff known code.dbl.comma: "double comma"; ma_char(code.dbl.comma, 2comma_wd# + u# + dot_wd#, asc_ht#, comma_ht# - dot_ht# + 2o#)(1,1); z1 = (l + 1/2dot_wd, 1/2dot_ht - o); draw_comma1(true); z2 = (x1 + comma_wd + 1/2dot_wd + u, y1); draw_comma2(true); set_ic_tr; endchar; %}}} iff known code.cdot: "raised dot"; ma_char(code.cdot, dot_wd#, axis_ht# + dot_ht# - 2o#, 0pt#)(1,1); z1 = (l + 1/2dot_wd, h - 1/2dot_ht + o); draw_dot1; set_ic_tr; endchar; iff known code.gr.colon: "Greek colon"; ma_char(code.gr.colon, dot_wd#, axis_ht# + dot_ht# - 2o#, 0pt#)(1,1); z1 = (l + 1/2dot_wd, h - 1/2dot_ht + o); draw_dot1; set_ic_tr; endchar; %}}} %{{{ brackets of different sorts def ma_brack(expr code, edoc, w_sh, lrsp, rlsp) = ma_char(if b: code else: edoc fi, w_sh, brack_ht#, brack_dp#) if b: (lrsp, rlsp) else: (rlsp, lrsp) fi enddef; for i = 0, 1: b := (i = 0); %{{{ parenthesis iff known code.paren.left: leftright "parenthesis"; ma_brack(code.paren.left, code.paren.right, 4u#)(1,1/3); numeric twist; twist = 3; top rtlft z1 = (rl, h + o); bot rtlft z3 = (rl, -d - o); y2 = 1/2[y1, y3]; lftrt x2 = lr; draw z1{(z2 - z1) xscaled twist} .. z2 .. {(z3 - z2) xscaled twist}z3; labels(1,2,3); if b: set_ic_tr; else: set_ic 0.7charht; fi endchar; %}}} %{{{ bracket iff known code.brack.left: leftright "bracket"; ma_brack(code.brack.left, code.brack.right, pn.wd# + 2u#)(1,1/3); lftrt x2 = lftrt x3 = lr; rtlft x1 = rtlft x4 = rl; top y1 = top y2 = h; bot y3 = bot y4 = -d; draw z1 -- z2 -- z3 -- z4; labels(1,2,3,4); set_ic_tr; endchar; %}}} %{{{ angle bracket iff known code.anglebr.left: leftright "angle bracket"; ma_brack(code.anglebr.left, code.anglebr.right, ang_brack_wd#)(1,0); top rtlft z1 = (rl, h); bot rtlft z3 = (rl, -d); lftrt z2 = (lr, 1/2[-d, h]); draw z1 -- z2 -- z3; labels(1,2,3); if b: set_ic_tr; else: set_ic 1/2[brack_ht#, brack_dp#]; fi endchar; %}}} %{{{ brace iff known code.brace.left: leftright "brace"; ma_brack(code.brace.left, code.brace.right, 6u#)(1/2,1/3); if 1/2[-d,h] <> good.y 1/2[-d,h]: change_depth; fi rtlft x1top = rtlft x1bot = rl; lftrt x1mid = lr; y1mid = y2mid = 1/2[-d, h]; top y1top = top y2top = h; bot y1bot = bot y2bot = -d; x3top = x4top = x3bot = x4bot = good.x 0.45[x1mid, x1top]; x2top = x2bot = 3/4[x3top, x1top]; x2mid = 3/4[x4top, x1mid]; z3top = z2top + whatever*(plus hratio,1); z4top = z2mid + whatever*(plus hratio,1); z3bot = z2bot + whatever*(minus hratio,1); z4bot = z2mid + whatever*(minus hratio,1); draw z1top --- z2top .. z3top --- z4top .. z2mid --- z1mid --- z2mid .. z4bot --- z3bot .. z2bot --- z1bot; labels(forsuffixes $=top, bot: 1$, 2$, 3$, 4$, endfor 1mid, 2mid); if b: set_ic_tr; else: set_ic 1/2[brack_ht#, brack_dp#]; fi endchar; %}}} endfor %}}} %{{{ exclam. and question marks iff known code.exclam: "exclamation mark"; ma_char(code.exclam, max(pn.wd#, dot_wd#), cap_ht#, 0pt#)(5/4,5/4); if 1/2w <> good.x 1/2w: change_width; fi z1 = (1/2w, 1/2dot_ht - o); draw_dot1; bot y2 = max(dot_ht + 2v, 1/4[-d, h]); top y3 = h + o; x2 = x3 = 1/2w; draw z2 -- z3; labels(1,2,3); set_ic_tr; endchar; iff known code.inv.exclam: "inverted exclamation mark"; ma_char(code.inv.exclam, max(pn.wd#, dot_wd#), x_ht#, desc_dp#)(5/4,5/4); if 1/2w <> good.x 1/2w: change_width; fi z1 = (1/2w, h - 1/2dot_ht + o); draw_dot1; top y2 = min(h - dot_ht - 2v, 1/4[h, -d]); bot y3 = -d - o; x2 = x3 = 1/2w; draw z2 -- z3; labels(1,2,3); set_ic_tr; endchar; def draw_question expr bb = b := bb; topbot y2 = hd plus o; rtlft x3 = rl; lftrt x1 = lr; x2 = x4 = x6 = 0.55[x3, x1]; y6 = y7 = good.y maxmin(dh plus dot_ht plus 2v, 1/4[dh, hd]); y3 = 1/2[y2,y4]; y5 = 1/2[y6,y4]; y4 = good.y (2/3[y2,y6]); y1 = hd minus v; x7 = x6 plus u; x5 = good.x (x6 minus 1.5u); draw z1 ... z2{(x3 - x1, 0)} ... z3{(0, y4 - y2)} ... z4 ... z5{(0, y6 - y4)} ... z6 --- z7; z0 = (x2, dh plus 1/2dot_ht minus o); draw_dot0; labels(0, 1,2,3,4,5,6,7); enddef; iff known code.question: "question mark"; ma_char(code.question, 7u#, cap_ht#, 0v#)(1/2,2/3); draw_question true; set_ic 0.9h#; endchar; iff known code.inv.question: "inverted question mark"; ma_char(code.inv.question, 7u#, x_ht#, desc_dp#)(2/3,1/2); draw_question false; set_ic 0.6h#; endchar; %}}} %{{{ Guillemets guil_wd# := 1/2(x_ht# - pn.ht#)*hratio + pn.wd#; guil_adj# := -u#; define_whole_pixels(guil_wd, guil_adj); vardef guil@#(expr leftx) = lftrt x@#2 = good.x leftx plus eps; y@#2 = good.y 1/2[-d, h]; z@#1 = z@#2 + whatever * if b: ne else: se fi; z@#3 = z@#2 + whatever * if b: se else: ne fi; x@#1 = x@#3; bot y@#3 = -d; draw z@#1 -- z@#2 -- z@#3; labels(@#1, @#2, @#3); enddef; for i = 0,1: b := (i = 0); iff known code.guillemet.single.left: leftright "single guillemet"; ma_char(if b: code.guillemet.single.left else: code.guillemet.single.right fi, guil_wd#, x_ht#, 0v#) if b: (1,1/2) else: (1/2,1) fi; guil(lr); if b: set_ic_tr; else: set_ic 1/2x_ht#; fi endchar; iff known code.guillemet.left: leftright "guillemet"; ma_char(if b: code.guillemet.left else: code.guillemet.right fi, 2guil_wd# + guil_adj#, x_ht#, 0v#) if b: (1,1/2) else: (1/2,1) fi; guil$(lr); guil#(lr plus guil_wd plus guil_adj); if b: set_ic_tr; else: set_ic 1/2x_ht#; fi endchar; endfor %}}} %}}} %Local variables: %fold-folded-p: t %End: