summaryrefslogtreecommitdiff
path: root/web/glasgow/lit2x-0.16/literate/lit2stuff.lprl
diff options
context:
space:
mode:
Diffstat (limited to 'web/glasgow/lit2x-0.16/literate/lit2stuff.lprl')
-rw-r--r--web/glasgow/lit2x-0.16/literate/lit2stuff.lprl775
1 files changed, 775 insertions, 0 deletions
diff --git a/web/glasgow/lit2x-0.16/literate/lit2stuff.lprl b/web/glasgow/lit2x-0.16/literate/lit2stuff.lprl
new file mode 100644
index 0000000000..cacb4422fe
--- /dev/null
+++ b/web/glasgow/lit2x-0.16/literate/lit2stuff.lprl
@@ -0,0 +1,775 @@
+% *** MSUB does some substitutions here ***
+% *** grep for $( ***
+%
+\begin{onlystandalone}
+\documentstyle[11pt,literate]{article}
+\begin{document}
+\title{Source for the Glasgow literate programming system}
+\author{(A sheepish) Will Partain}
+\maketitle
+\begin{rawlatex}
+\tableofcontents
+\end{rawlatex}
+\end{onlystandalone}
+
+\section[Source_Introduction]{Source: introduction and overall structure}
+
+This \tr{perl} script is a driver that converts literate scripts into other
+useful forms. Because the various tasks
+\tr{lit2pgm},\index{lit2pgm} \tr{lit2latex},\index{lit2latex}
+etc., are so similar, there's just one script (which I call
+\tr{lit2stuff}),\index{lit2stuff} with some parts conditionally
+included/executed, depending on how
+the script was invoked (exactly one of the variables @$Lit2pgm@,
+@$Lit2latex@, and @$Lit2texi@ will be @1@, the others @0@).
+
+\tr{lit2stuff} is written in \tr{perl}, so some tasks are not as
+conveniently expressed as one might wish. For example, \tr{perl} is
+line-oriented so, for example, chasing down the contents of a multi-line
+\tr{\title{...}} is, in the general case, unpleasant.
+\tr{lit2stuff} uses helper programs to cope with such things. You'll
+see 'em along the way.
+
+\section[Naming_and_background]{Naming conventions, perl hackery, etc.}
+
+[How I use names, and so on.]
+
+\section[Global_data_structures]{Global data structures}
+\downsection
+\input{lit-globals.lprl}
+\input{lit-link-globals.lprl}
+\upsection
+
+\section[Lit_initialization]{Initialization and command-line argument checking}
+
+First, the program must have been invoked with an approved name:
+\begin{code}
+($Pgm = $0) =~ s/.*\/([^\/]+)$/\1/;
+$LIT_VERSION = '0.16';
+
+# an initial -A<name> option overrides the name
+if ($#ARGV >= 0 && $ARGV[0] =~ /^-A(lit2)(pgm|texi|latex)$/) {
+ $Pgm = $1.$2;
+ shift(@ARGV);
+}
+$Lit2pgm = ($Pgm eq 'lit2pgm') ? 1 : 0;
+$Lit2latex = ($Pgm eq 'lit2latex') ? 1 : 0;
+$Lit2texi = ($Pgm eq 'lit2texi') ? 1 : 0;
+$Lit2depend = ($Pgm eq 'mkdependlit') ? 1 : 0;
+$Lit2changelog = ($Pgm eq 'lit2changelog') ? 1 : 0;
+$Lit2text = ($Pgm eq 'lit2text') ? 1 : 0;
+die "$Pgm: must be invoked as lit2pgm, lit2texi, lit2latex, mkdependlit, lit2changelog, or lit2text (or use -A<name>)\n"
+ if (!($Lit2pgm || $Lit2latex || $Lit2texi || $Lit2depend || $Lit2changelog || $Lit2text));
+
+# $Lit2what will be set after we know $Quick_lit2pgm
+
+$Status = 0; # just used for exit() status
+\end{code}
+
+Unravel the command-line options with one of the perl-library @getopt@
+routines, then transfer that information to more pleasantly-named
+global variables (see the User Guide
+\standaloneornot{}{[Section~\ref{Literate_guide}]}
+for what passes as good command-line arguments):
+
+\begin{code}
+# really only needed if perl is misinstalled. (and can't find getopts.pl)
+if ( $(INSTALLING) ) {
+ unshift(@INC, '$(INSTDATADIR_LITERATE)');
+} else {
+ unshift(@INC, '$(TOP_PWD)/$(CURRENT_DIR)'); # absolutize the paths
+}
+
+do 'getopts.pl' || die "Giant error 'do'ing getopts.pl: $@";
+
+$Usage = "usage: $Pgm ".
+ '[-i input-file] '.
+ '[-I LITINPUTS-path-additions] '.
+ '[-o output-file] ';
+$Usage .= '[-cdnqv] '.
+ '[-r ribbons] '.
+ "[input-file]\n" if $Lit2pgm;
+$Usage .= '[-cdLnOSv] '.
+ '[-f nodename-suffix] '.
+ '[-N infofilename] '.
+ '[-[lx] language] '.
+ '[-s stop-list-file] '.
+ "[input-file]\n" if $Lit2texi;
+$Usage .= '[-cdDnOSv] '.
+ '[-g node-name] '.
+ '[-[lptx] language] '.
+ '[-s stop-list-file] '.
+ "[input-file]\n" if $Lit2latex;
+$Usage .= '[-dv] '.
+ "[input-file]\n" if $Lit2depend;
+$Usage .= '[-dnv] '.
+ "[input-file]\n" if $Lit2changelog;
+$Usage .= '[-dnv] '.
+ "[input-file]\n" if $Lit2text;
+
+if ( ($Lit2pgm && ! &Getopts('cdH:I:i:no:qr:v'))
+ || ($Lit2texi && ! &Getopts('cdf:H:I:i:Ll:nN:Oo:Ss:vx:'))
+ || ($Lit2latex && ! &Getopts('cdDg:H:I:i:l:no:Op:Ss:t:vx:'))
+ || ($Lit2depend && ! &Getopts('dH:I:i:o:v'))
+ || ($Lit2text && ! &Getopts('dH:I:i:no:v'))
+ || ($Lit2changelog && ! &Getopts('dH:I:i:no:v'))) {
+ print STDERR $Usage;
+ exit 1;
+} elsif ($#ARGV > 0) {
+ print STDERR "$Pgm: cannot have more than one input file: @ARGV \n";
+ print STDERR $Usage;
+ exit 1;
+}
+# SHARED OPTIONS
+$Debugging = ($opt_d) ? 1 : 0;
+$Verbose = ($Debugging | $opt_v) ? 1 : 0;
+print STDERR "Glasgow literate programming system, version $LIT_VERSION\n" if $Verbose;
+$Input_file = ($opt_i) ? $opt_i : '';
+# -o <output file> handled after deciding if linking
+
+$Litinputs = '.';
+$Litinputs_adds = ($opt_I) ? $opt_I : '';
+$Litinputs = "$Litinputs_adds:$Litinputs" if $Litinputs && $Litinputs_adds;
+
+# where all the assisting code is found (HARDWIRED)
+if ($opt_H) {
+ # no error checking; you get what you deserve
+ ($LIB_ARCH_DIR,$LIB_DIR) = split(/:/,$opt_H);
+} elsif ( $(INSTALLING) ) {
+ $LIB_ARCH_DIR = '$(INSTLIBDIR_LITERATE)';
+ $LIB_DIR = '$(INSTDATADIR_LITERATE)';
+} else {
+ $LIB_ARCH_DIR = '$(TOP_PWD)/$(CURRENT_DIR)'; # absolutize the paths
+ $LIB_DIR = '$(TOP_PWD)/$(CURRENT_DIR)';
+}
+unshift(@INC, $LIB_DIR); # adding to; for .prl libraries sucked in at runtime
+#
+# now the (derived) names of all the helpers
+$Lit_inputter = "$LIB_ARCH_DIR/lit-inputter";
+$Lit_deatify = "$LIB_ARCH_DIR/lit-deatify";
+$Lit_verb2latex = "$LIB_ARCH_DIR/lit-verb2latex";
+
+# this should be done a better way...
+$Tgrind_pgm = '$(TGRIND_HELPER)';
+
+# finish knowing myself; must agree with lit-deatify.llex
+$Quick_lit2pgm = ($opt_q) ? 1 : 0;
+$Lit2what = 1 if $Quick_lit2pgm;
+$Lit2what = 2 if $Lit2pgm && ! $Quick_lit2pgm;
+$Lit2what = 3 if $Lit2texi;
+$Lit2what = 4 if $Lit2latex;
+$Lit2what = 5 if $Lit2depend;
+$Lit2what = 6 if $Lit2changelog;
+$Lit2what = 7 if $Lit2text;
+
+# LESS SHARED OPTIONS
+$Codedef_blurbs = ($opt_D) ? 1 : 0;
+$Grab_node = ($opt_g) ? $opt_g : 'Top';
+$Infofilename = ($opt_N) ? $opt_N : ''; # see do_setfilename
+$Follow_inputs = ($opt_n) ? 1 : 0;
+$Show_node_owner= ($opt_O) ? 1 : 0;
+$Nodename_suffix= ($opt_f) ? $opt_f : '';
+$Opt_node_links = ($opt_L) ? 1 : 0;
+$Standalone_doc = ($opt_S) ? 1 : 0;
+
+$Stoplist_file = ($opt_s) ? $opt_s : '';
+# for now, stop lists are simply words to be ignored
+if ($Stoplist_file) {
+ if ( ! -f $Stoplist_file) {
+ &not_OK('','',"stop-list file does not exist: $Stoplist_file\n");
+ } else {
+ open(STOPF,"<$Stoplist_file") || die "Can't open file: $Stoplist_file\n";
+ while (<STOPF>) {
+ chop;
+ $IGNORE_WD{$_} = 1; # no questions asked...
+ }
+ close(STOPF);
+ }
+}
+
+$Ribbons_to_get = ($opt_r) ? $opt_r : 'main';
+$Ribbons_to_get =~ s/\s*,\s*/,/g; # remove spaces around commas
+
+# figure out what we're doing and the input and output files...
+if ( ! $Input_file ) {
+ if ($#ARGV == 0) {
+ $Input_file = $ARGV[0];
+ } else {
+ $Input_file = '-'; # stdin; hmm...
+ }
+}
+
+($Inputfile_root,$Inputfile_suff) = &root_and_suffix($Input_file);
+@Files_to_tidy = ();
+
+# are we "processing" and/or "linking" ?
+if ( ! ($Lit2texi || $Lit2latex)) { # that's easy...
+ $Processing = 1;
+ $Linking = 0;
+} else {
+ $Processing = 1 if $Inputfile_suff !~ /^(itxi|itex|texi|tex)$/;
+ $Linking = ($opt_c) ? 0 : 1;
+}
+
+# table of input-suffixes -> output-suffixes (for "processing");
+# cf. tables in &check_language_stuff
+$ISUFF2OSUFF{'lit'} = '';
+$ISUFF2OSUFF{'lhs'} = 'hs';
+$ISUFF2OSUFF{'lit.hs'} = 'hs';
+$ISUFF2OSUFF{'lprl'} = 'prl';
+$ISUFF2OSUFF{'llex'} = 'lex';
+$ISUFF2OSUFF{'lhc'} = 'hc';
+$ISUFF2OSUFF{'lc'} = 'c';
+$ISUFF2OSUFF{'lh'} = 'h';
+$ISUFF2OSUFF{'ltex'} = 'tex';
+$ISUFF2OSUFF{'lit.tex'} = 'tex';
+$ISUFF2OSUFF{'ljm'} = 'jm'; # mkworld-ery
+$ISUFF2OSUFF{'lf'} = 'f'; # Literate Fortran (adriaan@dcs.qmw.ac.uk)
+
+# guess the output filenames (for "processing" and "linking")
+if ( $opt_o ) {
+ @Files_to_tidy = ( $opt_o );
+ if ( $Linking ) {
+ $Link_outfile = $opt_o;
+ } else {
+ $Proc_outfile = $opt_o;
+ }
+}
+if ( !defined($Proc_outfile) ) {
+ if ($Linking) { # got to put it _somewhere_
+ $Proc_outfile = "$(TMPDIR)/lit2stuff-po.$$";
+
+ } elsif ($Lit2pgm) { # try to be clever
+ if (defined($ISUFF2OSUFF{$Inputfile_suff})) {
+ $Proc_outfile = $Inputfile_root;
+ $Proc_outfile .= '.'.$ISUFF2OSUFF{$Inputfile_suff}
+ if $ISUFF2OSUFF{$Inputfile_suff};
+ } else {
+ print STDERR "$Pgm: don't know the file suffix: $Inputfile_suff\n";
+ $Proc_outfile = '-'; # stdout will do
+ }
+
+ } elsif ($Lit2texi) {
+ $Proc_outfile = $Inputfile_root . '.itxi';
+
+ } elsif ($Lit2latex) {
+ $Proc_outfile = $Inputfile_root . '.itex';
+
+ } else {
+ $Proc_outfile = '-'; # stdout
+ }
+ @Files_to_tidy = ( $Proc_outfile ) if $Proc_outfile ne '-';
+}
+# messing with Link_outfile deferred to later...
+
+&check_language_stuff();
+exit $Status if $Status; # don't proceed if errors
+
+# here we go: set up signal handler
+sub quit_upon_signal {
+ # delete any files to tidy
+ print STDERR "deleting... @Files_to_tidy\n" if $Verbose && $#Files_to_tidy >= 0;
+ unlink @Files_to_tidy if $#Files_to_tidy >= 0;
+ exit 1;
+}
+$SIG{'INT'} = 'quit_upon_signal';
+$SIG{'QUIT'} = 'quit_upon_signal';
+
+print STDERR "Language info: code=$Code_lang, xref=$Lang_xref, ",
+ "typeset=$Lang_typeset, pagebreak=$Lang_pagebreak\n"
+ if $Verbose;
+
+# now we know the program, the options, and the language info, we load
+# the other (non-language-related) pieces of perl code (roll-your-own
+# dynamic linking...)
+if ( ! $Quick_lit2pgm) {
+ do 'lit-globals.prl' || die "Giant error 'do'ing lit-globals.prl: $@";
+ do 'lit-reader.prl' || die "Giant error 'do'ing lit-reader.prl: $@";
+}
+if ($Lit2pgm) {
+ if (! $Quick_lit2pgm) { # i.e., the slow one
+ do 'lit-2pgm.prl' || die "Giant error 'do'ing lit-2pgm.prl: $@";
+ }
+ # we _always_ need something for line directives
+ do "lit-2pgm-$Code_lang.prl"
+ || die "Giant error 'do'ing lit-2pgm-$Code_lang.prl: $@";
+
+} elsif ($Lit2depend) {
+ do 'lit-2depend.prl' || die "Giant error 'do'ing lit-2depend.prl: $@";
+
+} elsif ($Lit2changelog) {
+ do 'lit-2changes.prl' || die "Giant error 'do'ing lit-2changes.prl: $@";
+
+} elsif ($Lit2text) {
+ do 'lit-2text.prl' || die "Giant error 'do'ing lit-2text.prl: $@";
+
+} else {
+ # creating a document...
+ do 'lit-2doc.prl' || die "Giant error 'do'ing lit-2doc.prl: $@";
+ # language-specific stuff (most of it)
+ do "lit-2doc-$Code_lang.prl"
+ || die "Giant error 'do'ing lit-2doc-$Code_lang.prl: $@";
+ if ( $Lit2texi ) {
+ do 'lit-2texi.prl' || die "Giant error 'do'ing lit-2texi.prl: $@";
+ if ($Processing) {
+ do "lit-2texi-$Code_lang.prl"
+ || die "Giant error 'do'ing lit-2texi-$Code_lang.prl: $@";
+ # non-Code_lang xref/typeset/pagebreak code would be slurped here
+ # [not implemented]
+ }
+ }
+ if ( $Lit2latex ) {
+ do 'lit-2latex.prl' || die "Giant error 'do'ing lit-2latex.prl: $@";
+ if ($Processing) {
+ do "lit-2latex-$Code_lang.prl"
+ || die "Giant error 'do'ing lit-2latex-$Code_lang.prl: $@";
+ # non-Code_lang xref/typeset/pagebreak code would be slurped here
+ # [not implemented]
+ }
+ }
+ if ( $Linking ) {
+ do 'lit-link-globals.prl' || die "Giant error 'do'ing lit-link-globals.prl: $@";
+ do 'lit-linker.prl' || die "Giant error 'do'ing lit-linker.prl: $@";
+ }
+}
+
+# NOW WE START DRIVING...
+
+# first: we handle "quick" lit2pgm
+if ($Quick_lit2pgm) {
+
+ # check that no incompatible lit2pgm options were used
+ die "Can only get ribbon 'main' with lit2pgm -q option\n"
+ if ($Ribbons_to_get ne 'main');
+ die "Can't follow \\input{}s with lit2pgm -q option\n"
+ if ($Follow_inputs);
+
+ $Input_file = '' if $Input_file eq '-';
+ $pipe_string = "(echo \"srcfile!_!$Input_file!_!1!_!\" ; expand $Input_file) | " .
+ "$Lit_deatify $Verbose 0 $Lit2what -";
+ print STDERR "QUICK LIT2PGM:in=$pipe_string\n" if $Verbose;
+ print STDERR " out=$Proc_outfile\n" if $Verbose;
+ &do_std_opens($pipe_string,$Proc_outfile);
+
+ # this "quick" loop does as little as possible
+ while (<INPIPE>) {
+ if ( /^srcfile!_!(.*)!_!(.*)!_!/) {
+ print &mk_line_directive($1,$2);
+ } else {
+ print $_ ;
+ }
+ }
+ &do_std_closes();
+ exit $Status;
+}
+
+# second: we handle lit2depend
+if ($Lit2depend) {
+ $Follow_inputs = 1; # that's the whole point
+ # just using lit-inputter to follow \input's
+
+ $pipe_string = "$Lit_inputter $Verbose $Follow_inputs $Litinputs $Input_file";
+ print STDERR "MKDEPENDLIT:in=$pipe_string\n" if $Verbose;
+ print STDERR " out=$Proc_outfile\n" if $Verbose;
+ &do_std_opens($pipe_string,$Proc_outfile);
+
+ # lineno 1 means we just started the file
+ # look for these and deduce dependency info (a hack)
+ @Depend_lines = ();
+ while (<INPIPE>) {
+ if ( /^srcfile!_!(.*)!_!1!_!/) {
+ &collect_dependencies($1);
+ }
+ }
+ &do_std_closes();
+ &mangle_Makefile();
+ exit $Status;
+}
+
+# all other invocations of "processing" (slow lit2pgm, lit2latex,
+# lit2texi, lit2changelog) need the input "parsed" and stuffed into
+# the global data structures, so we do that now.
+
+if ($Processing) {
+ # (would really like to get \input'ing over to deatify...)
+
+ $pipe_string = "$Lit_inputter $Verbose $Follow_inputs $Litinputs $Input_file | ".
+ "expand | ".
+ "$Lit_deatify $Verbose 0 $Lit2what -";
+ # lit-deatify last so we get its error report
+ print STDERR "PARSING:in=$pipe_string\n" if $Verbose;
+ print STDERR " out=$Proc_outfile\n" if $Verbose;
+
+ &do_std_opens($pipe_string,$Proc_outfile);
+
+ &read_and_categorize_input(); # reads <INPIPE>
+ &fiddle_line_numbers() if ! $Lit2pgm;
+
+ if ($Lit2texi || $Lit2latex) { # want this before dumping...
+ &find_interesting_codethings();
+ }
+
+ if ($Debugging) {
+ print STDERR "AFTER \"PARSING\" :-\n";
+ &dump_sections_and_blocks();
+ }
+}
+
+# continue with various kinds of "processing" ...
+
+if ($Lit2pgm) {
+ print STDERR "LIT2PGM:out=$Proc_outfile\n" if $Verbose;
+ &spit_out_ribbons_code(split(/,/, $Ribbons_to_get));
+ &do_std_closes();
+ exit $Status;
+}
+
+if ($Lit2changelog) {
+ print STDERR "LIT2CHANGELOG:out=$Proc_outfile\n" if $Verbose;
+ &spit_out_change_info();
+ &do_std_closes();
+ exit $Status;
+}
+
+if ($Lit2text) {
+ print STDERR "LIT2TEXT:out=$Proc_outfile\n" if $Verbose;
+ &spit_out_raw_text();
+ &do_std_closes();
+ exit $Status;
+}
+
+if ($Processing) {
+ # now either lit2latex or lit2texi...
+ print STDERR "LIT2DOC:out=$Proc_outfile\n" if $Verbose;
+
+ &do_text_substitutions(); # \defines
+
+ &print_intermed_document();
+
+ &do_std_closes();
+}
+
+## (I'd rather keep going... )
+## close up and unlink temp outfile file if we are about to die
+#unlink("$(TMPDIR)/lit2stuff-po.$$") if $Status;
+#exit $Status if $Status || ! $Linking;
+exit $Status if ! $Linking;
+
+# NOW WE'RE TO "linking" ... (lit2texi and lit2latex only)
+
+# make sure we know where to put the output (_before_ redefining Input_file)
+if ( !defined($Link_outfile) ) {
+ $Link_outfile = $Inputfile_root . '.texi' if $Lit2texi;
+ $Link_outfile = $Inputfile_root . '.tex' if $Lit2latex;
+ @Files_to_tidy = ( $Link_outfile );
+}
+# readjust notions of "input" file if just processed
+if ( $Processing ) {
+ $Input_file = $Proc_outfile;
+}
+
+# $Input_file is the root of a bunch of i{tex,texi} files to be glued
+# together; the sectioning needs to be fixed and unresolved node refs
+# need to be fixed.
+# each file has a table of relevant info at the beginning
+# 1st pass: go \inputting down through them, reading those tables
+# 2nd pass: go \inputting down through them, fixing things and writing
+
+&first_link_pass(); # GO!!!
+
+if ($Debugging) {
+ print STDERR "AFTER LINKER FIRST PASS :-\n";
+ &dump_sections_and_blocks();
+}
+
+# # (I'd rather keep going)
+# # unlink temp outfile file if we are about to die
+# unlink("$(TMPDIR)/lit2stuff-po.$$") if $Status;
+# exit $Status if $Status;
+
+&second_link_pass();
+
+# unlink temp outfile no matter what
+unlink("$(TMPDIR)/lit2stuff-po.$$");
+exit $Status;
+\end{code}
+
+\begin{code}
+sub check_language_stuff {
+
+ # fixed tables of "language"-related info
+
+ $ISUFF2LANG{'lit'} = 'none';
+ $ISUFF2LANG{'lhc'} = 'c';
+ $ISUFF2LANG{'lc'} = 'c';
+ $ISUFF2LANG{'lh'} = 'c';
+ $ISUFF2LANG{'lhs'} = 'hs';
+ $ISUFF2LANG{'lit.hs'}='hs';
+ $ISUFF2LANG{'lprl'} = 'prl';
+ $ISUFF2LANG{'llex'} = 'lex';
+ $ISUFF2LANG{'ljm'} = 'jm'; # mkworld-ery
+ $ISUFF2LANG{'lf'} = 'f'; # Literate Fortran (adriaan@dcs.qmw.ac.uk)
+
+ $STD_LANGS = 'none,c,hs,prl,lex,jm,f'; # fully supported (?)
+
+ $XREF_HINTS = 'noindex'; # could have more...
+ $PAGEBREAK_HINTS = '';
+ $TYPESET_HINTS = 'tgrind,ruled,unruled,bird,nobird';
+
+ $Code_lang =
+ ($opt_l) ? $opt_l
+ : (defined($ISUFF2LANG{$Inputfile_suff})) ? $ISUFF2LANG{$Inputfile_suff}
+ : 'none';
+ $Lang_pagebreak = ($opt_p) ? $opt_p : '';
+ $Lang_typeset = ($opt_t) ? $opt_t : '';
+ $Lang_xref = ($opt_x) ? $opt_x : '';
+
+ &not_OK("","","xref hint(s) unknown: $Lang_xref\n")
+ if $Lang_xref && &hints_not_OK( $XREF_HINTS, $Lang_xref );
+ &not_OK("","","pagebreak hint(s) unknown: $Lang_pagebreak\n")
+ if $Lang_pagebreak && &hints_not_OK( $PAGEBREAK_HINTS, $Lang_pagebreak );
+ &not_OK("","","typeset hint(s) unknown: $Lang_typeset\n")
+ if $Lang_typeset && &hints_not_OK( $TYPESET_HINTS, $Lang_typeset );
+}
+\end{code}
+
+\section[Misc_routines]{Miscellaneous subroutines}
+
+\begin{code}
+sub do_std_opens { # opens INPIPE, and OUTF; selects the latter
+
+ local($pipe_string,$output_file) = @_;
+
+ # check it output is to a pipe
+ $output_file = ">$output_file" if $output_file !~ /^\|/;
+
+ open(INPIPE, "$pipe_string |")
+ || die "$Pgm: can't start prefilter pipe: $pipe_string\n";
+ open(OUTF, "$output_file")
+ || die "$Pgm: can't open output file: $output_file\n";
+ select(OUTF);
+}
+
+sub do_std_closes { # closes INPIPE and OUTF; re-selects STDOUT
+
+ close(INPIPE);
+ # most regrettably, this only tells if the _last_ thing
+ # in the pipeline croaked...
+ if ($? >> 8) {
+ print STDERR "$Pgm: error(s) from prefilter pipe\n";
+ unlink("$(TMPDIR)/lit2stuff-po.$$"); # this might exist...
+ if ($#Files_to_tidy >= 0) {
+ print STDERR "rm -f @Files_to_tidy\n" if $Verbose;
+ unlink ( @Files_to_tidy );
+ }
+ exit 1;
+ }
+ close(OUTF);
+ if ($? >> 8) {
+ print STDERR "$Pgm: error in closing output file: $?\n";
+ unlink("$(TMPDIR)/lit2stuff-po.$$"); # this might exist...
+ exit 1;
+ }
+ select(STDOUT);
+}
+
+sub not_OK { # report error, increment $Status, but keep going
+ local($srcfilename, $srclineno, $msg) = @_;
+ if ($srcfilename) { # not always there
+ print STDERR "$srcfilename:$srclineno: $msg";
+ } else {
+ print STDERR "$Pgm: $msg";
+ }
+ $Status++;
+}
+
+sub hints_not_OK { # return 1 or '' depending on if all hints are in valid list or not
+ local($valid_hints,$given_hints) = @_;
+ local($h);
+
+ foreach $h (split(/,/,$given_hints)) {
+ return(1) if index($valid_hints,$h) < 0;
+ }
+ '';
+}
+
+sub filter_string {
+ local($filter, $string) = @_;
+
+ open(FILT, "| $filter > /tmp/lit$$") || die "Can't open in filter_string\n";
+ print FILT $string;
+ close(FILT);
+ if ($? >> 8) { # something went wrong in the pipe ???
+ print STDERR "$Pgm: error(s) in/from filter: $filter\n";
+ }
+# local($filtered_string) = `cat /tmp/lit$$`; # perl bug
+ $filtered_string = `cat /tmp/lit$$`;
+ unlink("/tmp/lit$$");
+ $filtered_string;
+}
+
+sub deatified2verb_nl { # lit-deatify put 'em in; now we take 'em out
+ local($_) = @_;
+
+ s/\001newline\003/\n/g; # _WITH_ newlines
+ s/\001lbrace\003/\{/g;
+ s/\001rbrace\003/\}/g;
+ s/\001rbracket\003/\]/g;
+
+ $_;
+}
+
+sub deatified2verb { # without newlines
+ local($_) = @_;
+
+ $_ = &deatified2verb_nl($_);
+
+ s/\n/ /g; # the difference; to SPACES
+ $_;
+}
+
+sub de_newlined {
+ local($_) = @_;
+
+ s/\n/\001newline\003/g;
+ $_;
+}
+
+sub root_and_suffix {
+ local($filename) = @_;
+ local($root,$suffix);
+
+ # find the file's "suffix" (NB: *.lit.hs has a 6-letter suffix)
+ if ($filename =~ /\.(lit\.[^\.\/]+)$/) { # cf \input handling in reader
+ $suffix = $1;
+ ($root = $filename) =~ s/\.(lit\.[^\.\/]+)$//;
+
+ } elsif ($filename =~ /\.([^\.\/]+)$/) {
+ $suffix = $1;
+ ($root = $filename) =~ s/\.([^\.\/]+)$//;
+
+ } else {
+ # should there be a warning or something here?
+ $root = '???';
+ $suffix = '???';
+ }
+ ($root, $suffix);
+}
+
+\end{code}
+
+\section[Reader_feeding]{Pre-processing programs that feed the reader}
+\downsection
+% the inputter that we hope will go away
+\input{lit-inputter.lprl}
+
+% the pre-processing filter, a lex script
+\input{lit-deatify.llex}
+\upsection
+
+\section[Reader]{The input reader and categorizer}
+\downsection
+\input{lit-reader.lprl}
+\upsection
+
+\section[Language_independent_processing]{Language-independent processing code}
+
+``Language''-specific code is described after the linker.
+
+\downsection
+\input{lit-2pgm.lprl}
+% for both lit2texi and lit2latex
+\input{lit-2doc.lprl}
+\input{lit-2texi.lprl}
+\input{lit-2latex.lprl}
+\input{lit-2depend.lprl}
+\input{lit-2changes.lprl}
+\upsection
+
+\section[Linking_code]{Language-independent code for linking}
+\downsection
+\input{lit-linker.lprl}
+\upsection
+
+\section[Language_specific_processing]{Code-language-specific processing}
+
+This code only applies for \tr{lit2texi} and \tr{lit2latex}.
+
+\downsection
+\section[Language_none]{Special stuff for language \tr{none}}
+\downsection
+\input{lit-2pgm-none.lprl}
+\input{lit-2doc-none.lprl}
+\input{lit-2texi-none.lprl}
+\input{lit-2latex-none.lprl}
+\upsection
+\upsection
+
+\downsection
+\section[Language_hs]{Special stuff for language \tr{hs} (Haskell)}
+\downsection
+\input{lit-2pgm-hs.lprl}
+\input{lit-2doc-hs.lprl}
+\input{lit-2texi-hs.lprl}
+\input{lit-2latex-hs.lprl}
+\upsection
+\upsection
+
+\downsection
+\section[Language_prl]{Special stuff for language \tr{prl} (Perl)}
+\downsection
+\input{lit-2pgm-prl.lprl}
+\input{lit-2doc-prl.lprl}
+\input{lit-2texi-prl.lprl}
+\input{lit-2latex-prl.lprl}
+\upsection
+\upsection
+
+\downsection
+\section[Language_C]{Special stuff for language \tr{c} (C)}
+\downsection
+\input{lit-2pgm-c.lprl}
+\input{lit-2doc-c.lprl}
+\input{lit-2texi-c.lprl}
+\input{lit-2latex-c.lprl}
+\upsection
+\upsection
+
+\downsection
+\section[Language_lex]{Special stuff for language \tr{lex}}
+\downsection
+\input{lit-2pgm-lex.lprl}
+\input{lit-2doc-lex.lprl}
+\input{lit-2texi-lex.lprl}
+\input{lit-2latex-lex.lprl}
+\upsection
+\upsection
+
+\downsection
+\section[Language_Fortran]{Special stuff for language \tr{f}}
+\downsection
+\input{lit-2pgm-f.lprl}
+\input{lit-2doc-f.lprl}
+\input{lit-2texi-f.lprl}
+\input{lit-2latex-f.lprl}
+\upsection
+\upsection
+
+\downsection
+\section[Language_jm]{Special stuff for language \tr{jm} (``make world'' stuff)}
+
+This type of input file is a mixture of C-pre-processor stuff and
+\tr{make} stuff.
+
+\downsection
+\input{lit-2pgm-jm.lprl}
+\input{lit-2doc-jm.lprl}
+\input{lit-2texi-jm.lprl}
+\input{lit-2latex-jm.lprl}
+\upsection
+\upsection
+
+\begin{onlystandalone}
+\printindex
+\end{document}
+\end{onlystandalone}