diff options
Diffstat (limited to 'systems/unix/tex-gpc/mp')
-rw-r--r-- | systems/unix/tex-gpc/mp/README | 186 | ||||
-rw-r--r-- | systems/unix/tex-gpc/mp/dvitomp.ch | 208 | ||||
-rw-r--r-- | systems/unix/tex-gpc/mp/mk_MP_dir | 2 | ||||
-rw-r--r-- | systems/unix/tex-gpc/mp/mp.ch | 651 | ||||
-rw-r--r-- | systems/unix/tex-gpc/mp/mptotex.c | 224 | ||||
-rw-r--r-- | systems/unix/tex-gpc/mp/mpx | 8 |
6 files changed, 1279 insertions, 0 deletions
diff --git a/systems/unix/tex-gpc/mp/README b/systems/unix/tex-gpc/mp/README new file mode 100644 index 0000000000..eab901fca6 --- /dev/null +++ b/systems/unix/tex-gpc/mp/README @@ -0,0 +1,186 @@ +Aug. 2008 +This is the stage directory to build and install John Hobby's +METAPOST for GPC. METAPOST produces pictures as PostScript files +that are to be included by dvips in its output. + +METAPOST's file formats and their documentation: +------------------------------------------------ +.mp METAPOST source, + see "A User's manual for MetaPost", AT&T Bell Laboratories + Computing Science Technical Report 162, 1992 +.mpx METAPOST source, auxiliary file, needed if a .mp file contains text. +.mem METAPOST format file (plain.mp) +.c C source (Kernighan/Ritchie The C Programming Language) +.ps Adobe PostScript +.<n> Where n an integer, a PostScript file for picture n, to be included + by dvips. + + +builtin file names: +------------------ +MPlib/mp.pool string pool for mp, (in inimp) +MPlib/plain.mem base file for Plain METAFONT, (in mf) + +METAPOST's processors: +---------------------- + inimp + plain.mp -------> MPlib/plain.mem + + mp +.mp, .mpx -------> .n + + mptotex +.mp -------> .tex + + tex +.tex -------> .dvi + + dvitomp +.dvi --------> .mpx + + mpx +.mp --------> .n (combines the last four steps) + +Use the shell script mpx instead of mp if your .mp file contains +TeX programs. These extra steps are necessary to include TeX's output +in the picture. + +And finally: + dvips +.<n>, .dvi, .pk, .tfm ----> PostScript file/printer + + +Get John Hobby's distribution +----------------------------- +The sources from CTAN only work with web2c but not with WEB programs, +so I downloaded the originals from netlib: + ftp ftp://ftp.netlib.org/research/metapost.tar.Z +unpack it with uncompress and tar xf: + uncompress metapost.tar.Z + tar xf metapost.tar +This will give you a directory metapost, from which you copy at least +mp.web, plain.mp, mptotex.c and dvitomp.web into this directory. + +Masterdirectories: +------------------ +Create the master directories MPlib and MPinputs. Prepare a directory from +where you want to run mp with the shell script mk_MP_dir. +(Additionally to mk_TeX_dir) + +Building and installing: +----------------------- +Move a.out into your binary directory under the name at the +right end of --->. + +1. mp.web, mp.ch ---> inimp +Change mp.ch for initialization (see building inimf, initex) and tgl. +Move mp.pool to MPlib. + +2. plain.mp ---> MPlib/plain.mem + inimp plain.mp dump +mv plain.mem to MPlib + +3. mp.web, mp.ch ---> mp +Change mp.ch for production (see building inimf, initex) and tgl. + +4. dvitomp.web, dvitomp.ch ---> dvitomp +Just tgl and move a.out as dvitomp to your binary directory + +5. mptotex.c ---> mptotex +cc mptotex.c, ignore the warning and move a.out to .... + +6. mpx ---> mpx (just move the shell script to your binary dir) + +Using MetaPost: +-------------- +To include a MetaPost picture xxx.mp in your output, \input +the TeX macro epsf.tex. At the place where you want to include your +picture, write + \epsfbox{xxx.n} +where xxx is the name of the picture and n is the argument given +in the beginfig() command. + +Here are those files: +fig.mp + +beginfig(1); +a=.7in; b=0.5in; +z0=(0,); z1=(a,0); z2=(0,b); +z0=.5[z1,z3]=.5[z2,z4]; +draw z1..z2..z3..z4..cycle; +drawarrow z0..z1; +drawarrow z0..z2; +label.top(btex $a$ etex, .5[z0, z1]); +label.lft(btex $b$ etex, .5[z0, z2]); +endfig; +end + +fig.mp contains two Tex programs, $a$ and $b$. So you need to call mpx instead +of mp. This creates fig.mpx: + +% Written by DVItoMP-GPC +begingroup save _p,_r,_s,_n; picture _p; _p=nullpicture; +string _n[]; +vardef _s(expr _t,_f,_m,_x,_y)= + addto _p also _t infont _f scaled _m shifted (_x,_y); enddef; +_n0="cmmi10"; +_s("a",_n0,1.00000,0.0000,0.0000); +setbounds _p to (0,0.0000)--(5.2661,0.0000)-- + (5.2661,4.2895)--(0,4.2895)--cycle; +_p endgroup +mpxbreak +begingroup save _p,_r,_s,_n; picture _p; _p=nullpicture; +string _n[]; +vardef _s(expr _t,_f,_m,_x,_y)= + addto _p also _t infont _f scaled _m shifted (_x,_y); enddef; +_n0="cmmi10"; +_s("b",_n0,1.00000,0.0000,0.0000); +setbounds _p to (0,0.0000)--(4.2756,0.0000)-- + (4.2756,6.9185)--(0,6.9185)--cycle; +_p endgroup +mpxbreak + +From fig.mp and fig.mpx METAPOST creates fig.1 + +%!PS +%%BoundingBox: -51 -37 51 37 +%%Creator: MetaPost +%%CreationDate: 2008.08.25:1829 +%%Pages: 1 +%*Font: cmmi10 9.96265 9.96265 61:c +%%EndProlog +%%Page: 1 1 + 0 0.5 dtransform truncate idtransform setlinewidth pop [] 0 setdash + 1 setlinejoin 10 setmiterlimit +newpath 50.39978 0 moveto +50.39978 23.04858 25.56044 36 0 36 curveto +-25.56044 36 -50.39978 23.04858 -50.39978 0 curveto +-50.39978 -23.04858 -25.56044 -36 0 -36 curveto +25.56044 -36 50.39978 -23.04858 50.39978 0 curveto closepath stroke + 1 setlinecap +newpath 0 0 moveto +50.39978 0 lineto stroke +newpath 46.70451 -1.53067 moveto +50.39978 0 lineto +46.70451 1.53067 lineto + closepath +gsave fill grestore stroke + 0.5 0 dtransform exch truncate exch idtransform pop setlinewidth +newpath 0 0 moveto +0 36 lineto stroke + 0 0.5 dtransform truncate idtransform setlinewidth pop +newpath 1.5308 32.3044 moveto +0 36 lineto +-1.5308 32.3044 lineto + closepath +gsave fill grestore stroke +22.56683 3 moveto +(a) cmmi10 9.96265 fshow +-7.2756 14.54074 moveto +(b) cmmi10 9.96265 fshow +showpage +%%EOF + +Finally, include the figure in your TeX document by +\input epsf +\epsfbox{fig.1} diff --git a/systems/unix/tex-gpc/mp/dvitomp.ch b/systems/unix/tex-gpc/mp/dvitomp.ch new file mode 100644 index 0000000000..1d8f7db09d --- /dev/null +++ b/systems/unix/tex-gpc/mp/dvitomp.ch @@ -0,0 +1,208 @@ +% This is a change file of DVItoMP-GPC, Wolfgang Helbig, Aug. 2008 +To be used with the GNU Pascal Compiler Version 2.1 + +[0] About DVItoMP-GPC +@x +\pageno=\contentspagenumber \advance\pageno by 1 +@y +\pageno=\contentspagenumber \advance\pageno by 1 +\input webmac-gpc + +% \let\maybe=\iffalse % uncomment to print changed modules only. + +\def\name{\tt DVItoMP} + +\N0\*. About \namegpc.\fi + +This is an adaption of John Hobby's \name, version 0.64, to Unix +and GNU~Pascal, version 2.1. + +This program expects the input file (\.{.dvi}) and the output file, +(\.{mpx}) which is a text file, on the command line. To support shell +scripting, \namegpc\ sets the exit code to one when something was +wrong with the input file. + +\hint + +Comments and questions are welcome! + +\bigskip +\address +@z +[1] Change the banner line +@x +@d banner=='% Written by DVItoMP, Version 0.64' +@y +@d banner=='% Written by DVItoMP-GPC' +@z + +[3] only stdio files in program header. +@x +@p program DVI_to_MP(@!dvi_file,@!mpx_file,@!output); +@y +@p +@{@&$I-@} {no I/O checking} +program DVI_to_MP(input, output); +@z + +[9] check command line arguments +@x +history:=spotless; +@y +history:=spotless; +if param_count <> 2 then + begin write_ln('Usage: dvitomp dvi_file mpx_file'); halt(1); + end; +@z + +[12] Pascal's type of text_files is text +@x +@!text_file=packed file of text_char; +@y +@!text_file=text; +@z + +[14] get file name from command line +@x +begin rewrite(mpx_file); +@y +begin +rewrite(mpx_file, param_str(2)); +@z + +[17] use GPC extension for packing subranges. +@x +@!eight_bits=0..255; {unsigned one-byte quantity} +@y +@!eight_bits=packed 0..255; {unsigned one-byte quantity} +@z + +[22] declare out_file +@x +@!tfm_file:byte_file; {a font metric file} +@y +@!tfm_file:byte_file; {a font metric file} +@!out_file:text; {the outfile} +@z + +[19] open file whose name is not known at compile time +@x +has acted, these routines assume that no file named |s| is accessible. +@y +has acted, these routines assume that no file named |s| is accessible. +@d io_ok==io_result=0 +@d clear_io_result==@+if io_result=0 then +@z + +@x +begin reset(dvi_file); +@y +begin reset(dvi_file, param_str(1)); +@z + +@x +begin reset(tfm_file,cur_name); +@y +begin reset(tfm_file,trim(cur_name)); {ignore leading and trailing blanks} +@z + +@x +begin reset(vf_file,cur_name); +open_vf_file:=(not eof(vf_file)); +@y +begin clear_io_result; reset(vf_file,trim(cur_name)); + open_vf_file:=io_ok; +@z + + [28] no random access + @x; + begin set_pos(dvi_file,-1); dvi_length:=cur_pos(dvi_file); + end; + @# + procedure move_to_byte(n:integer); + begin set_pos(dvi_file,n); cur_loc:=n; + end; + @y; + begin do_nothing; + end; + @# + procedure move_to_byte(n:integer); + begin do_nothing; + end; + @z + +[47] + @x + is always at least one blank space in |buffer|. + @^system dependencies@> + + @p procedure input_ln; {inputs a line from the terminal} + var k:0..terminal_line_length; + begin update_terminal; reset(term_in); + if eoln(term_in) then read_ln(term_in); + k:=0; + while (k<terminal_line_length)and not eoln(term_in) do + begin buffer[k]:=xord[term_in^]; incr(k); get(term_in); + end; + buffer[k]:=" "; + end; + @y + is always at least one blank space in |buffer|. + This is changed here: |term_in| is standard input and is not supposed + to be opened. There is never an end-of-line marker at the beginning of + a line but always at the end of a line. + @^system dependencies@> + + @p procedure input_ln; {inputs a line from the terminal} + var k:0..terminal_line_length; + begin update_terminal; + k:=0; + while (k<terminal_line_length)and not eoln(term_in) do + begin buffer[k]:=xord[term_in^]; incr(k); get(term_in); + end; + read_ln(term_in); + buffer[k]:=" "; + end; + @z + + [50] don't rewrite output file, write the banner while initializing + @x + begin rewrite(term_out); {prepare the terminal for output} + write_ln(term_out,banner); + @y + begin + @z + +[61] +@x +@d default_directory_name=='TeXfonts:' {change this to the correct name} +@y +@d default_directory_name=='TeXfonts/' {change this to the correct name} +@z + +[63] lowercase filename +@x + if (names[k]>="a")and(names[k]<="z") then + cur_name[l]:=xchr[names[k]-@'40] + else cur_name[l]:=xchr[names[k]]; + end; +cur_name[l+1]:='.'; cur_name[l+2]:='V'; cur_name[l+3]:='F' +@y + cur_name[l]:=xchr[names[k]] + end; +cur_name[l+1]:='.'; cur_name[l+2]:='v'; cur_name[l+3]:='f' +@z + +[64] lowercase filename +@x +cur_name[l+2]:='T'; cur_name[l+3]:='F'; cur_name[l+4]:='M' +@y +cur_name[l+2]:='t'; cur_name[l+3]:='f'; cur_name[l+4]:='m' +@z + +[107] set exit code +@x +final_end:end. +@y +final_end:halt(history) end. +@z diff --git a/systems/unix/tex-gpc/mp/mk_MP_dir b/systems/unix/tex-gpc/mp/mk_MP_dir new file mode 100644 index 0000000000..7e755a9d40 --- /dev/null +++ b/systems/unix/tex-gpc/mp/mk_MP_dir @@ -0,0 +1,2 @@ +ln -s ~/MPlib . +ln -s ~/MPinputs . diff --git a/systems/unix/tex-gpc/mp/mp.ch b/systems/unix/tex-gpc/mp/mp.ch new file mode 100644 index 0000000000..60dec6ee13 --- /dev/null +++ b/systems/unix/tex-gpc/mp/mp.ch @@ -0,0 +1,651 @@ +% This is a change file of METAPOST for GPC, Wolfgang Helbig, Aug. 2008 +% See tex.ch and mf.ch from tex-gpc +[0] to print changed sections only +@x +\def\gglob{20, 26} % this should be the next two sections of "<Global...>" +@y +\def\gglob{20, 26} % this should be the next two sections of "<Global...>" +\input webmac-gpc +\emergencystretch 0.5in % avoid overfull boxes + +% \let\maybe=\iffalse % uncomment to print changed modules only. + +\def\name{\MP} + +\N0\*. \[0] About \namegpc. + +This is an adaption of John Hobby's \MP, version 0.641, to Unix, +and GNU~Pascal, version 2.1. + +The features added include treating the command line as the first +input line and invoking a system editor, in this case \.{vi}, to +let the user correct the input file. +On exit, \namegpc\ passes its `history' to the operating system. + +\hint + +Comments and questions are welcome! + +\bigskip +\address +\fi +@z + +[2] Change the banner line +@x +@d banner=='This is MetaPost, Version 0.641' {printed when \MP\ starts} +@y +@d banner=='This is MetaPost-GPC' {printed when \MP\ starts} +@z + +[4] terminal output and input +@x +@d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:} +@y +@d term_in==i@&n@&p@&u@&t +@d term_out==o@&u@&t@&p@&u@&t +@d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:} +@z + +[4] terminal output and input +@x +program MP; {all file names are defined dynamically} +@y +program MP(@!term_in,@!term_out); +{all other file names are defined dynamically} +import gpc only (gpc_execute,gpc_install_signal_handler, + gpc_t_signal_handler, gpc_sig_int); +@z + +[4] forward reference for signal handler +@x +procedure initialize; {this procedure gets things started properly} +@y +procedure set_interrupt(signal: gpc_integer); forward; @t\2@> +{|initialize| installs |set_interrupt| as a Unix signal handler} +@# +procedure initialize; {this procedure gets things started properly} +@z + +Since @x, @y, and @z only define a change block when they begin a +line, you deactivate a block by indenting it (shift right) and +activate it by unindenting it (shift left). With vi set the +cursor to the @x line and enter >} or <} to (un)indent a paragraph. + +[7] shift left to turn debugging on, right to turn it off +@x +@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging} +@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging} +@y +@d debug== {change this to `$\\{debug}\equiv\.{@@\{}$' when not debugging} +@d gubed== {change this to `$\\{gubed}\equiv\.{@@\}}$' when not debugging} +@z + +[7] shift left to turn on statistics, shift rigth to turn off statistics +@x +@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering + usage statistics} +@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering + usage statistics} +@y +@d stat== {change this to `$\\{stat}\equiv\.{@@\{}$' to turn off statistics} +@d tats== {change this to `$\\{tats}\equiv\.{@@\}}$' to turn off statistics} +@z + +[8] shift left to build MP and right it to build INIMP. + @x inimp + @d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version} + @d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version} + @y + @d init==@{ + @d tini==@} + @z + +[9] compiler directives, turn off I/O checking. +@x +@{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} +@!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} +@y +@{@&$I-@} {no I/O checking} +@z + +[10] default case branch +@x +@d othercases == others: {default for cases not listed explicitly} +@y +@d othercases == @+ else {default for cases not listed explicitly} +@z + +[11] location of pool file +@x +@!pool_name='MPlib:MP.POOL '; + {string of length |file_name_size|; tells where the string pool appears} +@.MPlib@> +@!ps_tab_name='MPlib:PSFONTS.MAP '; + {string of length |file_name_size|; locates font name translation table} +@y +@!pool_name='MPlib/mp.pool '; + {string of length |file_name_size|; tells where the string pool appears} +@.MPlib@> +@!ps_tab_name='MPlib/psfonts.map '; + {string of length |file_name_size|; locates font name translation table} +@z + + +[22] accept tab and formfeed +@x +for i:=0 to @'37 do xchr[i]:=' '; +@y +for i:=0 to @'37 do xchr[i]:=' '; +xchr[@'11] := chr(@'11); {accept horizontal tab} +xchr[@'14] := chr(@'14); {accept form feed} +@z + +[24] the type of text_files is text in ISO Pascal +@x +@!eight_bits=0..255; {unsigned one-byte quantity} +@!alpha_file=packed file of text_char; {files that contain textual data} +@y +@!eight_bits=packed 0..255; {unsigned one-byte quantity} +@!alpha_file=t@&e@&x@&t; {coding trick is needed since |text| is a macro} +@z + +[26] dynamic io +@x +@d reset_OK(#)==erstat(#)=0 +@d rewrite_OK(#)==erstat(#)=0 +@y +@d gpc_trim==t@&r@&i@&m +@d gpc_io_result==i@&o@&r@&e@&s@&u@&l@&t +@d reset_OK(#)==gpc_io_result=0 +@d rewrite_OK(#)==gpc_io_result=0 +@d clear_io_result==@+if gpc_io_result=0 then do_nothing +@z + +[26] (reset and rewrite for each of three file types) alpha +@x +begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f); +@y +begin clear_io_result; reset(f,gpc_trim(name_of_file)); a_open_in:=reset_OK(f); +@z + +[26] +@x +begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f); +@y +begin clear_io_result; rewrite(f,gpc_trim(name_of_file)); +a_open_out:=rewrite_OK(f); +@z + +[26] byte file +@x +begin reset(f,name_of_file,'/O'); b_open_in:=reset_OK(f); +@y +begin clear_io_result; reset(f,gpc_trim(name_of_file)); b_open_in:=reset_OK(f); +@z + +@x +begin rewrite(f,name_of_file,'/O'); b_open_out:=rewrite_OK(f); +@y +begin clear_io_result; rewrite(f,gpc_trim(name_of_file)); +b_open_out:=reset_OK(f); +@z + +[26] word_file +@x +begin reset(f,name_of_file,'/O'); w_open_in:=reset_OK(f); +@y +begin clear_io_result; reset(f,gpc_trim(name_of_file)); w_open_in:=reset_OK(f); +@z + +[26] +@x +begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f); +@y +begin clear_io_result; rewrite(f,gpc_trim(name_of_file)); +w_open_out:=rewrite_OK(f); +@z + +[30] eoln handling +@x +@p function input_ln(var @!f:alpha_file;@!bypass_eoln:boolean):boolean; + {inputs the next line or returns |false|} +var @!last_nonblank:0..buf_size; {|last| with trailing blanks removed} +begin if bypass_eoln then if not eof(f) then get(f); + {input the first character of the line into |f^|} +last:=first; {cf.\ Matthew 19\thinspace:\thinspace30} +if eof(f) then input_ln:=false +else begin last_nonblank:=first; + while not eoln(f) do + begin if last>=max_buf_stack then + begin max_buf_stack:=last+1; + if max_buf_stack=buf_size then + @<Report overflow of the input buffer, and abort@>; + end; + buffer[last]:=xord[f^]; get(f); incr(last); + if buffer[last-1]<>" " then last_nonblank:=last; + end; + last:=last_nonblank; input_ln:=true; + end; +end; +@y +@p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean; + {inputs the next line or returns |false|} +begin + {ignore |bypass_eoln|. Assuming |f| being positioned at the first character} +last:=first; {cf.\ Matthew 19\thinspace:\thinspace30} +if eof(f) then input_ln:=false +else begin + while not eoln(f) do + begin if last>=max_buf_stack then + begin max_buf_stack:=last+1; + if max_buf_stack=buf_size then begin + read_ln(f); {complete the current line} + @<Report overflow of the input buffer, and abort@>; + end; + end; + buffer[last]:=xord[f^]; get(f); incr(last); + end; + get(f); {Advance |f| to the first character of the next line} + input_ln:=true; + end; +end; +@z + +[31] term_in and term_out are the standard pascal files +@x +is considered an output file the file variable is |term_out|. +@^system dependencies@> + +@<Glob...@>= +@!term_in:alpha_file; {the terminal as an input file} +@!term_out:alpha_file; {the terminal as an output file} +@y +is considered an output file the file variable is |term_out|. +The file |term_in| is declared as \\{input} and |term_out| as +\\{output} in the program header. +@z + +[32] +@x +@d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input} +@d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output} +@y +@d t_open_in==do_nothing {open the terminal for text input} +@d t_open_out==do_nothing {open the terminal for text output} +@z + +[33] +@x +@d update_terminal == break(term_out) {empty the terminal output buffer} +@d clear_terminal == break_in(term_in,true) {clear the terminal input buffer} +@y +@d update_terminal == do_nothing {empty the terminal output buffer} +@d clear_terminal == do_nothing {clear the terminal input buffer} +@z + +[35] command line +@x +@d loc==cur_input.loc_field {location of first unread character in |buffer|} +@y +@d loc==cur_input.loc_field {location of first unread character in |buffer|} +@d gpc_string==s@&t@&r@&i@&n@&g {a string with varying length} +@d gpc_length==l@&e@&n@&g@&t@&h +@d gpc_param_count==p@&a@&r@&a@&m@&c@&o@&u@&n@&t +@d gpc_param_str==p@&a@&r@&a@&m@&s@&t@&r + +{GPC function returning the length of a |gpc_string|} + +@p procedure input_command_ln; {get the command line in |buffer|} +var argc: integer; {argument counter} + arg: gpc_string; {argument} + cc: integer; {character counter in argument} +begin last := first; argc := 1; +while argc <= gpc_param_count do + begin cc := 1; arg := gpc_param_str(argc); incr(argc); + while cc <= gpc_length(arg) do + begin + if last+1>=buf_size then + @<Report overflow of the input buffer, and abort@>; + buffer[last] := xord[arg[cc]]; incr(last); incr(cc); + end; + if (argc <= gpc_param_count) then begin + buffer[last] := " "; incr(last); + end; + end; +end; +@z + +[36] command line +@x +@p function init_terminal:boolean; {gets the terminal input started} +label exit; +begin t_open_in; +loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal; +@.**@> + if not input_ln(term_in,true) then {this shouldn't happen} + begin write_ln(term_out); + write(term_out,'! End of file on the terminal... why?'); +@.End of file on the terminal@> + init_terminal:=false; return; + end; + loc:=first; + while (loc<last)and(buffer[loc]=" ") do incr(loc); + if loc<last then + begin init_terminal:=true; + return; {return unless the line was all blank} + end; + write_ln(term_out,'Please type the name of your input file.'); + end; +exit:end; +@y +@p function init_terminal:boolean; {gets the terminal input started} +label exit; +begin t_open_in; input_command_ln; +while first=last do begin + wake_up_terminal; write(term_out,'**'); update_terminal; +@.**@> + if not input_ln(term_in, true) then {this shouldn't happen} + begin write_ln(term_out); + write_ln(term_out,'! End of file on the terminal... why?'); +@.End of file on the terminal@> + init_terminal:=false; return; + end; + if first=last then + write_ln(term_out,'Please type the name of your input file.'); + end; +loc := first; {trim leading spaces} +while buffer[loc]=" " do incr(loc); +init_terminal:=true; +exit: end; +@z + +[76] print banner line on terminal +@x +@<Initialize the output...@>= +update_terminal; +@y +@<Initialize the output...@>= +wterm(banner); +if mem_ident=0 then wterm_ln(' (no mem preloaded)') +else begin print(mem_ident); print_ln; + end; +update_terminal; +@z + +[89] start editor +@x +@!use_err_help:boolean; {should the |err_help| string be shown?} +@y +@!use_err_help:boolean; {should the |err_help| string be shown?} +@!edit_line: integer; {line number to be passed to the system editor} +@!edit_file_name: str_number; {file name to be passed to the system editor} +@z + +[90] initial value for edit argument +@x +help_ptr:=0; use_err_help:=false; err_help:=0; +@y +help_ptr:=0; use_err_help:=false; err_help:=0; +edit_line:=0; edit_file_name:=0; +@z + +[94] set edit_cmd +@x + begin print_nl("You want to edit file "); +@.You want to edit file x@> + print(input_stack[file_ptr].name_field); + print(" at line "); print_int(true_line);@/ + interaction:=scroll_mode; jump_out; + end; +@y + begin {save values to be passed to the system editor} + edit_file_name := input_stack[file_ptr].name_field; + add_str_ref(edit_file_name); + edit_line := true_line; + interaction:=scroll_mode; jump_out; + end; +@z + +[106] interrupt is predefined and not implemented in GNU~Pascal +@x +@d check_interrupt==begin if interrupt<>0 then pause_for_instructions; +@y +@d interrupt==buginterrupt +@f interrupt==true +@d check_interrupt==begin if interrupt<>0 then pause_for_instructions; +@z + +[171] pack subranges +@x +@!quarterword = min_quarterword..max_quarterword; {1/4 of a word} +@!halfword=min_halfword..max_halfword; {1/2 of a word} +@y +@!quarterword = packed min_quarterword..max_quarterword; {1/4 of a word} +@!halfword=packed min_halfword..max_halfword; {1/2 of a word} +@z + +[212] time and date +@x +begin internal[time]:=12*60*unity; {minutes since midnight} +internal[day]:=4*unity; {fourth day of the month} +internal[month]:=7*unity; {seventh month of the year} +internal[year]:=1776*unity; {Anno Domini} +@y +var t: time_stamp; +begin +get_time_stamp(t); +internal[time]:=(t.minute + t.hour*60)*unity; {minutes since midnight} +internal[day]:=t.d@&a@&y*unity; +internal[month]:=t.m@&o@&n@&t@&h*unity; +internal[year]:=t.y@&e@&a@&r*unity; {Anno Domini} +@z + +[217] character class for tab and lf +@x +for k:=127 to 255 do char_class[k]:=invalid_class; +@y +for k:=127 to 255 do char_class[k]:=invalid_class; +char_class[@'11] := space_class; +char_class[@'14] := space_class; +@z + +[640] spurious empty line on terminal +@x + print_ln; first:=start; + prompt_input("*"); {input on-line into |buffer|} +@y + print_nl(""); + first:=start; {avoid empty lines on terminal and log file} + prompt_input("*"); {input on-line into |buffer|} +@z + +[746] Path separator in Unix +@x +@d MP_area=="MPinputs:" +@.MPinputs@> +@d MF_area=="MFinputs:" +@.MFinputs@> +@d MP_font_area=="TeXfonts:" +@.TeXfonts@> +@y +@d MP_area=="MPinputs/" +@.MPinputs@> +@d MF_area=="MFinputs/" +@.MFinputs@> +@d MP_font_area=="TeXfonts/" +@.TeXfonts@> +@z + +[748] +@x +else begin if (c=">")or(c=":") then +@y +else begin if c="/" then +@z + +[752] +@x +MP_mem_default:='MPlib:plain.mem'; +@y +MP_mem_default:='MPlib/plain.mem'; +@z + +[771] filename is needed for system editor +@x +flush_string(name); name:=cur_name; cur_name:=0 +@y +do_nothing +@z + +[1298] +@x +@p begin @!{|start_here|} +@y +@d gpc_halt == h@&a@&l@&t + +@p begin @!{|start_here|} +@z + +[1298] load the mem file before printing the banner line +@x +start_of_MP: @<Initialize the output routines@>; +@y +start_of_MP: @<Preload the default mem file@>; +@<Initialize the output routines@>; +@z + +[1298] start editor and pass history +@x +final_end: ready_already:=0; +@y +final_end: +if edit_file_name > 0 then start_editor; {user typed `\.{E}'} +gpc_halt(history); + {pass |history| as the exit value to the system} +@z + +[1299] print last end-of-line marker if needed +@x +if log_opened then + begin wlog_cr; + a_close(log_file); selector:=selector-2; + if selector=term_only then + begin print_nl("Transcript written on "); +@.Transcript written...@> + print(log_name); print_char("."); + end; + end; +end; +@y +if log_opened then + begin if file_offset > 0 then wlog_cr; + a_close(log_file); selector:=selector-2; + if selector=term_only then + begin print_nl("Transcript written on "); +@.Transcript written...@> + print(log_name); print_char("."); + end; + end; + if term_offset > 0 then wterm_cr; +end; +@z + +[1307] return if eof +@x + read(term_in,m); +@y + if eof(term_in) then return; + {don't try to read past end of file} + read(term_in,m); +@z + +[1307] return if eof +@x + else begin read(term_in,n); +@y + else begin if eof(term_in) then return; + {don't try to read past end of file} + read(term_in,n); +@z + +[1308] return eof +@x +13: begin read(term_in,l); print_cmd_mod(n,l); +@y +13: begin if eof(term_in) then return; + {don't try to read past end of file} +read(term_in,l); print_cmd_mod(n,l); +@z + +[1309 and modules added for METAPOST-GPC] +@x +itself will get a new section number. +@^system dependencies@> +@y +itself will get a new section number. +@^system dependencies@> + +@ Try to preload the default mem file. This is called even before +the first line is read from the terminal, and thus turns \.{VIRMP} +into \.{MP}, at least as seen by the user. + +\indent\.{INIMP} sets |mem_ident| to `\.{INIMP}' and won't load a mem +file here. + +@<Preload the default mem file@> = +if mem_ident = 0 then + begin pack_buffered_name(mem_default_length - mem_ext_length, 1, 0); + if not w_open_in(mem_file) then + begin + wterm_ln('I can''t find the mem file'); + goto final_end + end; + if not load_mem_file then + begin w_close(mem_file); goto final_end + end; + w_close(mem_file); + end + +@ +@d gpc_execute == e@&x@&e@&c@&u@&t@&e +@d gpc_write_str == w@&r@&i@&t@&e@&s@&t@&r + +@<Error hand...@>= +procedure start_editor; +var i: integer; {index into |name_of_file|} + j: pool_pointer; {index into |str_pool|} + cmd_line: gpc_string(200); {area to build the command line} +begin i := 1; j := str_start[edit_file_name]; +while j<str_stop(edit_file_name) do + begin name_of_file[i] := xchr[str_pool[j]]; incr(i); incr(j) + end; +while i<=file_name_size do begin name_of_file[i] := ' '; incr(i) end; +gpc_write_str(cmd_line, 'vi +', edit_line, ' ', gpc_trim(name_of_file)); +if 0 <> gpc_execute(cmd_line) then + write_ln(gpc_param_str(0), ': could not start editor with: "', + cmd_line, '"'); +end; + +@ +@d gpc_t_signal_handler == t@&s@&i@&g@&n@&a@&l@&h@&a@&n@&d@&l@&e@&r +@d gpc_install_signal_handler == + i@&n@&s@&t@&a@&l@&l@&s@&i@&g@&n@&a@&l@&h@&a@&n@&d@&l@&e@&r +@d gpc_sig_int == s@&i@&g@&i@&n@&t +@d gpc_integer == integer {for later versions of GPC (3.4+) replace + \\{integer} by \\{cinteger}} + +@<Error hand...@>= +procedure set_interrupt(signal: gpc_integer); +begin interrupt := 1 @+end; + +@ +@<Set initial values ... @>= +gpc_install_signal_handler(gpc_sig_int,set_interrupt,true,true,dummy_handler, + dummy_boolean); + +@ Here are two variables that are needed to install |set_interrupt|. +@<Local variables for initialization@> = +dummy_handler: gpc_t_signal_handler; +dummy_boolean: boolean; +@z diff --git a/systems/unix/tex-gpc/mp/mptotex.c b/systems/unix/tex-gpc/mp/mptotex.c new file mode 100644 index 0000000000..9defdf2f9e --- /dev/null +++ b/systems/unix/tex-gpc/mp/mptotex.c @@ -0,0 +1,224 @@ +/**************************************************************** +Copyright 1990 - 1995 by AT&T Bell Laboratories. + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T Bell Laboratories or +any of its entities not be used in advertising or publicity +pertaining to distribution of the software without specific, +written prior permission. + +AT&T disclaims all warranties with regard to this software, +including all implied warranties of merchantability and fitness. +In no event shall AT&T be liable for any special, indirect or +consequential damages or any damages whatsoever resulting from +loss of use, data or profits, whether in an action of contract, +negligence or other tortious action, arising out of or in +connection with the use or performance of this software. +****************************************************************/ + +/* This program transforms a MetaPost input file into a TeX or LaTeX input + * file by stripping out btex...etex and verbatimtex...etex sections. + * Leading and trailing spaces and tabs are removed from the extracted + * material and it is surrounded by the preceeding and following strings + * defined immediately below. The input file should be given as argument 1 + * and the resulting TeX file is written on standard output. + */ + +#include <stdio.h> +#define bufsize 1000 + +char* predoc = ""; +char* postdoc = "\\end{document}\n"; +char* pretex1 = "\\shipout\\hbox{\\smash{\\hbox{\\hbox{%% line %d %s\n"; +char* pretex = "\\shipout\\hbox{\\smash{\\hbox{\\hbox{%% line %d %s\n"; +char* posttex = "}\\vrule width1sp}}}\n"; +char* preverb = "%% line %d %s\n"; +char* postverb = "%\n"; + +char *mpname; +FILE *mpfile; +int lnno = 0; /* current line number */ +int texcnt = 0; /* btex..etex blocks so far */ +char buf[bufsize]; /* the input line */ +char *bb, *tt, *aa; /* start of before, token, and after strings */ + +void usage(nam) + char *nam; +{ + fprintf(stderr, "Usage: %s <mp-file>\n", nam); + exit(1); +} + +void err(msg) + char *msg; +{ + fprintf(stderr, "! Error in %s at line %d: %s\n", mpname, lnno, msg); + exit(1); +} + +char *getline() /* returns NULL on EOF or error, otherwise buf */ +{ + char *s; + + if (fgets(buf, bufsize, mpfile)==NULL) + return NULL; + lnno++; + for (s= &buf[1]; *s!='\0'; s++) /* do nothing */; + if (s==&buf[bufsize-1] && s[-1]!='\n') err("Line is too long"); + s[-1] = '\0'; + return buf; +} + + +/* Return nonzero if a prefix of string s matches the null-terminated string t + * and the next character is not a letter of an underscore. + */ +int match_str(s, t) + char *s, *t; +{ + while (*t!=0) { + if (*s!=*t) return 0; + s++; t++; + } + switch (*s) { + case 'a': case 'c': case 'd': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'w': case 'x': case 'y': case 'z': case '_': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': case 'b': case 'e': case 'v': + return 0; + default: + return 1; + } +} + + +/* This function tries to express s as the concatination of three strings + * b, t, a, with the global pointers bb, tt, and aa set to the start of the + * corresponding strings. String t is either a quote mark, a percent sign, + * or an alphabetic token "btex", "etex", or "verbatimtex". (An alphabetic + * token is a maximal sequence of letters and underscores.) If there are + * several possible substrings t, we choose the leftmost one. If there is + * no such t, we set b=s and return 0. + */ +int getbta(s) + char *s; +{ + int ok=1; /* zero if last character was a-z, A-Z, or _ */ + + bb = s; + for (tt=bb; *tt!=0; tt++) + switch (*tt) { + case '"': case '%': + aa = tt+1; + return 1; + case 'b': + if (ok && match_str(tt,"btex")) { + aa = tt+4; + return 1; + } else ok=0; + break; + case 'e': + if (ok && match_str(tt,"etex")) { + aa = tt+4; + return 1; + } else ok=0; + break; + case 'v': + if (ok && match_str(tt,"verbatimtex")) { + aa = tt+11; + return 1; + } else ok=0; + break; + case 'a': case 'c': case 'd': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'w': case 'x': case 'y': case 'z': case '_': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + ok = 0; + break; + default: + ok = 1; + } + aa = tt; + return 0; +} + + +void copytex() +{ + char *s; /* where a string to print stops */ + char c; + int ignore = 1; + + do { if (*aa==0) + if ((aa=getline())==NULL) + err("btex section does not end"); + else if (--ignore<0) printf("\n"); + if (getbta(aa) && *tt=='e') { + s = tt-1; + while (s>=bb && (*s==' ' || *s=='\t')) + s--; + s++; + } else { + if (*tt=='b') err("btex in TeX mode"); + if (*tt=='v') err("verbatimtex in TeX mode"); + s = aa; + } + c = *s; + *s = 0; + printf("%s", bb); + *s = c; + } while (*tt!='e'); +} + + +void do_line() +{ + aa = buf; + while (getbta(aa)) + if (*tt=='%') break; + else if (*tt=='"') { + do if (!getbta(aa)) err("string does not end"); + while (*tt!='"'); + } else if (*tt=='b') { + if (texcnt++ ==0) printf(pretex1,lnno,mpname); + else printf(pretex,lnno,mpname); + while (*aa==' ' || *aa=='\t') aa++; + copytex(); + printf("%s",posttex); + } else if (*tt=='v') { + printf(preverb,lnno,mpname); + while (*aa==' ' || *aa=='\t') aa++; + copytex(); + printf("%s",postverb); + } else err("unmatched etex"); +} + + + +void main(argc, argv) + char *argv[]; +{ + if (argc!=2) usage(argv[0]); + mpname = argv[1]; + mpfile = fopen(mpname, "r"); + if (mpname==NULL) usage(argv[0]); + printf("%s",predoc); + while (getline()!=NULL) + do_line(); + printf("%s",postdoc); + exit(0); +} diff --git a/systems/unix/tex-gpc/mp/mpx b/systems/unix/tex-gpc/mp/mpx new file mode 100644 index 0000000000..866bad0600 --- /dev/null +++ b/systems/unix/tex-gpc/mp/mpx @@ -0,0 +1,8 @@ +# process .mp files that include TeX programs. +case $# in +1) f=`basename $1 .mp`;; +*) echo Usage: $0 mp-file; exit 1;; +esac +mptotex $f.mp \ +| tex && dvitomp texput.dvi $f.mpx && mp $f.mp \ +|| echo $0 failed!; exit 1 |