% *** 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 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)\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 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) { ¬_OK('','',"stop-list file does not exist: $Stoplist_file\n"); } else { open(STOPF,"<$Stoplist_file") || die "Can't open file: $Stoplist_file\n"; while () { 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 () { 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 () { 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 &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 : ''; ¬_OK("","","xref hint(s) unknown: $Lang_xref\n") if $Lang_xref && &hints_not_OK( $XREF_HINTS, $Lang_xref ); ¬_OK("","","pagebreak hint(s) unknown: $Lang_pagebreak\n") if $Lang_pagebreak && &hints_not_OK( $PAGEBREAK_HINTS, $Lang_pagebreak ); ¬_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}