diff options
author | Karl Berry <karl@freefriends.org> | 2015-09-05 22:16:03 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-09-05 22:16:03 +0000 |
commit | 458ae81ef20dbea77877876c44a0de359afd55de (patch) | |
tree | 9a307a71a169b831bd2dff1f1408638a86218e8a | |
parent | 412a3bd77bd76014472d93aa65ce8d7b75809ebb (diff) |
checklistings (3sep15)
git-svn-id: svn://tug.org/texlive/trunk@38300 c570f23f-e606-0410-a88d-b1316a301751
36 files changed, 2699 insertions, 1 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am index b12aa912f75..42a2071877f 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.am +++ b/Build/source/texk/texlive/linked_scripts/Makefile.am @@ -54,6 +54,7 @@ texmf_scriptsdir = $(datarootdir)/texmf-dist/scripts texmf_shell_scripts = \ adhocfilelist/adhocfilelist.sh \ bibexport/bibexport.sh \ + checklistings/checklistings.sh \ dtxgen/dtxgen \ installfont/installfont-tl \ latexfileversion/latexfileversion \ diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in index eb7278edb78..16b80d118f9 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.in +++ b/Build/source/texk/texlive/linked_scripts/Makefile.in @@ -269,6 +269,7 @@ texmf_scriptsdir = $(datarootdir)/texmf-dist/scripts texmf_shell_scripts = \ adhocfilelist/adhocfilelist.sh \ bibexport/bibexport.sh \ + checklistings/checklistings.sh \ dtxgen/dtxgen \ installfont/installfont-tl \ latexfileversion/latexfileversion \ diff --git a/Build/source/texk/texlive/linked_scripts/checklistings/checklistings.sh b/Build/source/texk/texlive/linked_scripts/checklistings/checklistings.sh new file mode 100755 index 00000000000..4131d9acbc4 --- /dev/null +++ b/Build/source/texk/texlive/linked_scripts/checklistings/checklistings.sh @@ -0,0 +1,446 @@ +#!/bin/sh +# +# checklistings # +# version 1.0 # +# # +# Timothy Bourke <tim@tbrk.org> # +# Inria # +# École normale supérieure # +# # +# Marc Pouzet <pouzet@ens.fr> # +# Université Pierre et Marie Curie # +# École normale supérieure # +# Inria # +# + +## +# Configuration +SCRIPT=$(basename "$0") +SUFFIX=.chkl + +RED="[0;31m" +BLUE="[0;34m" +BLACK="[0;0m" + +ADJUSTLINETEXT=line + +## +# Command-line + +usage () { + printf '%s: check source code exported from LaTeX documents.\n' "$SCRIPT" + printf 'usage: %s [options] [file ...]\n' "$SCRIPT" + printf '\n' + printf ' options:\n' + printf ' --no-colors log to terminal without control codes\n' + printf ' --no-line-adjust do not try to adjust error line numbers\n' + printf '\n' +} + +unset INFILES +while [ -n "$1" ]; do + case "$1" in + --no-colors) + unset RED BLUE BLACK + ;; + --no-line-adjust) + unset ADJUSTLINETEXT + ;; + --h) + usage + exit 0 + ;; + --help) + usage + exit 0 + ;; + -*) + printf "%s: unrecognized option '%s'\n" "$SCRIPT" "$1" + usage + exit 1 + ;; + *${SUFFIX}) + INFILES="$INFILES $1" + ;; + *) + INFILES="$INFILES $1${SUFFIX}" + ;; + esac + shift +done + +if [ -z "$INFILES" ]; then + INFILES=$(ls ./*${SUFFIX}) +fi + +## +# Allocate temporary files + +cleanup() { + rm -f "${OUTFILE}" "${ERRFILE}" +} +OUTFILE=$(mktemp -t "${SCRIPT}.out.XXXXXX") || exit 1 +ERRFILE=$(mktemp -t "${SCRIPT}.err.XXXXXX") || (cleanup; exit 1) +trap cleanup 1 2 15 + +## +# Code + +# +# Given +# var a variable to store the result +# name the filename prefix +# num an id number +# generate a filename from name and num and store it in var. +# +setfilename() { + var="$1" + name="$2" + num="$3" + if [ "$num" -lt 10 ]; then + eval "$var='${name}000${num}'" + elif [ "$num" -lt 100 ]; then + eval "$var='${name}00${num}'" + elif [ "$num" -lt 1000 ]; then + eval "$var='${name}0${num}'" + else + eval "$var='${name}${num}'" + fi +} + +# +# If the WITHOPEN option is set, create a modified program text (with a +# different name) whose first lines import dependencies. +# Args: +# filename the id of the program text +# openfilenums its dependencies (id list) +# +addopen() { + filename="$1" + openfilenums="$2" + unset of f + + if [ -n "$WITHOPEN" ]; then + setfilename f "$PREFIX" "$filename" + if [ -f "$SUBDIR$f$EXT" ]; then + + openfiles="" + for n in $openfilenums; do + setfilename of "$WITHOPEN" "$n" + # shellcheck disable=SC2154 + openfiles="$openfiles ${INCLUDECMD} $of" + done + + setfilename of "$WITHOPEN" "$filename" + if [ -n "$openfiles" ]; then + addedlines=$((addedlines + 1)) + printf '%s \n' "$openfiles" > "$SUBDIR$of$EXT" + cat "$SUBDIR$f$EXT" >> "$SUBDIR$of$EXT" + else + cat "$SUBDIR$f$EXT" > "$SUBDIR$of$EXT" + fi + fi + fi +} + +# A filename string for sed that ignores the case (BSD sed has no i flag) +makeicfilename() { + IFILENAME="" + for l in $(printf "%s" "$FILENAME" | sed -e 's/\(.\)/\1 /g'); do + L="$(printf "%s" "$l" | tr "[:lower:]" "[:upper:]")" + IFILENAME="${IFILENAME}[$L$l]" + done +} + +# +# Given +# $ERRFILE path to the file containing error messages +# $ADJUSTLINETEXT the text preceding the line number (default: "line") +# if empty or unset, no adjustments are made. +# $addedlines the amount by which to decrement line numbers +# +adjustlinenumbers() { + if [ -n "$ADJUSTLINETEXT" ]; then + printf '' > "$ERRFILE-adjusted" + while read line + do + linen=$(expr "$line" : ".*$ADJUSTLINETEXT *\([0-9][0-9]*\).*") + if [ -n "$linen" ]; then + before=$(expr "$line" : "^\(.*$ADJUSTLINETEXT *\)$linen.*$") + after=$(expr "$line" : "^.*$ADJUSTLINETEXT *$linen\(.*\)$") + newlinen=$((linen - addedlines)) + printf "%s%s%s\n" "$before" "$newlinen" "$after" \ + >> "$ERRFILE-adjusted" + else + printf "%s\n" "$line" >> "$ERRFILE-adjusted" + fi + done < "$ERRFILE" + mv "$ERRFILE-adjusted" "$ERRFILE" + fi +} + +# +# Given +# num a program (id) +# openfilenums its dependencies (id list) +# (Try to) Compile the program and create a corresponding .tex file that +# summarizes the results for reading back into the source document. +# +compile() { + num="$1" + openfilenums="$2" + unset ifile ofile outf of FILENAME + + # Decide whether to use the original program source or the version + # augmented to import dependencies. + if [ -n "$WITHOPEN" ]; then + FILENAME=${WITHOPEN} + else + FILENAME=${PREFIX} + fi + makeicfilename + + # Generate the program (ifile) and output (ofile) filenames + setfilename ifile "$FILENAME" "$num" + # shellcheck disable=SC2154 + ipath="$SUBDIR$ifile$EXT" + setfilename ofile "$PREFIX" "$num" + # shellcheck disable=SC2154 + opath="$SUBDIR$ofile.tex" + opath_msg="$SUBDIR$ofile.msg" + opath_err="$SUBDIR$ofile.err" + opath_html="$SUBDIR$ofile.html" + + # Check that the input file exists + if [ -f "$ipath" ]; then + printf '> %s%s...%s\n' "$BLUE" "$ofile$EXT" "$BLACK" + else + printf '%s> %s%s: program source not found.%s\n' \ + "$RED" "$ofile" "$EXT" "$BLACK" + return 1 + fi + + # Generate a list of dependency filenames to pass to the compiler + openfiles="" + for n in $openfilenums; do + setfilename of "$FILENAME" "$n" + openfiles="$openfiles $SUBDIR$of$EXT" + done + + # Invoke the compiler + # shellcheck disable=SC2086 + $COMPILER $COMPILERFLAGS $openfiles $LASTFLAGS "$ipath" \ + >"$OUTFILE" 2>"$ERRFILE" + COMPILERSTATUS=$? + adjustlinenumbers + + # Start the output tex file with the compilation command as a comment + printf '%% %s\n' "$COMPILER $COMPILERFLAGS $openfiles \ + $LASTFLAGS $ipath ($COMPILERSTATUS)" > "$opath" + + # Signal compilation success (\chklistingtrue) or not (\chklistingfalse) + if [ "$COMPILERSTATUS" -eq 0 ]; then + printf '\\chklistingtrue\n' >> "$opath" + if [ "$SHOULDFAIL" -eq 1 ]; then + printf '%s unexpected success (line %s/ page %s)!%s\n' \ + "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2 + fi + else + printf '\\chklistingfalse\n' >> "$opath" + if [ "$SHOULDFAIL" -eq 0 ]; then + printf "%s unexpected failure (line %s / page %s)!%s\n" \ + "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2 + while read line + do + printf " | %s\n" "$line" + done < "$ERRFILE" >&2 + fi + fi + + # Include a sanitized compilation command (\setchklistingcmd) + printf '\setchklistingcmd{%s %s \\chklistingfile}\n' \ + "${COMPILERNAME}" "${LASTFLAGS}" >> "$opath" + + # Include the compiler's stdout + printf "%s\n" '\begin{ChkListingMsg}' >> "$opath" + if [ "$(wc -l < "$OUTFILE")" -eq 0 ]; then + printf "Failed.\n" >> "$opath" + else + sed -e "s#$SUBDIR$ifile#$PREFIX#g" \ + -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \ + "$OUTFILE" > "$opath_msg" + cat "$opath_msg" >> "$opath" + fi + printf "%s\n" '\end{ChkListingMsg}' >> "$opath" + + # Include the compiler's stderr + printf "%s\n" '\begin{ChkListingErr}' >> "$opath" + if [ "$(wc -l < "$ERRFILE")" -eq 0 ]; then + printf "%s\n" "Success." >> "$opath" + else + sed -e "s#$SUBDIR$ifile#$PREFIX#g" \ + -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \ + "$ERRFILE" > "$opath_err" + cat "$opath_err" >> "$opath" + fi + printf "%s\n" '\end{ChkListingErr}' >> "$opath" + + # Filter to html if necessary + if [ -n "$HTMLFILTER" ]; then + # shellcheck disable=SC2086 + if [ "$HTMLFILTER" = "cat" ]; then + printf '<pre>\n' > "$opath_html" + $HTMLFILTER "$ipath" >> "$opath_html" + printf '</pre>\n' >> "$opath_html" + else + $HTMLFILTER "$ipath" > "$opath_html" + fi + fi + + return 0 +} + +locked= +dooption() { + opt_name="$1" + opt_value="$2" + + case "$opt_name" in + lock\ *) + opt_name=${opt_name#lock } + locked="$locked $opt_name " + ;; + *) + if [ "$(expr "$locked" : ".* $opt_name .*")" -ne 0 ]; then + printf \ + 'info: %s: ignoring locked option ''%s''\n' \ + "$infile" "$opt_name" >&2 + return + fi + ;; + esac + + case "$opt_name" in + subdir) + SUBDIR="$opt_value" ;; + prefix) + PREFIX="$opt_value" ;; + ext) + EXT="$opt_value" ;; + compiler) + COMPILER="${opt_value}" + COMPILERNAME="$(basename "${COMPILER}")" + ;; + compilerflags) + COMPILERFLAGS="${opt_value}" ;; + lastflags) + LASTFLAGS="${opt_value}" ;; + includecmd) + INCLUDECMD="${opt_value}" + if [ -z "$INCLUDECMD" ]; then + WITHOPEN= + else + WITHOPEN=Withopen + fi + ;; + htmlfilter) + HTMLFILTER="${opt_value}" ;; + esac +} + +subdirs= +readchkl() { + infile=$1 + unset l existing openfilenums filenum opennums + + # Process each line of the command file + while read l; do + addedlines=0 + case $l in + [[:digit:]]*:*) + # a snippet to be compiled + filenum=$(expr "$l" : '\(.*\):.*') + openfilenums=$(expr "$l" : '.*:\(.*\)') + + # build up a list of dependencies in opennums + opennums="" + for n in $openfilenums; do + case $n in + \[page=*) + PAGENUM=$(expr "$n" : '\[page=\(.*\)\]') + if [ "$PAGENUM" = "" ]; then + PAGENUM="unknown" + fi + ;; + \]) + # ignore invalid patterns when checklistings.sty + # cannot expand \thepage properly (due to a + # conflicting package setting) and instead produces + # '[page=\thepage ]' which is read as two tokens: + # '[page=\thepage' and ']'. + ;; + \[line=*\]) + LINENUM=$(expr "$n" : '\[line=\(.*\)\]') + ;; + \[fail\]) + SHOULDFAIL=1 + ;; + \[skip=*\]) + addedlines=$(expr "$n" : '\[skip=\([0-9][0-9]*\)\]') + ;; + *) + if [ "$n" -eq "$n" ] 2>/dev/null; then + opennums="$opennums $n" + else + printf \ + "%swarning: %s: ignoring unresolved include '%s'%s\n" \ + "$RED" "$filenum" "$n" "$BLACK" >&2 + fi + ;; + esac + done + + addopen "$filenum" "$opennums" + compile "$filenum" "$opennums" + ;; + + *=*) + n="$(expr "$l" : '\([^=]*\)=.*')" + v="$(expr "$l" : '.*=\(.*\)')" + dooption "$n" "$v" + if [ "$n" = "subdir" ]; then + existing=$(expr "$subdirs" : ".*::${SUBDIR}:\\([^:]*\\):.*") + if [ -n "$existing" ]; then + printf "%swarning: %s: subdir=%s already used by %s!%s\n" \ + "$RED" "$infile" "$SUBDIR" "$existing" "$BLACK" >&2 + fi + fi + ;; + + *) + if [ -n "$l" ]; then + printf "%sbad %s: %s%s\n" "$RED" "$infile" "$l" "$BLACK" >&2 + fi + ;; + esac + unset PAGENUM + unset LINENUM + SHOULDFAIL=0 + done < "$1" + subdirs="$subdirs::$SUBDIR:$infile:" +} + +# Loop through each checklistings command file +for f in ${INFILES}; do + + # Add the suffix if necessary (as latex does) + case $f in + *${SUFFIX}) ;; + *) infile="$f$SUFFIX" ;; + esac + + readchkl "$f" +done + +cleanup + diff --git a/Master/bin/alpha-linux/checklistings b/Master/bin/alpha-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/alpha-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/amd64-freebsd/checklistings b/Master/bin/amd64-freebsd/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/amd64-freebsd/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/amd64-netbsd/checklistings b/Master/bin/amd64-netbsd/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/amd64-netbsd/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/armel-linux/checklistings b/Master/bin/armel-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/armel-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/armhf-linux/checklistings b/Master/bin/armhf-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/armhf-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/i386-cygwin/checklistings b/Master/bin/i386-cygwin/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/i386-cygwin/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/i386-freebsd/checklistings b/Master/bin/i386-freebsd/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/i386-freebsd/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/i386-linux/checklistings b/Master/bin/i386-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/i386-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/i386-netbsd/checklistings b/Master/bin/i386-netbsd/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/i386-netbsd/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/i386-solaris/checklistings b/Master/bin/i386-solaris/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/i386-solaris/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/mipsel-linux/checklistings b/Master/bin/mipsel-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/mipsel-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/powerpc-linux/checklistings b/Master/bin/powerpc-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/powerpc-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/sparc-solaris/checklistings b/Master/bin/sparc-solaris/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/sparc-solaris/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/universal-darwin/checklistings b/Master/bin/universal-darwin/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/universal-darwin/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/x86_64-cygwin/checklistings b/Master/bin/x86_64-cygwin/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/x86_64-cygwin/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/x86_64-darwin/checklistings b/Master/bin/x86_64-darwin/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/x86_64-darwin/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/x86_64-linux/checklistings b/Master/bin/x86_64-linux/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/x86_64-linux/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/bin/x86_64-solaris/checklistings b/Master/bin/x86_64-solaris/checklistings new file mode 120000 index 00000000000..0ba1400d830 --- /dev/null +++ b/Master/bin/x86_64-solaris/checklistings @@ -0,0 +1 @@ +../../texmf-dist/scripts/checklistings/checklistings.sh
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/checklistings/Makefile b/Master/texmf-dist/doc/latex/checklistings/Makefile new file mode 100644 index 00000000000..15126e2aba6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/Makefile @@ -0,0 +1,42 @@ + +all: checklistings.sty checklistings.pdf + +checklistings.pdf: checklistings.dtx checklistings.ind checklistings.sty \ + checklistings.chkl + ./checklistings.sh checklistings.chkl + pdflatex $< + pdflatex $< + +checklistings.ind: checklistings.idx + makeindex -s gind.ist -o $@ $< + +checklistings.idx checklistings.chkl: checklistings.dtx + pdflatex $< + +checklistings.sty: checklistings.dtx + latex checklistings.ins + +example.pdf: example.tex example.chkl checklistings.sty + ./checklistings.sh example.chkl + pdflatex $< + pdflatex $< + +example.html: example.tex example.chkl checklistings.hva + ./checklistings.sh example.chkl + hevea -fix example + +example.chkl: example.tex + pdflatex $< + +clean: + -@rm -rf chklisting0*.tex chklisting0*.ml Withopen* + -@rm -rf chklisting0*.msg chklisting0*.err + -@rm -rf checklistings.aux checklistings.glo checklistings.idx + -@rm -rf checklistings.ilg checklistings.ind checklistings.log + -@rm -rf checklistings.chkl checklistings.tmp + -@rm -rf checklistings.hd checklistings.out + -@rm -rf example0*.tex example0*.ml + -@rm -rf example0*.msg example0*.err example0*.html + -@rm -rf example.aux example.log + -@rm -rf example.chkl example.tmp + diff --git a/Master/texmf-dist/doc/latex/checklistings/README.md b/Master/texmf-dist/doc/latex/checklistings/README.md new file mode 100644 index 00000000000..70f6c7fcabe --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/README.md @@ -0,0 +1,56 @@ +checklistings +============= + +By [Timothy Bourke](http://www.tbrk.org) +and [Marc Pouzet](http://www.di.ens.fr/~pouzet). + +User manuals and papers about programming languages usually contain many +code samples, often with accompanying compiler messages giving the types +of declarations or error messages explaining why certain declarations are +invalid. + +The `checklistings` package augments the +[fancyvrb](http://www.ctan.org/pkg/fancyvrb) and +[listings](http://www.ctan.org/pkg/listings) packages for including source +code in LaTeX documents with a way to pass the source code through a +compiler and also include the resulting messages in the document. + +The motivation is to check the code samples in a document for syntax and +typing errors and to facilitate the inclusion of inferred types and compiler +warnings or errors in a text. This package is intentionally very lightweight +and unlike packages like [python](http://www.ctan.org/pkg/python) it is not +intended for interacting with an interpretor or including the execution +traces of code. While `checklistings` does not focus on a specific +programming language, it is designed to work well with ML-like languages. + +Using the package involves three elements: + +1. The declaration `\usepackage{checklistings}`. +2. The verbatim environment `\begin{chklisting}...\end{chklisting}`. +3. The shell script `checklistings.sh`. + +In a first pass, `latex`/`pdflatex` outputs code samples into files. +The second pass is performed by `checklistings.sh` which passes each file +through a compiler to generate corresponding output files. +In a third pass, `latex`/`pdflatex` reads from the generated files to +incorporate the results into the document. + +A `checklistings.hva` file is provided for interoperability with +[HeVeA](http://hevea.inria.fr). + +The `checklistings` package may be distributed and/or modified under the +conditions of the +[LaTeX Project Public License](http://www.latex-project.org/lppl.txt), +either version 1.2 of this license or (at your option) any later version. + +Please send comments, suggestions, and bug reports (with version number and +the keyword "checklistings" in the subject of the message) to +<tim@tbrk.org>. Please keep in mind that we prefer to keep `checklistings` +simple and lightweight rather than to incorporate many different +configuration and customization options. The source code is hosted on +[GitHub](https://github.com/tbrk/checklistings). + +This package was developed within the +[PARKAS](http://www.di.ens.fr/ParkasTeam.html) at +[Inria](http://www.inria.fr) and the [ENS](http://www.di.ens.fr). + diff --git a/Master/texmf-dist/doc/latex/checklistings/checklistings.hva b/Master/texmf-dist/doc/latex/checklistings/checklistings.hva new file mode 100644 index 00000000000..8e3a95563bb --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/checklistings.hva @@ -0,0 +1,188 @@ +%% HeVeA support for checklistings. +%% +%% Limitations / caveats +%% +%% * checklistings.hva requires all the intermediate generated by latex and +%% checklistings.sh (*.<ext>, *.tex, *.msg, *.err). +%% +%% * The options 'codestyle', 'msgstyle', 'errstyle', 'codelst', 'msglst', +%% and 'errlst' cannot be set as in LaTeX, e.g., +%% \checklistings{codelst={language=caml}} +%% Since HeVeA eliminates the grouping braces and passes 'language' to +%% the handler for 'codelst' (rather than 'language=caml'). +%% +%% One workaround is to \usepackage{hevea} and use \ifhevea to select +%% the most appropriate of the two forms. +%% +%% * fancyvrb and the package options codestyle, msgstyle, and errstyle are +%% not supported. +%% Alternative 1: use the codelst, msglst, and errlst options. +%% Alternative 2: use css for formatting code, messages, and errors. +%% +%% * Non-empty labels in the arguments of \chklistingmsg and +%% \chklistingerr are not supported. +%% +\ProvidesPackage{checklistings} +\RequirePackage{keyval} +\RequirePackage{listings} + +\newcounter{chklisting} +\setcounter{chklisting}{-1} + +\newif\ifCHKL@fileexists +\newif\ifCHKL@showcode\CHKL@showcodetrue +\newif\ifCHKL@shouldfail\CHKL@shouldfailfalse +\newif\ifCHKL@withresult\CHKL@withresultfalse +\newif\ifCHKL@showerrors\CHKL@showerrorstrue +\newif\ifCHKL@loadhtml\CHKL@loadhtmlfalse +\def\CHKL@pkg@skipopts{} + +% % % Declare Options % % % + +\DeclareOption{withresult}{\CHKL@withresulttrue} +\DeclareOption{withoutresult}{\CHKL@withresultfalse} +\DeclareOption{skipone}{\def\CHKL@pkg@skipopts{firstline=2}} +\DeclareOption{skiptwo}{\def\CHKL@pkg@skipopts{firstline=3}} +\DeclareOption{showproblems}{\CHKL@showproblemstrue} +\DeclareOption{hideproblems}{\CHKL@showproblemsfalse} + +\def\CHKL@codestyle{} +\def\CHKL@msgstyle{} +\def\CHKL@errstyle{} +\define@key{CHKL@pkgkeys}{codestyle}[]{\def\CHKL@codestyle{#1}} +\define@key{CHKL@pkgkeys}{msgstyle}[]{\def\CHKL@msgstyle{#1}} +\define@key{CHKL@pkgkeys}{errstyle}[]{\def\CHKL@errstyle{#1}} + +\def\CHKL@codelst{} +\def\CHKL@msglst{} +\def\CHKL@errlst{} +\define@key{CHKL@pkgkeys}{codelst}[]{\def\CHKL@codelst{#1}} +\define@key{CHKL@pkgkeys}{msglst}[]{\def\CHKL@msglst{#1}} +\define@key{CHKL@pkgkeys}{errlst}[]{\def\CHKL@errlst{#1}} + +\def\CHKL@subdir{.} +\def\CHKL@prefix{chklisting} +\def\CHKL@prompt{\#} +\def\CHKL@ext{.ml} +\define@key{CHKL@pkgkeys}{prompt}[]{\def\CHKL@prompt{#1}} +\define@key{CHKL@pkgkeys}{subdir}[]{\def\CHKL@subdir{#1}} +\define@key{CHKL@pkgkeys}{prefix}[]{\def\CHKL@prefix{#1}} +\define@key{CHKL@pkgkeys}{ext}[]{\def\CHKL@ext{#1}} +\define@key{CHKL@pkgkeys}{html}[]{\CHKL@loadhtmltrue} + +% Unused options +\define@key{CHKL@pkgkeys}{compiler}[]{} +\define@key{CHKL@pkgkeys}{compilerflags}[]{} +\define@key{CHKL@pkgkeys}{lastflags}[]{} +\define@key{CHKL@pkgkeys}{includecmd}[]{} + +% % % Process Options % % % + +% Work around the lack of \DeclareOption* in package.hva +\renewcommand{\@process@option}[1]% + {\def\pkg@opt{{\@nostyle\@callprim{\@eatspaces}{#1,}}}% + \ifu\csname\@pkg@opt@name{\pkg@opt}\endcsname + \setkeys{CHKL@pkgkeys}{#1} + \else + \csname\@pkg@opt@name{\pkg@opt}\endcsname\fi}% + +\ProcessOptions* +\newcommand{\checklistings}[1]{\ExecuteOptions{#1}} + +% % % Macros used in files generated by checklistings.sh % % % + +\newif\ifchklisting +\newcommand{\setchklistingcmd}[1]{% + \global\def\chklistingcmd{\emph{\CHKL@prompt{#1}}}} + +\newenvironment{ChkListingMsg}{\verblatex}{\endverblatex} +\newenvironment{ChkListingErr}{\verblatex}{\endverblatex} + +\newcommand{\chklistingfile}{\CHKL@prefix\CHKL@ext} + +% % % Checklistings user macros % % % + +\define@key{CHKL@envkeys}{continue}[]{} +\define@key{CHKL@envkeys}{include}[]{} +\define@key{CHKL@envkeys}{label}[]{} +\define@key{CHKL@envkeys}{showproblems}[]{\CHKL@showproblemstrue} +\define@key{CHKL@envkeys}{hideproblems}[]{\CHKL@showproblemsfalse} +\define@key{CHKL@envkeys}{skipnone}[]{\def\CHKL@pkg@skipopts{firstline=1}} +\define@key{CHKL@envkeys}{skipone}[]{\def\CHKL@pkg@skipopts{firstline=2}} +\define@key{CHKL@envkeys}{skiptwo}[]{\def\CHKL@pkg@skipopts{firstline=3}} +\define@key{CHKL@envkeys}{hide}[]{\CHKL@showcodefalse} +\define@key{CHKL@envkeys}{withresult}[]{\CHKL@withresulttrue} +\define@key{CHKL@envkeys}{withoutresult}[]{\CHKL@withresultfalse} +\define@key{CHKL@envkeys}{fail}[]{\CHKL@shouldfailtrue} + +% Work around the lack of \edef and \expandafter +\def\CHKL@lstset#1{\lstset{#1}} +\def\elstset#1{\@callprim{\CHKL@lstset}{\{#1\}}} + +\newcommand{\chklistingmsg}{\bgroup% + \setenvclass{lstlisting}{lstlisting chklistingmsg}% + \elstset{\CHKL@msgstyle}% + \elstset{\CHKL@msglst}% + \lstinputlisting{\CHKL@subdir/\CHKL@prefix\CHKL@num.msg}% + \egroup}% + +\newcommand{\chklistingerr}{\bgroup% + \setenvclass{lstlisting}{lstlisting chklistingerr}% + \elstset{\CHKL@errstyle}% + \elstset{\CHKL@errlst}% + \lstinputlisting{\CHKL@subdir/\CHKL@prefix\CHKL@num.err}% + \egroup}% + +\newenvironment{chklisting}[1][] + {% + \setenvclass{lstlisting}{lstlisting chklisting}% + \stepcounter{chklisting}% + \def\@currentlabel{\thechklisting}% + \@setkeys{CHKL@envkeys}{#1}% + \global\def\CHKL@num{% + \ifthenelse{\value{chklisting}<1000}{0}{}% + \ifthenelse{\value{chklisting}<100}{0}{}% + \ifthenelse{\value{chklisting}<10}{0}{}% + \arabic{chklisting}}% + \global\def\CHKL@file{\CHKL@subdir/\CHKL@prefix\CHKL@num}% + \global\let\chklistingcmd\relax% + \ifCHKL@showcode% + \bgroup% + \ifCHKL@loadhtml% + \@open{div}{class="chklisting"}% + \rawinput{\CHKL@file{}.html}% + \@close{div}% + \else% + \elstset{\CHKL@pkg@skipopts}% + \elstset{\CHKL@codestyle}% + \elstset{\CHKL@codelst}% + \lstinputlisting{\CHKL@file\CHKL@ext}% + \fi% + \egroup% + \input{\CHKL@file.tex}% + \ifCHKL@shouldfail% + \ifchklisting% + \ifCHKL@showproblems% + \begin{divstyle}{checklistingserror}% + Unexpected success: \chklistingmsg{} + \end{divstyle}% + \fi% + \else% + \ifCHKL@withresult{\chklistingerr{}}\fi% + \fi% + \else + \ifchklisting% + \ifCHKL@withresult{\chklistingmsg{}}\fi% + \else% + \ifCHKL@showproblems% + \begin{divstyle}{checklistingserror}% + Unexpected failure: \chklistingerr{} + \end{divstyle}% + \fi% + \fi% + \fi + \fi% + \verblatex% + } + {\endverblatex}% +\endinput diff --git a/Master/texmf-dist/doc/latex/checklistings/checklistings.pdf b/Master/texmf-dist/doc/latex/checklistings/checklistings.pdf Binary files differnew file mode 100644 index 00000000000..49f1aa917c9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/checklistings.pdf diff --git a/Master/texmf-dist/doc/latex/checklistings/example.html b/Master/texmf-dist/doc/latex/checklistings/example.html new file mode 100644 index 00000000000..5a78714da5a --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/example.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<meta name="generator" content="hevea 2.16"> +<style type="text/css"> +.li-itemize{margin:1ex 0ex;} +.li-enumerate{margin:1ex 0ex;} +.dd-description{margin:0ex 0ex 1ex 4ex;} +.dt-description{margin:0ex;} +.toc{list-style:none;} +.footnotetext{margin:0ex; padding:0ex;} +div.footnotetext P{margin:0px; text-indent:1em;} +.thefootnotes{text-align:left;margin:0ex;} +.dt-thefootnotes{margin:0em;} +.dd-thefootnotes{margin:0em 0em 0em 2em;} +.footnoterule{margin:1em auto 1em 0px;width:50%;} +.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto} +.title{margin:2ex auto;text-align:center} +.titlemain{margin:1ex 2ex 2ex 1ex;} +.titlerest{margin:0ex 2ex;} +.center{text-align:center;margin-left:auto;margin-right:auto;} +.flushleft{text-align:left;margin-left:0ex;margin-right:auto;} +.flushright{text-align:right;margin-left:auto;margin-right:0ex;} +div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px} +td table{margin:auto;} +table{border-collapse:collapse;} +td{padding:0;} +.cellpadding0 tr td{padding:0;} +.cellpadding1 tr td{padding:1px;} +pre{text-align:left;margin-left:0ex;margin-right:auto;} +blockquote{margin-left:4ex;margin-right:4ex;text-align:left;} +td p{margin:0px;} +.boxed{border:1px solid black} +.textboxed{border:1px solid black} +.vbar{border:none;width:2px;background-color:black;} +.hbar{border:none;height:2px;width:100%;background-color:black;} +.hfill{border:none;height:1px;width:200%;background-color:black;} +.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;} +.vdcell{white-space:nowrap;padding:0px; border:2px solid green;} +.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;} +.dcell{white-space:nowrap;padding:0px; border:none;} +.dcenter{margin:0ex auto;} +.vdcenter{border:solid #FF8000 2px; margin:0ex auto;} +.minipage{text-align:left; margin-left:0em; margin-right:auto;} +.marginpar{border:solid thin black; width:20%; text-align:left;} +.marginparleft{float:left; margin-left:0ex; margin-right:1ex;} +.marginparright{float:right; margin-left:1ex; margin-right:0ex;} +.theorem{text-align:left;margin:1ex auto 1ex 0ex;} +.part{margin:2ex auto;text-align:center} +.lstlisting{font-family:monospace;white-space:pre;margin-right:auto;margin-left:0pt;text-align:left} +.chklistingerr{font-style: italic; color: red;} +.chklistingmsg{font-style: italic;} +</style> +<title>example</title> +</head> +<body > +<!--HEVEA command line is: /usr/bin/hevea -fix example --> +<!--CUT STYLE article--><!--CUT DEF section 1 --><p>Two simple declarations: +</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">x</span><span style="font-family:sans-serif"> = 3</span><span style="font-family:sans-serif"> +</span><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">f</span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">x</span><span style="font-family:sans-serif"> = </span><span style="font-family:sans-serif">x</span><span style="font-family:sans-serif"> + 1</span></div><p>and, after compilation with <em>ocamlc -i example.ml</em>, their types: +</p><div class="lstlisting chklistingmsg">val x : int +val f : int -> int</div><p>Then, building on these definitions: +</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">y</span><span style="font-family:sans-serif"> = </span><span style="font-family:sans-serif">f</span><span style="font-family:sans-serif"> 3</span></div><div class="lstlisting chklistingmsg">val y : int</div><p>What about compiler error messages?: +</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">z</span><span style="font-family:sans-serif"> = 3 + </span><span style="font-family:sans-serif"><span style="font-family:sans-serif">"four"</span></span></div><p>They are also detected: +</p><div class="lstlisting chklistingerr">File "example.ml", line 1, characters 12-18: +Error: This expression has type string but an expression was expected of type + int</div><p>We can continue on from earlier examples:</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">z</span><span style="font-family:sans-serif"> = </span><span style="font-family:sans-serif">f</span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">y</span></div><div class="lstlisting chklistingmsg">val z : int</div><!--CUT END --> +<!--HTMLFOOT--> +<!--ENDHTML--> +<!--FOOTER--> +<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by +</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body> +</html> diff --git a/Master/texmf-dist/doc/latex/checklistings/example.pdf b/Master/texmf-dist/doc/latex/checklistings/example.pdf Binary files differnew file mode 100644 index 00000000000..37def76c622 --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/example.pdf diff --git a/Master/texmf-dist/doc/latex/checklistings/example.tex b/Master/texmf-dist/doc/latex/checklistings/example.tex new file mode 100644 index 00000000000..88980097a9f --- /dev/null +++ b/Master/texmf-dist/doc/latex/checklistings/example.tex @@ -0,0 +1,56 @@ +\documentclass[a4paper]{article} + +\usepackage[T1]{fontenc} +\usepackage[prompt=,prefix=example]{checklistings} +\usepackage{listings} + +\lstdefinestyle{camlstyle}{% + language=caml, + basicstyle=\sffamily, + keywordstyle=\bf, + literate={"}{\textquotedbl}1, +} +%BEGIN LATEX +\checklistings{codelst={style=camlstyle}} +%END LATEX +%HEVEA \newstyle{.chklistingerr}{font-style: italic; color: red;} +%HEVEA \newstyle{.chklistingmsg}{font-style: italic;} +%HEVEA \checklistings{codelst=\{style=camlstyle\}} + +\begin{document} + +\noindent +Two simple declarations: +\begin{chklisting} +let x = 3 +let f x = x + 1 +\end{chklisting} + +\noindent +and, after compilation with \chklistingcmd, their types: +\chklistingmsg{} + +\noindent +Then, building on these definitions: +\begin{chklisting}[continue,withresult,label=early] +let y = f 3 +\end{chklisting} + +\noindent +What about compiler error messages?: +\begin{chklisting}[fail] +let z = 3 + "four" +\end{chklisting} + +\noindent +They are also detected: +\chklistingerr{} + +\noindent +We can continue on from earlier examples: + +\begin{chklisting}[withresult,include=early] +let z = f y +\end{chklisting} + +\end{document} diff --git a/Master/texmf-dist/scripts/checklistings/checklistings.sh b/Master/texmf-dist/scripts/checklistings/checklistings.sh new file mode 100755 index 00000000000..4131d9acbc4 --- /dev/null +++ b/Master/texmf-dist/scripts/checklistings/checklistings.sh @@ -0,0 +1,446 @@ +#!/bin/sh +# +# checklistings # +# version 1.0 # +# # +# Timothy Bourke <tim@tbrk.org> # +# Inria # +# École normale supérieure # +# # +# Marc Pouzet <pouzet@ens.fr> # +# Université Pierre et Marie Curie # +# École normale supérieure # +# Inria # +# + +## +# Configuration +SCRIPT=$(basename "$0") +SUFFIX=.chkl + +RED="[0;31m" +BLUE="[0;34m" +BLACK="[0;0m" + +ADJUSTLINETEXT=line + +## +# Command-line + +usage () { + printf '%s: check source code exported from LaTeX documents.\n' "$SCRIPT" + printf 'usage: %s [options] [file ...]\n' "$SCRIPT" + printf '\n' + printf ' options:\n' + printf ' --no-colors log to terminal without control codes\n' + printf ' --no-line-adjust do not try to adjust error line numbers\n' + printf '\n' +} + +unset INFILES +while [ -n "$1" ]; do + case "$1" in + --no-colors) + unset RED BLUE BLACK + ;; + --no-line-adjust) + unset ADJUSTLINETEXT + ;; + --h) + usage + exit 0 + ;; + --help) + usage + exit 0 + ;; + -*) + printf "%s: unrecognized option '%s'\n" "$SCRIPT" "$1" + usage + exit 1 + ;; + *${SUFFIX}) + INFILES="$INFILES $1" + ;; + *) + INFILES="$INFILES $1${SUFFIX}" + ;; + esac + shift +done + +if [ -z "$INFILES" ]; then + INFILES=$(ls ./*${SUFFIX}) +fi + +## +# Allocate temporary files + +cleanup() { + rm -f "${OUTFILE}" "${ERRFILE}" +} +OUTFILE=$(mktemp -t "${SCRIPT}.out.XXXXXX") || exit 1 +ERRFILE=$(mktemp -t "${SCRIPT}.err.XXXXXX") || (cleanup; exit 1) +trap cleanup 1 2 15 + +## +# Code + +# +# Given +# var a variable to store the result +# name the filename prefix +# num an id number +# generate a filename from name and num and store it in var. +# +setfilename() { + var="$1" + name="$2" + num="$3" + if [ "$num" -lt 10 ]; then + eval "$var='${name}000${num}'" + elif [ "$num" -lt 100 ]; then + eval "$var='${name}00${num}'" + elif [ "$num" -lt 1000 ]; then + eval "$var='${name}0${num}'" + else + eval "$var='${name}${num}'" + fi +} + +# +# If the WITHOPEN option is set, create a modified program text (with a +# different name) whose first lines import dependencies. +# Args: +# filename the id of the program text +# openfilenums its dependencies (id list) +# +addopen() { + filename="$1" + openfilenums="$2" + unset of f + + if [ -n "$WITHOPEN" ]; then + setfilename f "$PREFIX" "$filename" + if [ -f "$SUBDIR$f$EXT" ]; then + + openfiles="" + for n in $openfilenums; do + setfilename of "$WITHOPEN" "$n" + # shellcheck disable=SC2154 + openfiles="$openfiles ${INCLUDECMD} $of" + done + + setfilename of "$WITHOPEN" "$filename" + if [ -n "$openfiles" ]; then + addedlines=$((addedlines + 1)) + printf '%s \n' "$openfiles" > "$SUBDIR$of$EXT" + cat "$SUBDIR$f$EXT" >> "$SUBDIR$of$EXT" + else + cat "$SUBDIR$f$EXT" > "$SUBDIR$of$EXT" + fi + fi + fi +} + +# A filename string for sed that ignores the case (BSD sed has no i flag) +makeicfilename() { + IFILENAME="" + for l in $(printf "%s" "$FILENAME" | sed -e 's/\(.\)/\1 /g'); do + L="$(printf "%s" "$l" | tr "[:lower:]" "[:upper:]")" + IFILENAME="${IFILENAME}[$L$l]" + done +} + +# +# Given +# $ERRFILE path to the file containing error messages +# $ADJUSTLINETEXT the text preceding the line number (default: "line") +# if empty or unset, no adjustments are made. +# $addedlines the amount by which to decrement line numbers +# +adjustlinenumbers() { + if [ -n "$ADJUSTLINETEXT" ]; then + printf '' > "$ERRFILE-adjusted" + while read line + do + linen=$(expr "$line" : ".*$ADJUSTLINETEXT *\([0-9][0-9]*\).*") + if [ -n "$linen" ]; then + before=$(expr "$line" : "^\(.*$ADJUSTLINETEXT *\)$linen.*$") + after=$(expr "$line" : "^.*$ADJUSTLINETEXT *$linen\(.*\)$") + newlinen=$((linen - addedlines)) + printf "%s%s%s\n" "$before" "$newlinen" "$after" \ + >> "$ERRFILE-adjusted" + else + printf "%s\n" "$line" >> "$ERRFILE-adjusted" + fi + done < "$ERRFILE" + mv "$ERRFILE-adjusted" "$ERRFILE" + fi +} + +# +# Given +# num a program (id) +# openfilenums its dependencies (id list) +# (Try to) Compile the program and create a corresponding .tex file that +# summarizes the results for reading back into the source document. +# +compile() { + num="$1" + openfilenums="$2" + unset ifile ofile outf of FILENAME + + # Decide whether to use the original program source or the version + # augmented to import dependencies. + if [ -n "$WITHOPEN" ]; then + FILENAME=${WITHOPEN} + else + FILENAME=${PREFIX} + fi + makeicfilename + + # Generate the program (ifile) and output (ofile) filenames + setfilename ifile "$FILENAME" "$num" + # shellcheck disable=SC2154 + ipath="$SUBDIR$ifile$EXT" + setfilename ofile "$PREFIX" "$num" + # shellcheck disable=SC2154 + opath="$SUBDIR$ofile.tex" + opath_msg="$SUBDIR$ofile.msg" + opath_err="$SUBDIR$ofile.err" + opath_html="$SUBDIR$ofile.html" + + # Check that the input file exists + if [ -f "$ipath" ]; then + printf '> %s%s...%s\n' "$BLUE" "$ofile$EXT" "$BLACK" + else + printf '%s> %s%s: program source not found.%s\n' \ + "$RED" "$ofile" "$EXT" "$BLACK" + return 1 + fi + + # Generate a list of dependency filenames to pass to the compiler + openfiles="" + for n in $openfilenums; do + setfilename of "$FILENAME" "$n" + openfiles="$openfiles $SUBDIR$of$EXT" + done + + # Invoke the compiler + # shellcheck disable=SC2086 + $COMPILER $COMPILERFLAGS $openfiles $LASTFLAGS "$ipath" \ + >"$OUTFILE" 2>"$ERRFILE" + COMPILERSTATUS=$? + adjustlinenumbers + + # Start the output tex file with the compilation command as a comment + printf '%% %s\n' "$COMPILER $COMPILERFLAGS $openfiles \ + $LASTFLAGS $ipath ($COMPILERSTATUS)" > "$opath" + + # Signal compilation success (\chklistingtrue) or not (\chklistingfalse) + if [ "$COMPILERSTATUS" -eq 0 ]; then + printf '\\chklistingtrue\n' >> "$opath" + if [ "$SHOULDFAIL" -eq 1 ]; then + printf '%s unexpected success (line %s/ page %s)!%s\n' \ + "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2 + fi + else + printf '\\chklistingfalse\n' >> "$opath" + if [ "$SHOULDFAIL" -eq 0 ]; then + printf "%s unexpected failure (line %s / page %s)!%s\n" \ + "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2 + while read line + do + printf " | %s\n" "$line" + done < "$ERRFILE" >&2 + fi + fi + + # Include a sanitized compilation command (\setchklistingcmd) + printf '\setchklistingcmd{%s %s \\chklistingfile}\n' \ + "${COMPILERNAME}" "${LASTFLAGS}" >> "$opath" + + # Include the compiler's stdout + printf "%s\n" '\begin{ChkListingMsg}' >> "$opath" + if [ "$(wc -l < "$OUTFILE")" -eq 0 ]; then + printf "Failed.\n" >> "$opath" + else + sed -e "s#$SUBDIR$ifile#$PREFIX#g" \ + -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \ + "$OUTFILE" > "$opath_msg" + cat "$opath_msg" >> "$opath" + fi + printf "%s\n" '\end{ChkListingMsg}' >> "$opath" + + # Include the compiler's stderr + printf "%s\n" '\begin{ChkListingErr}' >> "$opath" + if [ "$(wc -l < "$ERRFILE")" -eq 0 ]; then + printf "%s\n" "Success." >> "$opath" + else + sed -e "s#$SUBDIR$ifile#$PREFIX#g" \ + -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \ + "$ERRFILE" > "$opath_err" + cat "$opath_err" >> "$opath" + fi + printf "%s\n" '\end{ChkListingErr}' >> "$opath" + + # Filter to html if necessary + if [ -n "$HTMLFILTER" ]; then + # shellcheck disable=SC2086 + if [ "$HTMLFILTER" = "cat" ]; then + printf '<pre>\n' > "$opath_html" + $HTMLFILTER "$ipath" >> "$opath_html" + printf '</pre>\n' >> "$opath_html" + else + $HTMLFILTER "$ipath" > "$opath_html" + fi + fi + + return 0 +} + +locked= +dooption() { + opt_name="$1" + opt_value="$2" + + case "$opt_name" in + lock\ *) + opt_name=${opt_name#lock } + locked="$locked $opt_name " + ;; + *) + if [ "$(expr "$locked" : ".* $opt_name .*")" -ne 0 ]; then + printf \ + 'info: %s: ignoring locked option ''%s''\n' \ + "$infile" "$opt_name" >&2 + return + fi + ;; + esac + + case "$opt_name" in + subdir) + SUBDIR="$opt_value" ;; + prefix) + PREFIX="$opt_value" ;; + ext) + EXT="$opt_value" ;; + compiler) + COMPILER="${opt_value}" + COMPILERNAME="$(basename "${COMPILER}")" + ;; + compilerflags) + COMPILERFLAGS="${opt_value}" ;; + lastflags) + LASTFLAGS="${opt_value}" ;; + includecmd) + INCLUDECMD="${opt_value}" + if [ -z "$INCLUDECMD" ]; then + WITHOPEN= + else + WITHOPEN=Withopen + fi + ;; + htmlfilter) + HTMLFILTER="${opt_value}" ;; + esac +} + +subdirs= +readchkl() { + infile=$1 + unset l existing openfilenums filenum opennums + + # Process each line of the command file + while read l; do + addedlines=0 + case $l in + [[:digit:]]*:*) + # a snippet to be compiled + filenum=$(expr "$l" : '\(.*\):.*') + openfilenums=$(expr "$l" : '.*:\(.*\)') + + # build up a list of dependencies in opennums + opennums="" + for n in $openfilenums; do + case $n in + \[page=*) + PAGENUM=$(expr "$n" : '\[page=\(.*\)\]') + if [ "$PAGENUM" = "" ]; then + PAGENUM="unknown" + fi + ;; + \]) + # ignore invalid patterns when checklistings.sty + # cannot expand \thepage properly (due to a + # conflicting package setting) and instead produces + # '[page=\thepage ]' which is read as two tokens: + # '[page=\thepage' and ']'. + ;; + \[line=*\]) + LINENUM=$(expr "$n" : '\[line=\(.*\)\]') + ;; + \[fail\]) + SHOULDFAIL=1 + ;; + \[skip=*\]) + addedlines=$(expr "$n" : '\[skip=\([0-9][0-9]*\)\]') + ;; + *) + if [ "$n" -eq "$n" ] 2>/dev/null; then + opennums="$opennums $n" + else + printf \ + "%swarning: %s: ignoring unresolved include '%s'%s\n" \ + "$RED" "$filenum" "$n" "$BLACK" >&2 + fi + ;; + esac + done + + addopen "$filenum" "$opennums" + compile "$filenum" "$opennums" + ;; + + *=*) + n="$(expr "$l" : '\([^=]*\)=.*')" + v="$(expr "$l" : '.*=\(.*\)')" + dooption "$n" "$v" + if [ "$n" = "subdir" ]; then + existing=$(expr "$subdirs" : ".*::${SUBDIR}:\\([^:]*\\):.*") + if [ -n "$existing" ]; then + printf "%swarning: %s: subdir=%s already used by %s!%s\n" \ + "$RED" "$infile" "$SUBDIR" "$existing" "$BLACK" >&2 + fi + fi + ;; + + *) + if [ -n "$l" ]; then + printf "%sbad %s: %s%s\n" "$RED" "$infile" "$l" "$BLACK" >&2 + fi + ;; + esac + unset PAGENUM + unset LINENUM + SHOULDFAIL=0 + done < "$1" + subdirs="$subdirs::$SUBDIR:$infile:" +} + +# Loop through each checklistings command file +for f in ${INFILES}; do + + # Add the suffix if necessary (as latex does) + case $f in + *${SUFFIX}) ;; + *) infile="$f$SUFFIX" ;; + esac + + readchkl "$f" +done + +cleanup + diff --git a/Master/texmf-dist/source/latex/checklistings/checklistings.dtx b/Master/texmf-dist/source/latex/checklistings/checklistings.dtx new file mode 100644 index 00000000000..7e12e53ab30 --- /dev/null +++ b/Master/texmf-dist/source/latex/checklistings/checklistings.dtx @@ -0,0 +1,1061 @@ +% \iffalse meta-comment +% +% Copyright (C) 2015 by Timothy Bourke <tim@tbrk.org> +% and Marc Pouzet <pouzet@ens.fr> +% ------------------------------------------------------- +% +% This file may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.2 +% of this license or (at your option) any later version. +% The latest version of this license is in: +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.2 or later is part of all distributions of LaTeX version +% 1999/12/01 or later. +% +% CTAN Topic: callback, listing +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{checklistings.dtx} +%</driver> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{checklistings} +%<package> [2015/09/01 v1.0 compile code samples and insert the results] +%<package>\RequirePackage{keyval} +%<package>\RequirePackage{kvoptions} +%<package>\RequirePackage{fancyvrb} +%<package>\RequirePackage{color} +%<package>\RequirePackage{listings} +%<package>\makeatletter +%<package>\lst@RequireAspects{writefile} +%<package>\SetupKeyvalOptions{family=CHKL,prefix=CHKL@} +%<package>\makeatother +% +%<*driver> +\documentclass{ltxdoc} + +\usepackage{checklistings} +\usepackage{url} +\usepackage{hypdoc} +\usepackage{showexpl} +\usepackage{array} +\usepackage{longtable} + +\lstset{ + basicstyle=\small\ttfamily, + numbers=none, + keywordstyle=\color{blue}\bfseries, + pos=l, +} + +\checklistings{ + msgstyle={formatcom=\footnotesize}, + errstyle={formatcom=\footnotesize}} + +\EnableCrossrefs \CodelineIndex +\RecordChanges + +\newcommand{\refsec}[1]{Section~\ref{sec:#1}} + +\begin{document} + \DocInput{checklistings.dtx} + \PrintChanges + \PrintIndex +\end{document} +%</driver> +% \fi +% +% \CheckSum{444} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2015/09/01}{Initial version} +% +% \GetFileInfo{checklistings.sty} +% +% \DoNotIndex{\newcommand,\newenvironment} +% \DoNotIndex{\@file,\@ifundefined,\@tempboxa,\@undefined} +% \DoNotIndex{\arabic,\bgroup,\color,\dimexpr,\relax,\topsep,\vspace} +% \DoNotIndex{\CurrentOption,\DeclareBoolOption,\DeclareComplementaryOption} +% \DoNotIndex{\DeclareDefaultOption,\DeclareStringOption,\DeclareVoidOption} +% \DoNotIndex{\def,\define@key,\edef,\egroup,\else,\emph,\expandafter} +% \DoNotIndex{\fi,\global,\hbox,\ifnum,\InputIfFileExists,\langle,\let} +% \DoNotIndex{\newcounter,\newif,\PackageWarning,\ProcessKeyvalOptions} +% \DoNotIndex{\rangle,\setbox,\setkeys,\space,\stepcounter} +% \DoNotIndex{\value,\@currentlabel,\@firstoftwo,\AtEndDocument,\em} +% \DoNotIndex{\closeout,\csname,\endcsname,\DefineVerbatimEnvironment} +% \DoNotIndex{\jobname,\kvsetkeys,\label,\newwrite,\noexpand,\openout} +% \DoNotIndex{\partopsep,\setlength,\thepage,\write,\resetcounteronoverlays} +% \DoNotIndex{\@tempa,\fvset,\ifx,\inputlineno,\lstset,\the} +% \DoNotIndex{\DeclareRobustCommand,\empty,\ifdefined,\meta} +% \expandafter\DoNotIndex\expandafter{\string\$} +% \expandafter\DoNotIndex\expandafter{\string\#} +% +% \title{The \textsf{checklistings} package\thanks{This document +% corresponds to \textsf{checklistings}~\fileversion, dated \filedate.}} +% \author{Timothy Bourke and Marc Pouzet} +% +% \maketitle + +% \section{Introduction} +% +% User manuals and papers about programming languages usually contain many +% code samples, often with accompanying compiler messages giving the types +% of declarations or error messages explaining why certain declarations are +% invalid. +% This package extends +% |fancyvrb|\footnote{\url{http://www.ctan.org/pkg/fancyvrb}} and +% |listings|\footnote{\url{http://www.ctan.org/pkg/listings}}, which are +% ideal for displaying code, with a way to pass code samples through a +% compiler and include the resulting messages in a \LaTeX{} document. +% The motivation is to check the code samples in a document for syntax and +% typing errors and to facilitate the inclusion of inferred types and +% compiler warnings or errors in a text. +% This package is intentionally very lightweight and unlike packages like +% |python|,\footnote{\url{http://www.ctan.org/pkg/python}} it is not +% intended for interacting with an interpretor or including the execution +% traces of code. +% While it does not focus on a specific programming language, it is designed +% to work well with ML-like languages. +% +% As an example, the text at left below is generated by the \LaTeX{} code at +% right: +% +% \iffalse +%<*example> +% \fi +\begin{LTXexample} +Code samples are included +verbatim and the results of +compilation can be included +automatically: +\begin{chklisting}[withresult] +let inc x = x + 1 +let y = inc 3 +\end{chklisting} +\end{LTXexample} +% \iffalse +%</example> +% \fi +% +% A first pass through |latex| generates both a |.chkl| file, +% with parameters for the compiler, and an |.ml| file containing the source +% code (i.e., the two lines in the example above). +% Running the |checklistings.sh| script processes these files to produce a +% |.tex| file with the results of compilation. +% A second pass through |latex| updates the compiler message. +% +% \noindent +% It is possible to continue examples and to label them (to be continued at +% some later point): +% \iffalse +%<*example> +% \fi +\begin{LTXexample}[pos=b] +These definitions follow on from the previous ones: +\begin{chklisting}[continue,withresult,label=early] +let z = y + inc y +\end{chklisting} +\end{LTXexample} +% \iffalse +%</example> +% \fi +% +% \bigskip\noindent +% Examples need not necessarily succeed: +% \iffalse +%<*example> +% \fi +\begin{LTXexample}[pos=b] +This code does not compile: +\begin{chklisting}[continue,fail,withresult,skipone] +let u = 3 +let w = u + "four" +\end{chklisting} +\end{LTXexample} +% \iffalse +%</example> +% \fi +% Note that the line number in the error message is 1 even though the +% |continue| option added a line to include the previous definitions and the +% |skipone| option hid the |let u = 3| line. +% The |checklistings.sh| script performs this adjustment by looking for the +% regular expression `|line *[0-9][0-9]*|' and decrementing the number +% appropriately. +% This approach is simple and effective but obviously not foolproof. +% Some manual tuning of the script may be required for correct results. +% +% \section{Use}\label{sec:use} +% +% Using the package involves three elements: +% \begin{enumerate} +% +% \item +% The declaration \verb|\usepackage{checklistings}|.\\ +% \refsec{rvpkg} describes the options for configuring package behaviour. +% +% \item +% The environment \verb|chklisting|.\\ +% This environment is used like any other verbatim environment. +% \refsec{rvenv} describes options that may be given to control its +% behaviour. +% +% \item +% The script \verb|checklistings.sh|.\\ +% Running this script passes the contents of each \verb|chklisting| +% environment through a compiler or interpreter and copies the resulting +% output into a file. +% +% \end{enumerate} +% +% Additionally, the file \verb|checklistings.hva| can be used to incorporate +% the output of |checklistings| in HTML documents generated by +% HeVeA.\footnote{\url{http://hevea.inria.fr}} +% +% \subsection{Package options}\label{sec:rvpkg} +% +% \DescribeMacro{\checklistings} +% Package options are either given as optional arguments to +% \verb|\usepackage| or via one or more calls to \verb|\checklistings|. +% The advantage of the latter is that macros are not expanded (for a +% detailed explanation see the documentation for +% |kvoptions|,\footnote{\url{http://www.ctan.org/pkg/kvoptions}} Section +% 4.1, \emph{Package kvoptions-patch}). +% Options are passed as a comma separated list of \meta{key}|=|\meta{value} +% pairs and single \meta{key}s. +% +% There are three classes of options: options controlling the default +% behaviour of \verb|chklisting|, options for configuring the +% \verb|checklistings.sh| script, and options controlling the display of +% code and results. +% +% \subsubsection{Behavioural options} +% +% These options control the default behaviour of the \verb|chklisting| +% environment. +% +% \begin{longtable}{@{}>{\ttfamily}lp{75mm}>{\ttfamily}l@{}} +% \parbox{15mm}{option} & description & \parbox{25mm}{default}\\\hline +% withresult +% & Automatically show compilation results. +% & false +% \\ +% skipone +% & Do not display the first line of code (see the description under the +% |chklisting| environment). +% & +% false +% \\ +% skiptwo +% & Do not display the first two lines of code (see the description under +% the |chklisting| environment). +% & +% false +% \\ +% hideproblems +% & Globally disable the display of failure messages (within a red box) when +% compilation fails or succeeds unexpectedly. +% & +% false +% \\ +% \end{longtable} +% +% \subsubsection{Configuring compilation}\label{sec:compileconfig} +% +% These options are used for naming and placing the files generated by +% \verb|chklisting| environments. +% They are passed to the \verb|checklistings.sh| script and thus control +% its behaviour. +% +% \makeatletter +% \begin{longtable}{@{}>{\ttfamily}lp{75mm}>{\ttfamily}l@{}} +% \parbox{15mm}{option} & description & \parbox{25mm}{default}\\\hline +% prefix +% & Prefix for naming source files. +% It must not contain underscores (\verb|_|). +% & \CHKL@prefix +% \\ +% ext +% & Extension of source files. +% & \CHKL@ext +% \\ +% subdir +% & If defined, source files are created in the given subdirectory, which +% must already exist. +% A final slash (\verb|/|) should not be given. +% The name must not contain underscores (\verb|_|). +% & \CHKL@subdir +% \\ +% prompt +% & The prompt displayed by |\chklistingcmd|. +% & \CHKL@prompt +% \\ +% compiler +% & Path of the compiler to execute. +% & \CHKL@compiler +% \\ +% compilerflags +% & Flags passed to the compiler. +% These are not revealed by |\chklistingcmd|. +% & \CHKL@compilerflags +% \\ +% lastflags +% & Flags passed to the compiler before the main source file, that is, the +% last one given. +% & \CHKL@lastflags +% \\ +% includecmd +% & The source language command for importing the definitions of another +% file. +% & \CHKL@includecmd +% \\ +% html +% & The path of a program that renders source code as html. +% This value can be useful when using HeVeA to produce web pages from +% \LaTeX{} documents. +% In any case, it is optional. +% & \CHKL@html +% \end{longtable} +% \makeatother +% +% Each \verb|chklisting| environment is assigned a number $n$, from zero, +% and its contents are written to the file: +% \meta{subdir}|/|\meta{prefix}\meta{n}|.|\meta{ext}, +% where \meta{n} is zero-padded to four characters. +% For example, by default, the fourth environment is written to the file +% \verb|chklisting0003.ml| in the current directory. +% +% Source lines are added for each dependency, and those files are compiled +% using the \meta{compiler}, \meta{compilerflags}, and \meta{lastflags} +% options. +% For example, if the fourth environment depends on the first and the +% second, a line is added: +% \begin{center} +% \meta{includecmd} |Withopen0000| \meta{includecmd} |Withopen0001|, +% \end{center} +% where \verb|Withopen| is the prefix used for such augmented files, and the +% compiler is invoked with:\\ +% \begin{center} +% \begin{tabular}{ll} +% \meta{compiler} +% & \meta{compilerflags}\ \ |Withopen0000|\ \ |Withopen0001| \\ +% & \meta{lastflags}\ \ |Withopen0003| +% \end{tabular} +% \end{center} +% +% \subsubsection{Controlling the display} +% +% This package exploits the display options given by the |fancyvrb| package. +% +% \begin{longtable}{@{}>{\ttfamily}lp{75mm}>{\ttfamily}l@{}} +% \parbox{15mm}{option} & description & \parbox{25mm}{default}\\\hline +% codestyle +% & |fancyvrb| options for code +% & \\ +% msgstyle +% & |fancyvrb| options for compiler messages +% & formatcom=\string\em +% \\ +% errstyle +% & |fancyvrb| options for error messages +% & formatcom=\string\em +% \\ +% codelst +% & |listings| options for source code, passed with |\lstset|. When this +% option is not empty, |fancyvrb=true| is included automatically. +% \\ +% msglst +% & As for |codelst|, but applied to compiler messages. +% \\ +% errlst +% & As for |codelst|, but applied to error messages. +% \\ +% \end{longtable} +% +% Other options are passed directly through to the |fancyvrb| package and +% applied to all |chklisting| code blocks (but not to messages or errors). +% For example, \verb|frame=single|. +% These options must typically be set using |\checklistings|, since they +% will usually contain commands that should not be expanded immediately +% (like |\em| or |\bf|). +% +% \subsection{The \texttt{chklisting} environment}\label{sec:rvenv} +% +% \DescribeEnv{chklisting} +% As an optional argument, this environment takes a comma separated list of +% \meta{key}|=|\meta{value} and single \meta{key}s. +% +% \begin{longtable}{@{}>{\ttfamily}lp{100mm}} +% \parbox{15mm}{option} & description \\\hline +% fail +% & This code is expected to fail; an error is reported if it succeeds. +% \\ +% continue +% & This code is continued from the previous |chklisting| environment; all +% of the definitions available there are imported. +% \\ +% label +% & Label this code for later inclusion. +% \\ +% include +% & All of the definitions available after the environment with the given +% label are imported. +% \\ +% withresult +% & The result of compiling the code is displayed (see also +% |\chklistingmsg| and |\chklistingerr|). +% This is normally either the types of declared values or the results of +% evaluation. +% For environments marked |fail|, it will be an error message. +% \\ +% withoutresult +% & The result of compiling code is not displayed automatically. +% This is the default behaviour, but it can be overridden by the package +% options. +% \\ +% hide +% & The code is not displayed, but it is still compiled, compiler messages +% are still displayed (if |withresult| is active), and definitions are still +% available for continuation (|continue|), labelling (|label|), and later +% inclusion (|include|). +% \\ +% skipone +% & Do not display the first line of the code. +% This line is still sent to the compiler and may thus be used to open +% other modules, or to pass execution options (via comments). +% \\ +% skiptwo +% & As pre the previous option, but two lines are skipped. +% \\ +% skipnone +% & Do not skip any lines; this option overrides any package-level skip +% setting. +% \\ +% hideproblems +% & Do not display an error message within the document when compilation +% fails or succeeds unexpectedly. +% \\ +% showproblems +% & Display an error message within the document when compilation fails or +% succeeds unexpectedly. +% This is the default behaviour unless the |hideproblems| package option was +% set. +% \\ +% \end{longtable} +% +% The results of compiling the code of a |chklisting| environment are made +% available in the following macros until the next |chklisting| which will +% redefine them. +% \begin{description} +% +% \item[\texttt{\string\chklistingcmd}] +% \DescribeMacro{\chklistingcmd} +% contains an idealised version of the command line used to compile the code +% sample. +% It includes the |prompt|, the basename of |compiler|, and |lastflags|, but +% not |compilerflags| or the list of included files. +% Furthermore, the |subdir| and serial number are removed from the filename +% of the code sample, which becomes simply \meta{prefix}|.|\meta{ext}. +% +% \item[\texttt{\string\chklistingmsg\marg{label}}] +% \DescribeMacro{\chklistingmsg}: inserts the verbatim text emitted by the +% compiler, provided compilation succeeded, for the |chklisting| +% environment labelled \meta{label}. +% When \meta{label} is left empty, the message for the last environment is +% inserted. +% It should not be used after environments marked |fail|. +% +% \item[\texttt{\string\chklistingerr\marg{label}}] +% \DescribeMacro{\chklistingerr}: inserts the verbatim text emitted by the +% compiler, provided compilation failed, for the |chklisting| environment +% labelled \meta{label}. +% When \meta{label} is left empty, the message for the last environment is +% inserted. +% It should only be used after environments marked |fail|. +% \end{description} +% +% \subsection{The \texttt{checklistings.sh} script}\label{sec:rvsh} +% +% Processing a document that uses the |checklistings| package produces a +% |.chkl| file containing compiler options and a list of source files +% together with their interdependencies. +% The |checklistings.sh| script processes |.chkl| files by executing the +% specified compiler against each listed source file +% \meta{subdir}|/|\meta{prefix}\meta{n}|.|\meta{ext} and copying the +% results---the command-line used, whether it succeeded or failed, the +% messages on |stdout|, and the messages on |stderr|---into a corresponding +% file, \meta{subdir}|/|\meta{prefix}\meta{n}|.tex|, for inclusion in the +% original document. +% +% The \verb|checklistings.sh| script is written for the Bourne shell +% (\verb|sh|). +% It takes a list of |.chkl| files as arguments (with or without the +% exentions), but if none are given it processes all such files in the +% current working directory. +% +% The compilation options specified within a \LaTeX{} source file, see +% \refsec{compileconfig}, can be manually overridden by processing a |.chkl| +% file, before any others, containing a `|lock|' directive, for example: +% |lock compiler=/usr/local/bin/ocamlc|. +% This feature is useful when working with others to develop the compiler +% being documented. +% +% \StopEventually{} +\makeatletter +% +% \section{Remarks} +% +% \subsection{Known limitations} +% +% The package and script have some known limitations. +% \begin{itemize} +% +% \item +% Line numbers in error messages may not correspond correctly with the line +% numbers of sample files, due to either the |skip*| options, or because of +% lines added to import code. +% +% \item +% The system has been designed to work with ML-style compilers. +% It has not been tested with other compilers and interpreters. +% Please contact \url{tim@tbrk.org} if you would like to support other +% systems. +% Patches are most welcome, but the intent is to keep this package +% relatively simple rather than to try to do everything. +% +% \item +% Multiple languages in a single document are not supported. +% +% \item +% Care must be taken when using |checklistings| with the overlays of the +% Beamer package. +% In particular, |chklisting| environment commands are to be avoided within +% commands that completely omit material from slides, like |only|, |alt|, or +% |temporal|, or with `closed' overlay specifications, like |2| or |1-3|. +% As these commands do not execute the material, the environment sequence +% numbers do not increase monotonically, and the compilation results may not +% be properly synchronized with the verbatim text. +% Commands that only hide material, or that introduce it successively, like +% |uncover| or |visible|, or `open' overlay specifications, like |2-|, +% should function as expected. +% +% \end{itemize} +% +% \section{Implementation} +% +% All internal macros have names of the form |\CHKL@|\meta{name}. +% +% \begin{macro}{\chklisting} +% Generate the sequence of source code identifiers used in per-environment +% filenames and to manage dependencies. +% If |beamer| is being used, reset the counter on each overlay to avoid +% generating multiple output files for the same program. +% \begin{macrocode} +\newcounter{chklisting} +\ifdefined\resetcounteronoverlays +\resetcounteronoverlays{chklisting} +\fi +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ifCHKL@fileexists} +% An internal boolean variable for remembering whether an input |.tex| file, +% corresponding to the compilation of source code, was found. +% \begin{macrocode} +\newif\ifCHKL@fileexists +% \end{macrocode} +% \end{macro} +% +% \subsection{Package Options} +% +% The package options are processed using the |kvoptions| package. +% +% \begin{macro}{\CHKL@pkg@verbopts} +% This list accumulates package-level options for the |verbatim| +% environments. +% \begin{macrocode} +\def\CHKL@pkg@verbopts{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CHKL@pkg@globalskip} +% Defines the number of lines to be skipped when displaying a code sample as +% defined by the global options |skipone| and |skiptwo|. +% \begin{macrocode} +\def\CHKL@pkg@globalskip{0} +% \end{macrocode} +% \end{macro} +% +% \noindent +% Declare the package options and their default values: + +% \begin{macrocode} +\DeclareBoolOption{withresult} +\DeclareComplementaryOption{withoutresult}{withresult} +\DeclareBoolOption[true]{showproblems} +\DeclareComplementaryOption{hideproblems}{showproblems} +\DeclareVoidOption{skipone} + {\edef\CHKL@pkg@globalskip{1}% + \edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,firstline=2}} +\DeclareVoidOption{skiptwo} + {\edef\CHKL@pkg@globalskip{2}% + \edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,firstline=3}} +\DeclareDefaultOption + {\edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,\CurrentOption}} +\DeclareStringOption[]{codestyle} +\DeclareStringOption[formatcom=\em]{msgstyle} +\DeclareStringOption[formatcom=\em]{errstyle} +\DeclareStringOption{codelst} +\DeclareStringOption{msglst} +\DeclareStringOption{errlst} +\DeclareStringOption{emptyoption} +\DeclareStringOption[.]{subdir} +\DeclareStringOption[chklisting]{prefix} +\DeclareStringOption[.ml]{ext} +\DeclareStringOption[\#]{prompt} +\DeclareStringOption[ocamlc]{compiler} +\DeclareStringOption{compilerflags} +\DeclareStringOption[-i]{lastflags} +\DeclareStringOption[open]{includecmd} +\DeclareStringOption[]{html} +\ProcessKeyvalOptions* +% \end{macrocode} +% +% \begin{macro}{\checklistings} +% This macro offers another way of setting package options with the +% advantage that values are not expanded. +% \begin{macrocode} +\def\checklistings{\kvsetkeys{CHKL}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Logging Files to be Processed} +% +% Several definitions and commands are used to create and write to the +% |.chkl| file. +% +% \begin{macro}{\CHKL@samplefile} +% The file generated when a \LaTeX{} document that uses the |checklistings| +% package is processed. +% \begin{macrocode} +\newwrite\CHKL@samplefile +\openout\CHKL@samplefile=\jobname.chkl +\AtEndDocument{\closeout\CHKL@samplefile} +% \end{macrocode} +% \end{macro} +% +% Package options are logged to the file. +% \begin{macrocode} +\write\CHKL@samplefile{subdir=\CHKL@subdir/} +\write\CHKL@samplefile{prefix=\CHKL@prefix} +\write\CHKL@samplefile{ext=\CHKL@ext} +\write\CHKL@samplefile{compiler=\CHKL@compiler} +\write\CHKL@samplefile{compilerflags=\CHKL@compilerflags} +\write\CHKL@samplefile{lastflags=\CHKL@lastflags} +\write\CHKL@samplefile{includecmd=\CHKL@includecmd} +\write\CHKL@samplefile{htmlfilter=\CHKL@html} +% \end{macrocode} +% +% \begin{macro}{\CHKL@logsample} +% An entry is logged for each |chklisting| environment. +% It contains the sequence number for the example, followed by a colon, an +% ordered list of other sample files to import, and the page and line +% numbers (to include in error messages). +% \begin{macrocode} +\DeclareRobustCommand{\CHKL@logsample}[2]{% + \edef\CHKL@tolog{#1:#2 [page=\noexpand\thepage] [line=\the\inputlineno]}% + \expandafter\write\expandafter\CHKL@samplefile\expandafter{\CHKL@tolog}% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Insertion of Compilation Results} +% +% Several macros are defined for use by the |checklistings.sh| script (and +% any similar program). +% These macros are called from within the |.tex| file generated for each +% |chklisting| environment. +% +% \begin{macro}{\ifchklisting} +% A successful compilation is signalled by |\chklistingtrue|, and a failed +% compilation by |\chklistingfalse|. +% \begin{macrocode} +\newif\ifchklisting +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\setchklistingcmd} +% The command used to compile a sample is recorded by |\setchklistingcmd| +% which (re)defines the internal |\CHKL@prompt| value. +% \begin{macrocode} +\DeclareRobustCommand{\setchklistingcmd}[1]{% + \global\def\chklistingcmd{\emph{\CHKL@prompt{#1}}}} +% \end{macrocode} +% \end{macro} + +% \begin{environment}{ChkListingMsg} +% Normal compiler messages (written on |stdout|) should be communicated +% between |\begin{ChkListingMsg}| and |\end{ChkListingMsg}|. +% This verbatim text is saved using the |SaveVerbatim| feature of +% |fancyvrb|. +% \begin{macrocode} +\def\ChkListingMsg{\FV@Environment{}{ChkListingMsg}} +\def\FVB@ChkListingMsg{\FVB@SaveVerbatim{ChkListingMsg}} +\let\FVE@ChkListingMsg\FVE@SaveVerbatim +\DefineVerbatimEnvironment{ChkListingMsg}{ChkListingMsg}{} +% \end{macrocode} +% \end{environment} + +% \begin{environment}{ChkListingErr} +% Compiler error messages (usually written on |stderr|) should be +% communicated between |\begin{ChkListingErr}| and |\end{ChkListingErr}|. +% This verbatim text is saved using the |SaveVerbatim| feature of +% |fancyvrb|. +% \begin{macrocode} +\def\ChkListingErr{\FV@Environment{}{ChkListingErr}} +\def\FVB@ChkListingErr{\FVB@SaveVerbatim{ChkListingErr}} +\let\FVE@ChkListingErr\FVE@SaveVerbatim +\DefineVerbatimEnvironment{ChkListingErr}{ChkListingErr}{} +% \end{macrocode} +% \end{environment} + +% \begin{macro}{\chklistingfile} +% This is the filename used by |checklistings.sh| to refer to the file +% containing sample code when |\setchklistingcmd| is called. +% \begin{macrocode} +\DeclareRobustCommand{\chklistingfile}{\CHKL@prefix\CHKL@ext} +% \end{macrocode} +% \end{macro} +% +% \subsection{Main Environment} +% +% Several auxiliary definitions are needed to track per-environment +% configuration options. +% +% \begin{macro}{\ifCHKL@shouldfail} +% This boolean variable records whether sample code is expected to fail. +% \begin{macrocode} +\newif\ifCHKL@shouldfail +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ifCHKL@showcode} +% This boolean variable records whether the compilation result should be +% shown. +% \begin{macrocode} +\newif\ifCHKL@showcode +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CHKL@skip} +% Defines the number of lines to be skipped when displaying a code sample. +% It defaults to the value of |\CHKL@pkg@globalskip|, but may be altered by +% the environment options |skipone| and |skiptwo|. +% This value is only used to generate the |skip=| field in the |.chkl| file. +% The actual skipping is done by the |firstline| option of |verbopts|. +% \begin{macrocode} +\def\CHKL@skip{0} +% \end{macrocode} +% \end{macro} +% +% The |keyval| package\footnote{\url{http://www.ctan.org/pkg/keyval}} is +% used to parse environment options. +% The following macros setup parameters used by the |chklisting| +% environment. +% +% \begin{macro}{\CHKL@continue} +% \begin{macro}{\CHKL@precontinue} +% These two macros hold lists of source code identifiers: +% |\CHKL@precontinue| tracks the dependencies of the previous |chklisting| +% environment and |\CHKL@continue| tracks those of the current one. +% The |continue| option appends the previous dependencies onto the list of +% current ones. +% The dependencies used at each labelled environment are remembered in +% |\RBRB@deps|\meta{label}. +% The |include| option causes them to be added to the list of current +% dependencies. +% +% \begin{macrocode} +\edef\CHKL@precontinue{} +\define@key{CHKL@envkeys}{continue}[]{\edef\CHKL@continue{\CHKL@precontinue}} +\define@key{CHKL@envkeys}{include}{% + \edef\CHKL@continue{\CHKL@continue\space\@ifundefined{CHKL@deps@#1}% + {#1}{\csname CHKL@deps@#1\endcsname}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +\define@key{CHKL@envkeys}{fail}[]{\CHKL@shouldfailtrue} +\define@key{CHKL@envkeys}{label}{\edef\CHKL@label{#1}} +\define@key{CHKL@envkeys}{skipnone}[]{% + \edef\CHKL@skip{0}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=1}} +\define@key{CHKL@envkeys}{skipone}[]{% + \edef\CHKL@skip{1}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=2}} +\define@key{CHKL@envkeys}{skiptwo}[]{% + \edef\CHKL@skip{2}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=3}} +\define@key{CHKL@envkeys}{hide}[]{\CHKL@showcodefalse} +\define@key{CHKL@envkeys}{withresult}[]{\CHKL@withresulttrue} +\define@key{CHKL@envkeys}{withoutresult}[]{\CHKL@withresultfalse} +\define@key{CHKL@envkeys}{showproblems}[]{\CHKL@showproblemstrue} +\define@key{CHKL@envkeys}{hideproblems}[]{\CHKL@showproblemsfalse} +% \end{macrocode} +% +% \begin{macro}{\chklistingmsg} +% This macro takes a single argument \meta{label}. +% It first configures the |listings| and |fancyvrb| packages with the +% current display options. +% It then checks the |fancyvrb| saved text namespace +% (`\texttt{FV@SV@\ldots}') for an entry named `\texttt{\ldots +% CHKL@MSG@\meta{label}}'. +% If found, the associated verbatim text is inserted via the |\UseVerbatim| +% feature of |fancyvrb|, otherwise an error message is inserted. +% In the latter case, we prefer not to fail outright, because the user may +% not yet have had the chance to run the compiler on the extracted code, in +% which case the log will already contain warnings from |chklisting|. +% By convention, the |chklisting| environment creates an entry for the +% empty label (`\texttt{FV@SV@CHKL@MSG@}') when compilation succeeds. +% \begin{macrocode} +\DeclareRobustCommand{\chklistingmsg}[1]{ + \bgroup% + \ifx\CHKL@msglst\CHKL@emptyoption\else + \expandafter\lstset\expandafter{\CHKL@msglst,fancyvrb=true}\fi% + \@ifundefined{FV@SV@CHKL@MSG@#1} + {\def\@tempa{#1} + \ifx\@tempa\empty + \CHKL@none + \else + $\langle$No message found for the label `#1'!$\rangle$ + \fi} + {\expandafter\UseVerbatim\expandafter[\CHKL@msgstyle]{CHKL@MSG@#1}}% + \egroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chklistingerr} +% This macro is essentially the same as the previous one---only that the +% substring `\texttt{ERR}' is used instead of `\texttt{MSG}'. +% \begin{macrocode} +\DeclareRobustCommand{\chklistingerr}[1]{ + \bgroup% + \ifx\CHKL@errlst\CHKL@emptyoption\else + \expandafter\lstset\expandafter{\CHKL@errlst,fancyvrb=true}\fi% + \@ifundefined{FV@SV@CHKL@ERR@#1} + {\def\@tempa{#1} + \ifx\@tempa\empty + \CHKL@none + \else + $\langle$No message found for the label `#1'!$\rangle$ + \fi} + {\expandafter\UseVerbatim\expandafter[\CHKL@errstyle]{CHKL@ERR@#1}}% + \egroup} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{chklisting} +% This is the main environment for including source code. +% This macro works in two parts: +% \begin{enumerate} +% \item +% It uses the listings package to write the code to a file, +% \item +% It either loads the corresponding |.tex| file or logs an error message. +% \end{enumerate} +% +% The |listings| package allows the definition of custom verbatim +% environments. +% This one has a single argument (a list of |keyval| options). +% +% \begin{macrocode} +\lstnewenvironment{chklisting}[1][] + {% +% \end{macrocode} +% Set default parameter values before invoking |\setkeys|: +% \begin{macrocode} + \CHKL@shouldfailfalse% + \CHKL@showcodetrue% + \let\CHKL@label\@undefined% + \edef\CHKL@continue{}% + \def\CHKL@skip{\CHKL@pkg@globalskip}% + \let\CHKL@verbopts\CHKL@pkg@verbopts% + \def\@currentlabel{\thechklisting}% + \setkeys{CHKL@envkeys}{#1}% +% \end{macrocode} +% +% Log an entry to the |.chkl| file: +% +% \begin{macrocode} + \CHKL@logsample{\arabic{chklisting}}{\CHKL@continue% + \space\ifnum\CHKL@skip>0[skip=\CHKL@skip]\fi% + \ifCHKL@shouldfail\space[fail]\fi}% +% \end{macrocode} +% +% Update |\CHKL@precontinue| for the next source code block, and, if a label +% was defined, add an |\CHKL@deps@|\meta{label} entry. +% +% \begin{macrocode} + \global\edef\CHKL@precontinue{\CHKL@continue\space\arabic{chklisting}}% + \@ifundefined{CHKL@label}{}{% + \global\expandafter\edef\csname CHKL@deps@\CHKL@label\endcsname{\CHKL@precontinue}}% +% \end{macrocode} +% +% A file will be created in the |\CHKL@subdir| subdirectory, with the name +% |\CHKL@prefix| followed by the value of the |chklisting| counter, padded +% out with zeroes to four digits, and the extension |\RBRB@ext|. +% +% \begin{macrocode} + \edef\CHKL@num{% + \ifnum\value{chklisting}<1000 0\fi + \ifnum\value{chklisting}<100 0\fi + \ifnum\value{chklisting}<10 0\fi + \arabic{chklisting}}% + \stepcounter{chklisting}% + \def\CHKL@file{\CHKL@subdir/\CHKL@prefix\CHKL@num}% +% \end{macrocode} +% +% Clear the definitions used to return information about the compilation +% run, and close the environment by opening a file, using the |listings| +% package, into which to write the ensuing contents. +% +% \begin{macrocode} + \global\let\chklistingcmd\@undefined% + \global\let\FV@SV@ChkListingMsg\@undefined% + \global\let\FV@SV@ChkListingErr\@undefined% + \chklistingtrue% + \setbox\@tempboxa\hbox\bgroup% + \lst@BeginWriteFile{\CHKL@file\CHKL@ext}% + } +% \end{macrocode} +% +% Start closing the environment by closing the previously opened file and +% group. +% +% \begin{macrocode} + {% + \lst@EndWriteFile% + \egroup% +% \end{macrocode} +% +% If |hide| is not active, apply |\CHKL@verbopts| and reload the newly +% created file. +% +% \begin{macrocode} + \ifCHKL@showcode% + \bgroup% + \ifx\CHKL@codelst\CHKL@emptyoption\else% + \expandafter\lstset\expandafter{\CHKL@codelst,fancyvrb=true}% + \fi% + \expandafter\fvset\expandafter{\CHKL@verbopts}% + \expandafter\VerbatimInput\expandafter[\CHKL@codestyle]{\CHKL@file\CHKL@ext}% + \egroup% + \fi% +% \end{macrocode} +% +% Check whether a corresponding |.tex| file was created: +% +% \begin{macrocode} + \global\edef\CHKL@none{$\langle$Cannot load \CHKL@file.tex!$\rangle$}% + \InputIfFileExists{\CHKL@file.tex}{\CHKL@fileexiststrue}{\CHKL@fileexistsfalse}% +% \end{macrocode} +% +% If the |.tex| file was loaded successfully, create `unlabelled' saved +% verbatim environments for the message and error texts. +% These are exploited, respectively, by the |\chklistingmsg| and +% |\chklistingerr| macros. +% +% \begin{macrocode} + \ifCHKL@fileexists% + \@ifundefined{FV@SV@ChkListingMsg}% + {}{\global\let\FV@SV@CHKL@MSG@=\FV@SV@ChkListingMsg}% + \@ifundefined{FV@SV@ChkListingErr}% + {}{\global\let\FV@SV@CHKL@ERR@=\FV@SV@ChkListingErr}% +% \end{macrocode} +% +% Then, if compilation failed and the |fail| option was not active, or if +% compilation succeeded and the |fail| option is active, log a warning +% message and, if errors are not being ignored, include details in the +% document. +% Otherwise, if |withresult| was given, expand either |\chklistingerr| or +% |\chklistingmsg|. +% +% \begin{macrocode} + \ifCHKL@shouldfail% + \ifchklisting% + \PackageWarning{checklistings}% + {Compilation of \CHKL@file\CHKL@ext\space should have failed}% + \ifCHKL@showproblems% + \UseVerbatim[frame=single, + label=Unexpected success, + rulecolor=\color{red}]{ChkListingMsg}% + \fi% + \else% + \ifCHKL@withresult% + {\setlength{\partopsep}{0em}\chklistingerr{}}% + \fi% + \fi% + \else% + \ifchklisting% + \ifCHKL@withresult% + {%\vspace{\dimexpr-2\topsep-2\partopsep+.5em\relax}% + \setlength{\partopsep}{0em}\chklistingmsg{}}% + \fi% + \else% + \PackageWarning{checklistings}% + {Compilation of \CHKL@file\CHKL@ext\space should not have failed}% + \ifCHKL@showproblems% + \UseVerbatim[frame=single, + label=Unexpected failure, + rulecolor=\color{red}]{ChkListingErr}% + \fi% + \fi% + \fi% + \else% +% \end{macrocode} +% +% If the |.tex| file was not loaded successfully, clear the +% |\chklistingcmd| macros, and the `unlabelled' saved verbatim environments +% for the message and error results. +% +% \begin{macrocode} + \PackageWarning{checklistings}{Cannot load \CHKL@file.tex}% + \global\let\chklistingcmd\CHKL@none% + \global\let\FV@SV@CHKL@MSG@\@undefined% + \global\let\FV@SV@CHKL@ERR@\@undefined% + \fi% +% If this environment is labelled, create persistent references to the saved +% verbatim environments for the message and error results. +% These are exploited, respectively, by the |\chklistingmsg| and +% |\chklistingerr| macros when their \meta{label} argument is not empty. +% + \@ifundefined{CHKL@label}{}{% + \global\expandafter\let% + \csname FV@SV@CHKL@MSG@\CHKL@label\endcsname=\FV@SV@CHKL@MSG@% + \global\expandafter\let% + \csname FV@SV@CHKL@ERR@\CHKL@label\endcsname=\FV@SV@CHKL@ERR@% + }% + }% +% \end{macrocode} +% \end{environment} +% +\makeatother +\clearpage +% \Finale +\endinput diff --git a/Master/texmf-dist/source/latex/checklistings/checklistings.ins b/Master/texmf-dist/source/latex/checklistings/checklistings.ins new file mode 100644 index 00000000000..eaf454782da --- /dev/null +++ b/Master/texmf-dist/source/latex/checklistings/checklistings.ins @@ -0,0 +1,57 @@ +%% +%% Copyright (C) 2014 by Timothy Bourke <tim@tbrk.org> +%% and Marc Pouzet <pouzet@ens.fr> +%% +%% This file may be distributed and/or modified under the conditions of +%% the LaTeX Project Public License, either version 1.2 of this license +%% or (at your option) any later version. The latest version of this +%% license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.2 or later is part of all distributions of LaTeX version +%% 1999/12/01 or later. +%% + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/checklistings} + +\preamble + +This is a generated file. + +Copyright (C) 2015 by Timothy Bourke <tim@tbrk.org> + and Marc Pouzet <pouzet@ens.fr> + +This file may be distributed and/or modified under the conditions of +the LaTeX Project Public License, either version 1.2 of this license +or (at your option) any later version. The latest version of this +license is in: + + http://www.latex-project.org/lppl.txt + +and version 1.2 or later is part of all distributions of LaTeX version +1999/12/01 or later. + +\endpreamble + +\generate{\file{checklistings.sty}{\from{checklistings.dtx}{package}}} + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* checklistings.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file *} +\Msg{* checklistings.dtx through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile diff --git a/Master/texmf-dist/tex/latex/checklistings/checklistings.sty b/Master/texmf-dist/tex/latex/checklistings/checklistings.sty new file mode 100644 index 00000000000..35ce3a30794 --- /dev/null +++ b/Master/texmf-dist/tex/latex/checklistings/checklistings.sty @@ -0,0 +1,249 @@ +%% +%% This is file `checklistings.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% checklistings.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% Copyright (C) 2015 by Timothy Bourke <tim@tbrk.org> +%% and Marc Pouzet <pouzet@ens.fr> +%% +%% This file may be distributed and/or modified under the conditions of +%% the LaTeX Project Public License, either version 1.2 of this license +%% or (at your option) any later version. The latest version of this +%% license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.2 or later is part of all distributions of LaTeX version +%% 1999/12/01 or later. +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{checklistings} + [2015/09/01 v1.0 compile code samples and insert the results] +\RequirePackage{keyval} +\RequirePackage{kvoptions} +\RequirePackage{fancyvrb} +\RequirePackage{color} +\RequirePackage{listings} +\makeatletter +\lst@RequireAspects{writefile} +\SetupKeyvalOptions{family=CHKL,prefix=CHKL@} +\makeatother + +\makeatletter +\newcounter{chklisting} +\ifdefined\resetcounteronoverlays +\resetcounteronoverlays{chklisting} +\fi +\newif\ifCHKL@fileexists +\def\CHKL@pkg@verbopts{} +\def\CHKL@pkg@globalskip{0} + +\DeclareBoolOption{withresult} +\DeclareComplementaryOption{withoutresult}{withresult} +\DeclareBoolOption[true]{showproblems} +\DeclareComplementaryOption{hideproblems}{showproblems} +\DeclareVoidOption{skipone} + {\edef\CHKL@pkg@globalskip{1}% + \edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,firstline=2}} +\DeclareVoidOption{skiptwo} + {\edef\CHKL@pkg@globalskip{2}% + \edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,firstline=3}} +\DeclareDefaultOption + {\edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,\CurrentOption}} +\DeclareStringOption[]{codestyle} +\DeclareStringOption[formatcom=\em]{msgstyle} +\DeclareStringOption[formatcom=\em]{errstyle} +\DeclareStringOption{codelst} +\DeclareStringOption{msglst} +\DeclareStringOption{errlst} +\DeclareStringOption{emptyoption} +\DeclareStringOption[.]{subdir} +\DeclareStringOption[chklisting]{prefix} +\DeclareStringOption[.ml]{ext} +\DeclareStringOption[\#]{prompt} +\DeclareStringOption[ocamlc]{compiler} +\DeclareStringOption{compilerflags} +\DeclareStringOption[-i]{lastflags} +\DeclareStringOption[open]{includecmd} +\DeclareStringOption[]{html} +\ProcessKeyvalOptions* +\def\checklistings{\kvsetkeys{CHKL}} +\newwrite\CHKL@samplefile +\openout\CHKL@samplefile=\jobname.chkl +\AtEndDocument{\closeout\CHKL@samplefile} +\write\CHKL@samplefile{subdir=\CHKL@subdir/} +\write\CHKL@samplefile{prefix=\CHKL@prefix} +\write\CHKL@samplefile{ext=\CHKL@ext} +\write\CHKL@samplefile{compiler=\CHKL@compiler} +\write\CHKL@samplefile{compilerflags=\CHKL@compilerflags} +\write\CHKL@samplefile{lastflags=\CHKL@lastflags} +\write\CHKL@samplefile{includecmd=\CHKL@includecmd} +\write\CHKL@samplefile{htmlfilter=\CHKL@html} +\DeclareRobustCommand{\CHKL@logsample}[2]{% + \edef\CHKL@tolog{#1:#2 [page=\noexpand\thepage] [line=\the\inputlineno]}% + \expandafter\write\expandafter\CHKL@samplefile\expandafter{\CHKL@tolog}% +} +\newif\ifchklisting +\DeclareRobustCommand{\setchklistingcmd}[1]{% + \global\def\chklistingcmd{\emph{\CHKL@prompt{#1}}}} + +\def\ChkListingMsg{\FV@Environment{}{ChkListingMsg}} +\def\FVB@ChkListingMsg{\FVB@SaveVerbatim{ChkListingMsg}} +\let\FVE@ChkListingMsg\FVE@SaveVerbatim +\DefineVerbatimEnvironment{ChkListingMsg}{ChkListingMsg}{} + +\def\ChkListingErr{\FV@Environment{}{ChkListingErr}} +\def\FVB@ChkListingErr{\FVB@SaveVerbatim{ChkListingErr}} +\let\FVE@ChkListingErr\FVE@SaveVerbatim +\DefineVerbatimEnvironment{ChkListingErr}{ChkListingErr}{} + +\DeclareRobustCommand{\chklistingfile}{\CHKL@prefix\CHKL@ext} +\newif\ifCHKL@shouldfail +\newif\ifCHKL@showcode +\def\CHKL@skip{0} +\edef\CHKL@precontinue{} +\define@key{CHKL@envkeys}{continue}[]{\edef\CHKL@continue{\CHKL@precontinue}} +\define@key{CHKL@envkeys}{include}{% + \edef\CHKL@continue{\CHKL@continue\space\@ifundefined{CHKL@deps@#1}% + {#1}{\csname CHKL@deps@#1\endcsname}}} +\define@key{CHKL@envkeys}{fail}[]{\CHKL@shouldfailtrue} +\define@key{CHKL@envkeys}{label}{\edef\CHKL@label{#1}} +\define@key{CHKL@envkeys}{skipnone}[]{% + \edef\CHKL@skip{0}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=1}} +\define@key{CHKL@envkeys}{skipone}[]{% + \edef\CHKL@skip{1}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=2}} +\define@key{CHKL@envkeys}{skiptwo}[]{% + \edef\CHKL@skip{2}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=3}} +\define@key{CHKL@envkeys}{hide}[]{\CHKL@showcodefalse} +\define@key{CHKL@envkeys}{withresult}[]{\CHKL@withresulttrue} +\define@key{CHKL@envkeys}{withoutresult}[]{\CHKL@withresultfalse} +\define@key{CHKL@envkeys}{showproblems}[]{\CHKL@showproblemstrue} +\define@key{CHKL@envkeys}{hideproblems}[]{\CHKL@showproblemsfalse} +\DeclareRobustCommand{\chklistingmsg}[1]{ + \bgroup% + \ifx\CHKL@msglst\CHKL@emptyoption\else + \expandafter\lstset\expandafter{\CHKL@msglst,fancyvrb=true}\fi% + \@ifundefined{FV@SV@CHKL@MSG@#1} + {\def\@tempa{#1} + \ifx\@tempa\empty + \CHKL@none + \else + $\langle$No message found for the label `#1'!$\rangle$ + \fi} + {\expandafter\UseVerbatim\expandafter[\CHKL@msgstyle]{CHKL@MSG@#1}}% + \egroup} +\DeclareRobustCommand{\chklistingerr}[1]{ + \bgroup% + \ifx\CHKL@errlst\CHKL@emptyoption\else + \expandafter\lstset\expandafter{\CHKL@errlst,fancyvrb=true}\fi% + \@ifundefined{FV@SV@CHKL@ERR@#1} + {\def\@tempa{#1} + \ifx\@tempa\empty + \CHKL@none + \else + $\langle$No message found for the label `#1'!$\rangle$ + \fi} + {\expandafter\UseVerbatim\expandafter[\CHKL@errstyle]{CHKL@ERR@#1}}% + \egroup} +\lstnewenvironment{chklisting}[1][] + {% + \CHKL@shouldfailfalse% + \CHKL@showcodetrue% + \let\CHKL@label\@undefined% + \edef\CHKL@continue{}% + \def\CHKL@skip{\CHKL@pkg@globalskip}% + \let\CHKL@verbopts\CHKL@pkg@verbopts% + \def\@currentlabel{\thechklisting}% + \setkeys{CHKL@envkeys}{#1}% + \CHKL@logsample{\arabic{chklisting}}{\CHKL@continue% + \space\ifnum\CHKL@skip>0[skip=\CHKL@skip]\fi% + \ifCHKL@shouldfail\space[fail]\fi}% + \global\edef\CHKL@precontinue{\CHKL@continue\space\arabic{chklisting}}% + \@ifundefined{CHKL@label}{}{% + \global\expandafter\edef\csname CHKL@deps@\CHKL@label\endcsname{\CHKL@precontinue}}% + \edef\CHKL@num{% + \ifnum\value{chklisting}<1000 0\fi + \ifnum\value{chklisting}<100 0\fi + \ifnum\value{chklisting}<10 0\fi + \arabic{chklisting}}% + \stepcounter{chklisting}% + \def\CHKL@file{\CHKL@subdir/\CHKL@prefix\CHKL@num}% + \global\let\chklistingcmd\@undefined% + \global\let\FV@SV@ChkListingMsg\@undefined% + \global\let\FV@SV@ChkListingErr\@undefined% + \chklistingtrue% + \setbox\@tempboxa\hbox\bgroup% + \lst@BeginWriteFile{\CHKL@file\CHKL@ext}% + } + {% + \lst@EndWriteFile% + \egroup% + \ifCHKL@showcode% + \bgroup% + \ifx\CHKL@codelst\CHKL@emptyoption\else% + \expandafter\lstset\expandafter{\CHKL@codelst,fancyvrb=true}% + \fi% + \expandafter\fvset\expandafter{\CHKL@verbopts}% + \expandafter\VerbatimInput\expandafter[\CHKL@codestyle]{\CHKL@file\CHKL@ext}% + \egroup% + \fi% + \global\edef\CHKL@none{$\langle$Cannot load \CHKL@file.tex!$\rangle$}% + \InputIfFileExists{\CHKL@file.tex}{\CHKL@fileexiststrue}{\CHKL@fileexistsfalse}% + \ifCHKL@fileexists% + \@ifundefined{FV@SV@ChkListingMsg}% + {}{\global\let\FV@SV@CHKL@MSG@=\FV@SV@ChkListingMsg}% + \@ifundefined{FV@SV@ChkListingErr}% + {}{\global\let\FV@SV@CHKL@ERR@=\FV@SV@ChkListingErr}% + \ifCHKL@shouldfail% + \ifchklisting% + \PackageWarning{checklistings}% + {Compilation of \CHKL@file\CHKL@ext\space should have failed}% + \ifCHKL@showproblems% + \UseVerbatim[frame=single, + label=Unexpected success, + rulecolor=\color{red}]{ChkListingMsg}% + \fi% + \else% + \ifCHKL@withresult% + {\setlength{\partopsep}{0em}\chklistingerr{}}% + \fi% + \fi% + \else% + \ifchklisting% + \ifCHKL@withresult% + {%\vspace{\dimexpr-2\topsep-2\partopsep+.5em\relax}% + \setlength{\partopsep}{0em}\chklistingmsg{}}% + \fi% + \else% + \PackageWarning{checklistings}% + {Compilation of \CHKL@file\CHKL@ext\space should not have failed}% + \ifCHKL@showproblems% + \UseVerbatim[frame=single, + label=Unexpected failure, + rulecolor=\color{red}]{ChkListingErr}% + \fi% + \fi% + \fi% + \else% + \PackageWarning{checklistings}{Cannot load \CHKL@file.tex}% + \global\let\chklistingcmd\CHKL@none% + \global\let\FV@SV@CHKL@MSG@\@undefined% + \global\let\FV@SV@CHKL@ERR@\@undefined% + \fi% + \@ifundefined{CHKL@label}{}{% + \global\expandafter\let% + \csname FV@SV@CHKL@MSG@\CHKL@label\endcsname=\FV@SV@CHKL@MSG@% + \global\expandafter\let% + \csname FV@SV@CHKL@ERR@\CHKL@label\endcsname=\FV@SV@CHKL@ERR@% + }% + }% +\makeatother +\clearpage +\endinput +%% +%% End of file `checklistings.sty'. diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index df2be36bc1e..343862ec4ec 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -120,7 +120,7 @@ my @TLP_working = qw( cd cd-cover cdpbundl cell cellspace celtic censor cfr-initials cfr-lm changebar changelayout changepage changes chappg chapterfolder - chbibref checkcites chem-journal + chbibref checkcites checklistings chem-journal chemarrow chembst chemcompounds chemcono chemexec chemfig chemformula chemgreek chemmacros chemnum chemschemex chemstyle cherokee diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index 389d8b505e8..d269fb8b529 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -2614,6 +2614,7 @@ $standardttf = '\.ttf|\.TTC'; 'bibexport' => 'bibexport\.sh$', 'bundledoc' => '(arlatex|bundledoc)$', 'checkcites' => '\.lua$', + 'checklistings' => '\.sh$', 'cjk-gs-integrate' => '\.pl$', 'convbkmk' => '\.rb$', 'crossrefware' => '\.pl$', diff --git a/Master/tlpkg/tlpsrc/checklistings.tlpsrc b/Master/tlpkg/tlpsrc/checklistings.tlpsrc new file mode 100644 index 00000000000..dca338c719c --- /dev/null +++ b/Master/tlpkg/tlpsrc/checklistings.tlpsrc @@ -0,0 +1 @@ +binpattern f bin/${ARCH}/${PKGNAME} diff --git a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc index 1241e586095..0411ecc4eb6 100644 --- a/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-binextra.tlpsrc @@ -13,6 +13,7 @@ depend asymptote depend bibtex8 depend bibtexu depend bundledoc +depend checklistings depend chktex depend ctan_chk depend ctanify |