As @egreg recommended, the bashful
package is specifically designed for this. Quoting from the user manual:
...bashful provides a convenient interface to TEX’s primitive \write18
—the execution of shell com- mands from within your input files, also known as shell escape. Text between \bash
and \END
is executed by bash, a popular Unix command line interpreter. Various flags control whether the executed commands and their output show up in the printed document, and whether they are saved to files.
Although provisions are made for using shells other than bash, this package may not operate without modifications on Microsoft’s operating systems.
Note that this requires -shell-escape
option to be specified.
Here I have used only basic bash
commands. I suspect that you could do something similar with the Haskell interpreter.
The first line of the bash script file begins with a %
, so I started the listings form line 2, and left the first line blank. When you initiate the \bash
command, you provide a file name for the .sh
bash file and the output file. Then use lstinputlisting
to reincorporate the contents of that file back into the .tex
file.
\documentclass{standalone}
\usepackage{xcolor}
\usepackage{bashful}
\usepackage{listings}
\lstdefinestyle{BashInputStyle}{
language=bash,
firstline=2,% Supress the first line that begins with `%`
basicstyle=\small\sffamily,
numbers=left,
numberstyle=\tiny,
numbersep=3pt,
frame=tb,
columns=fullflexible,
backgroundcolor=\color{yellow!20},
linewidth=0.9\linewidth,
xleftmargin=0.1\linewidth
}
\lstdefinestyle{BashOutputStyle}{
basicstyle=\small\ttfamily,
numbers=none,
frame=tblr,
columns=fullflexible,
backgroundcolor=\color{blue!10},
linewidth=0.9\linewidth,
xleftmargin=0.1\linewidth
}
\begin{document}
\bash[verbose,scriptFile=hello.sh,stdoutFile=hello.tex]
echo "Hello World!"
echo "Today is" `date`
echo ""
echo "Disk usage is:"
df
\END
\par\noindent
Executing the following code in \textbf{bash}
\lstinputlisting[style=BashInputStyle]{hello.sh}
%
yields the following output:
\lstinputlisting[style=BashOutputStyle]{hello.tex}
\end{document}
I followed the same approach as in my answer to Can the listings package highlight by regexp?.
\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\makeatletter
% ``state variables''
\newif\ifincomment\incommentfalse
\newif\ifinstring\instringfalse
% language and style definition
\lstdefinestyle{mybash}
{%
language = bash,
basicstyle = \ttfamily,
keywordstyle = \color{blue},
}[keywords,strings,comments]
% --- patch to automatically highlight identifier starting by @
% (only outside strings and comments, though) ---
\lst@AddToHook{Output}{\@ddedToOutput}
\lst@AddToHook{Endgroup}{\incommentfalse\instringfalse}
% local variables
\newif\if@identifierStartsByAt@
\newcount\currentchar
\def\splitfirstchar#1{\@splitfirstchar#1\@nil}
\def\@splitfirstchar#1#2\@nil{\gdef\@testChar{#1}}
\def\@testChar%
{%
% copy the first token in \the\lst@token to \@testChar
\expandafter\splitfirstchar\expandafter{\the\lst@token}%
%
% reset switch
\@identifierStartsByAt@false
%
% equality test
\expandafter\ifnum\expandafter`\@testChar=`@%
\@identifierStartsByAt@true % if equality, set switch to true
\fi
%
% apply class style if not within string or comment
\if@identifierStartsByAt@
\ifincomment
\else
\ifinstring
\else
\def\lst@thestyle{\lst@keywordstyle}%
\fi
\fi
\fi
}
\let\@ddedToOutput\@testChar
\makeatother
\begin{document}
\begin{lstlisting}[style=mybash]{text.txt}
# This is an example
@Blueword(foo) @Blueword bar
\end{lstlisting}
\end{document}
Best Answer
One way to automatically apply the solutions form Highlight text in code listing while also keeping syntax highlighting around each
lstinline
is to redefine some of the internal macros from thelistings
package to include a\bh{}
at the beginning of the listing and a\eh{}
. To ensure that this only applies to inline listings, we useiftoggle
from theetoolbox
package to produce:Known Issues:
Code: