From f128ebd6f9643de2a990dcf9e92e8f6f3d8774bc Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 1 Mar 2011 23:47:19 +0000 Subject: new latex package bashful (1mar11) git-svn-id: svn://tug.org/texlive/trunk@21577 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/bashful/bashful.sty | 309 ++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 Master/texmf-dist/tex/latex/bashful/bashful.sty (limited to 'Master/texmf-dist/tex/latex/bashful') diff --git a/Master/texmf-dist/tex/latex/bashful/bashful.sty b/Master/texmf-dist/tex/latex/bashful/bashful.sty new file mode 100644 index 00000000000..326b999158f --- /dev/null +++ b/Master/texmf-dist/tex/latex/bashful/bashful.sty @@ -0,0 +1,309 @@ +% Copyright (C) 2011 by Yossi Gil yogi@cs.technion.ac.il +% --------------------------------------------------------------------------- +% This work may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3 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.3 or later is part of all +% distributions of LaTeX version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Yossi Gil. +% +% This work consists of the files bashful.tex and bashful.sty and the derived +% bashful.pdf + +\NeedsTeXFormat{LaTeX2e}% + +% Auxiliary identification information +\newcommand\date@bashful{2011/02/28}% +\newcommand\version@bashful{V 0.91}% +\newcommand\author@bashful{Yossi Gil}% +\newcommand\mail@bashful{yogi@cs.technion.ac.il}% +\newcommand\signature@bashful{% + bashful \version@bashful{} by + \author@bashful{} \mail@bashful +}% + +% Identify this package +\ProvidesPackage{bashful}[\date@bashful{} \signature@bashful: + Write and execute a bash script within LaTeX, with, or + without displaying the script and/or its output. +] +\PackageInfo{bashful}{This is bashful, \signature@bashful}% + +% Use listing to display bash scripts. +\RequirePackage{listings}% + % listings style for the script, can be redefined by client + \lstdefinestyle{bashfulList}{ + basicstyle=\ttfamily, + showstringspaces=false}% + % listings style for the stdoutFile, can be redefined by client + \lstdefinestyle{bashfulStdout}{ + basicstyle=\sl\ttfamily, + showstringspaces=false + }% + +% Use xkeyval for retrieving parameters +\RequirePackage{xkeyval}% + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Keys in alphabetical order: + %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % environment: String = \BL@environment: Which environment should we wrap the listings + \def\BL@environment{none@BL}% + \define@cmdkey{bashful}[BL@]{environment}{}% + \newenvironment{none@BL}{}{} % Default, empty environment for wrapping the listings + + % scriptFile: String = Where should the listed script be saved? + \def\BL@scriptFile{\jobname.lsh}% + \define@cmdkey{bashful}[BL@]{scriptFile}{}% + + % list: Boolean = \ifBL@list: Should we list the script we generate? + \define@boolkey{bashful}[BL@]{list}[true]{}% + + % prefix: String = \BL@prefix: What prefix should be printed before a listing. + \def\BL@prefix{\@percentchar\space}% + \define@cmdkey{bashful}[BL@]{prefix}{}% + + % shell: String = \BL@shell: Which shell should be used for execution? + \def\BL@shell{bash}% + \define@cmdkey{bashful}[BL@]{shell}{}% + + % scriptFile: String = \BL@scriptFile: Where should the script be saved? + \def\BL@scriptFile{\jobname.sh}% + \define@cmdkey{bashful}[BL@]{scriptFile}{}% + + % stderrFile: String = \BL@stderrFile: Where should the standard error be saved? + \def\BL@stderrFile{\jobname.stderr}% + \define@cmdkey{bashful}[BL@]{stderrFile}{}% + + % stdout: Boolean = \ifBL@stdout: Should we list the standard output? + \define@boolkey{bashful}[BL@]{stdout}[true]{}% + + % stdoutFile: String = \BL@stdoutFile: Where should the standard output be saved? + \def\BL@stdoutFile{\jobname.stdout}% + \define@cmdkey{bashful}[BL@]{stdoutFile}{}% + + % verbose: Boolean = \ifBL@verbose: Log every step we do + \define@boolkey{bashful}[BL@]{verbose}[true]{}% + +% \bash: the main command we define. It chains to \bashI which chains to +% \bashII, etc. +\begingroup + \catcode`\^^M\active% + \gdef\bash{% + \log@BL{Beginning a group so that all cat code changes are local}% + \begingroup% + \log@BL{Making \^\^M a true newline}% + \catcode`\^^M\active% + \def^^M{^^J}% + \log@BL{Checking for optional arguments}% + \@ifnextchar[\bashI{\bashI[]}% + }% +\endgroup + +% \bashI: Process the optional arguments and continue +\def\bashI[#1]{% + \setKeys@BL{#1}% + \bashII% And, continue processing. +}% + +% \bashII: Set category codes of all to special, and proceed. +\begingroup + \catcode`\^^M\active% + \gdef\bashII{% + \log@BL{bashII: Making ^^M a true new line}% + \catcode`\^^M\active% + \def^^M{^^J}% + \log@BL{bashII: Making all characters other}% + \let\do\@makeother% + \dospecials% + \bashIII% + }% +\endgroup + +% \bashIII: Consume all tokens until \END (but ignoring the preceding and +% terminating newline), and proceed. +\begingroup + \catcode`\@=0\relax + \catcode`\^^M\active + @catcode`@\=12@relax% + @gdef@bashIII^^M#1^^M\END{@bashIV{#1}}@relax% +@endgroup + +% \bashIV: Process the tokens by storing them in a script file, executing this +% file, listing it if required, and presenting the standard output if required. +\newcommand\bashIV[1]{% + \generateScriptFile@BL{#1}\relax + \executeScriptFile@BL + \checkStderr@BL + \listScript@BL{#1}\relax% + \listStdout@BL + \log@BL{Ending group so that all cat codes changes disappear}\relax% + \endgroup +}% + +\def\setKeys@BL#1{% + \log@BL{Processing key=val pairs in options string [#1]}\relax + \setkeys{bashful}{#1}% +}% + +% Store the list of tokens in the first argument into our script file +\newcommand\generateScriptFile@BL[1]{% + \storeToFile@BL{#1}{\BL@scriptFile}% +}% + +\newwrite\writer@BL +% Store the list of tokens in the first argument into the file given +% in the second argument +\newcommand\storeToFile@BL[2]{% + \log@BL{Creating file #2 :=^^J#1^^J}% + \immediate\openout\writer@BL#2 + \immediate\write\writer@BL{#1}% + \immediate\closeout\writer@BL +}% + +% Execute the content of our script file. +\newcommand\executeScriptFile@BL{% + \def\command@BL{\BL@shell\space\BL@scriptFile}% + \edef\command@BL{% + \BL@shell\space -c + "\command@BL \space > \BL@stdoutFile \space2> \BL@stderrFile \space + || echo '\command@BL' exit code was $? 2>>\BL@stderrFile"% + }% + \log@BL{Executing:^^J \command@BL}% + \immediate\write18{\command@BL}% +}% + +\newread\reader@BL +% Issue an error if stderr is not empty +\newcommand\checkStderr@BL{% + \log@BL{Examining \BL@stderrFile}% + \begingroup + \newif\ifErrorsFound@\ErrorsFound@false + \log@BL{Opening \BL@stderrFile}% + \openin\reader@BL=\BL@stderrFile\relax + \ifeof\reader@BL + \BL@verbosetrue + \log@BL{Strange... \BL@stderrFile{} does not exist (probably bashful bug)}% + \log@BL{Switching to verbose mode}% + \else + \log@BL{Reading first line of \BL@stderrFile}% + \catcode`\^^M=5 + \read\reader@BL to \firstErrorLine + \ifeof\reader@BL + \def\eoln{\par} + \ifx\firstErrorLine\eoln + \log@BL{File \BL@stderrFile\space is empty}% + \closein\reader@BL + \else + \log@BL{File \BL@stderrFile\space has one line [\firstErrorLine]}% + \ErrorsFound@true + \closein\reader@BL + \fi + \else + \log@BL{File \BL@stderrFile\space has two lines or more}% + \ErrorsFound@true + \closein\reader@BL + \fi + \fi + \ifErrorsFound@ + \log@BL{Issuing an error message since \BL@stderrFile\space was not empty}% + \let\please=\relax\let\examine=\relax\let\stderr=\relax + \errmessage{^^JError(s) executing \BL@scriptFile. Here is how + ^^Jfile \BL@stderrFile\space begins: + ^^J\firstErrorLine + ^^Jbut, you really ought to examine this file yourself} + \please + \examine + \stderr + \else + \log@BL{Proceeding as usual since \BL@stderrFile{} is empty}% + \fi + \endgroup +}% + +% List the content of the script file. +\newcommand\listScript@BL[1]{% + \ifBL@list{% + \log@BL{Prepending prefix [[\BL@prefix]] to generate \BL@scriptFile}% + \storeToFile@BL{\BL@prefix#1}{\BL@scriptFile}% + \forceLTR@BL + \fixPolyglossiaBug@BL + \log@BL{Invoking \noexpand\lstinputlisting to list \BL@scriptFile}% + \ifBL@stdout + % trim bottom + \beginWrappingEnvironment@BL + \lstinputlisting[style=bashfulList,belowskip=0pt]{\BL@scriptFile}% + \else + \beginWrappingEnvironment@BL + \lstinputlisting[style=bashfulList]{\BL@scriptFile}% + \endWrappingEnvironment@BL + \fi + }\else\relax\fi +}% + +\def\beginWrappingEnvironment@BL{% + \expandafter\csname\BL@environment\endcsname +}% + +\def\endWrappingEnvironment@BL{% + \expandafter\csname end\BL@environment\endcsname +}% + +% Display the standard output of the execution +\newcommand\listStdout@BL{% + \ifBL@stdout{% + \log@BL{Listing stdout file \BL@stdoutFile}% + \forceLTR@BL + \fixPolyglossiaBug@BL + \log@BL{Invoking \noexpand\lstinputlisting to list \BL@stdoutFile}% + \ifBL@list % trim top + \lstinputlisting[style=bashfulStdout,aboveskip=0pt]{\BL@stdoutFile}% + \endWrappingEnvironment@BL + \else + \beginWrappingEnvironment@BL + \lstinputlisting[style=bashfulStdout]{\BL@stdoutFile}% + \endWrappingEnvironment@BL + \fi + }\else\relax\fi +}% + +\newcommand\fixPolyglossiaBug@BL{% + \log@BL{Trying to fix a Polyglossia package bug}% + \ifdefined\ttfamilylatin + \log@BL{Replacing \noexpand\ttfamily with \noexpand\ttfamilylatin}% + \let\ttfamily=\ttfamilylatin + \log@BL{Replacing \noexpand\rmfamily with \noexpand\rmfamilylatin}% + \let\rmfamily=\rmfamilylatin + \log@BL{Replacing \noexpand\sffamily with \noexpand\sffamilylatin}% + \let\sffamily=\sffamilylatin + \log@BL{Replacing \noexpand\normalfont with \noexpand\normalfontlatin}% + \let\normalfont=\normalfontlatin + \else + \log@BL{Polyglossia package probably not loaded}% + \relax + \fi +}% + +\newcommand\forceLTR@BL{% + \log@BL{Making sure we are not in right-to-left mode}% + \ifdefined\setLTR + \log@BL{Command \noexpand\setLTR is defined, invoking it}% + \setLTR + \else + \log@BL{Command \noexpand\setLTR is not defined, we are probably LTR}% + \relax + \fi +}% + +\newcommand\log@BL[1]{% + \ifBL@verbose + \typeout{L\the\inputlineno: #1}% + \else + \relax + \fi +}% + -- cgit v1.2.3