#! /usr/bin/perl # cexcerpt # # Extract tagged code chunks from a C source file for verbatim # inclusion in LaTeX documentation. # # Processes C source file ; extracts tagged excerpts, # and puts them in a file in directory . # # An excerpt is marked with special comments in the C file: # # /*::cexcerpt::my_example::begin::*/ # while (esl_sq_Read(sqfp, sq) == eslOK) # { n++; } # /*::cexcerpt::my_example::end::*/ # # The tag's format is "::cexcerpt::::begin::" (or end). # We match it with: # ^\s*\/\*::cexcerpt::(\S+)::begin::\*\/ # # The tag is used to construct the file name, as .tex. # In the example, the tag my_example creates a file my_example.tex # in . # # All the text between the cexcerpt tags is put in the file. # In addition, this text is wrapped in a {cchunk} environment. # So in the example above, my_example.tex will contain: # \begin{cchunk} # while (esl_sq_Read(sqfp, sq) == eslOK) # { n++; } # \end{cchunk} # # This file can then be included in a LaTeX file, with # \input{/} # # For best results, the C source should be free of TAB characters. # "M-x untabify" on the region to clean them out. # # Cexcerpts can't overlap or nest in any way in the C file; only # one can be active at any given time. # # SRE, Fri Feb 25 08:40:19 2005 # SVN $Id: cexcerpt 1531 2005-12-13 20:53:46Z eddy $ $usage = "cexcerpt "; die("Wrong number of command line arguments.\nUsage: $usage\n") unless ($#ARGV+1 == 2); $cfile = shift; $dir = shift; die("C source file $cfile doesn't exist.\n") unless -e $cfile; die("C source file $cfile isn't readable.\n") unless -r $cfile; die("Directory $dir doesn't exist.\n") unless -e $dir; die("$dir isn't a directory.\n") unless -d $dir; die("Can't write files to directory $dir.\n") unless -w $dir; open(CFILE,$cfile) || die("Couldn't open C file $cfile.\n"); $in_cexcerpt = 0; $linenumber = 1; while () { if (/^\s*\/\*::cexcerpt::(\S+)::begin::\*\//) { if ($in_cexcerpt) { die("Can't start $1 at line $linenumber; $tag started at line $startline.\n"); } if (($n = grep(/$1/, @taglist)) > 0) { die("Already saw tag $1 in this C file ($n); tags must be unique.\n"); } $tag = $1; $in_cexcerpt = 1; $startline = $linenumber; $outfile = "$dir/$tag.tex"; push(@taglist, $tag); print (" extracting $tag.tex...\n"); open(OUTFILE,">$outfile") || die("Couldn't open $outfile for writing."); print OUTFILE "\\begin{cchunk}\n"; } elsif (/^\s*\/\*::cexcerpt::(\S+)::end::\*\//) { if (!$in_cexcerpt) { die("cexcerpt $1 can't end (line $linenumber) because it never started.\n"); } if ($tag ne $1) { die("tried to end $1 at line $linenumber, but $tag is active (from line $startline).\n"); } $in_cexcerpt = 0; print OUTFILE "\\end{cchunk}\n"; close(OUTFILE); } elsif ($in_cexcerpt) { print OUTFILE $_; } $linenumber++; } close(CFILE);