From 458ae81ef20dbea77877876c44a0de359afd55de Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 5 Sep 2015 22:16:03 +0000 Subject: checklistings (3sep15) git-svn-id: svn://tug.org/texlive/trunk@38300 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/checklistings/Makefile | 42 + .../texmf-dist/doc/latex/checklistings/README.md | 56 ++ .../doc/latex/checklistings/checklistings.hva | 188 ++++ .../doc/latex/checklistings/checklistings.pdf | Bin 0 -> 286631 bytes .../doc/latex/checklistings/example.html | 74 ++ .../texmf-dist/doc/latex/checklistings/example.pdf | Bin 0 -> 73949 bytes .../texmf-dist/doc/latex/checklistings/example.tex | 56 ++ .../scripts/checklistings/checklistings.sh | 446 ++++++++ .../source/latex/checklistings/checklistings.dtx | 1061 ++++++++++++++++++++ .../source/latex/checklistings/checklistings.ins | 57 ++ .../tex/latex/checklistings/checklistings.sty | 249 +++++ 11 files changed, 2229 insertions(+) create mode 100644 Master/texmf-dist/doc/latex/checklistings/Makefile create mode 100644 Master/texmf-dist/doc/latex/checklistings/README.md create mode 100644 Master/texmf-dist/doc/latex/checklistings/checklistings.hva create mode 100644 Master/texmf-dist/doc/latex/checklistings/checklistings.pdf create mode 100644 Master/texmf-dist/doc/latex/checklistings/example.html create mode 100644 Master/texmf-dist/doc/latex/checklistings/example.pdf create mode 100644 Master/texmf-dist/doc/latex/checklistings/example.tex create mode 100755 Master/texmf-dist/scripts/checklistings/checklistings.sh create mode 100644 Master/texmf-dist/source/latex/checklistings/checklistings.dtx create mode 100644 Master/texmf-dist/source/latex/checklistings/checklistings.ins create mode 100644 Master/texmf-dist/tex/latex/checklistings/checklistings.sty (limited to 'Master/texmf-dist') 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 +. 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 (*., *.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 new file mode 100644 index 00000000000..49f1aa917c9 Binary files /dev/null and b/Master/texmf-dist/doc/latex/checklistings/checklistings.pdf differ 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 @@ + + + + + + +example + + + +

Two simple declarations: +

let x = 3 +let f x = x + 1

and, after compilation with ocamlc -i example.ml, their types: +

val x : int +val f : int -> int

Then, building on these definitions: +

let y = f 3
val y : int

What about compiler error messages?: +

let z = 3 + "four"

They are also detected: +

File "example.ml", line 1, characters 12-18: +Error: This expression has type string but an expression was expected of type + int

We can continue on from earlier examples:

let z = f y
val z : int
+ + + +
This document was translated from LATEX by +HEVEA.
+ diff --git a/Master/texmf-dist/doc/latex/checklistings/example.pdf b/Master/texmf-dist/doc/latex/checklistings/example.pdf new file mode 100644 index 00000000000..37def76c622 Binary files /dev/null and b/Master/texmf-dist/doc/latex/checklistings/example.pdf differ 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 # +# Inria # +# École normale supérieure # +# # +# Marc Pouzet # +# Université Pierre et Marie Curie # +# École normale supérieure # +# Inria # +# + +## +# Configuration +SCRIPT=$(basename "$0") +SUFFIX=.chkl + +RED="" +BLUE="" +BLACK="" + +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 '
\n'	    > "$opath_html"
+	    $HTMLFILTER "$ipath"    >> "$opath_html"
+	    printf '
\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 +% and Marc Pouzet +% ------------------------------------------------------- +% +% 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} +% +%\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 +% +%<*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} +% +% \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 +% +% \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 +% +% \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 +% +% \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 +%% and Marc Pouzet +%% +%% 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 + and Marc Pouzet + +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 +%% and Marc Pouzet +%% +%% 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'. -- cgit v1.2.3