My turn to try something:
\documentclass{minimal}
\usepackage{verbatim}
\usepackage{listings}
\usepackage{ted}
\newwrite\listinginput
\makeatletter
\def\newsubstitution{\begingroup\let\do\@makeother\dospecials\newsubstitution@}
\def\newsubstitution@||#1||<->||#2||{%
\endgroup
\expandafter\def\expandafter\subst@list\expandafter{\subst@list\Substitute*[\verbatim@line]{\the\verbatim@line}{#1}{#2}}}
\def\clearsubstlist{\let\subst@list\@empty}
\clearsubstlist
\newenvironment{Schunk}
{\begingroup
\@bsphack
\immediate\openout\listinginput=\jobname.lst%
\let\do\@makeother\dospecials\catcode`\^^M\active
\def\verbatim@processline{%
\subst@list
\immediate\write\listinginput{\the\verbatim@line}}%
\verbatim@start}%
{\immediate\closeout\listinginput
\@esphack
\endgroup
\lstinputlisting{\jobname.lst}}
\makeatother
\begin{document}
\newsubstitution||\begin{Sinput}||<->||Swe@veBeginInput||
\newsubstitution||\end{Sinput}||<->||Swe@veEndInput||
\newsubstitution||\begin{Soutput}||<->||Swe@veBeginOutput||
\newsubstitution||\end{Soutput}||<->||Swe@veEndOutput||
With a substitution list:
\begin{Schunk}
\begin{Sinput}
> getLatexStrWidth("The symbol: alpha")
\end{Sinput}
\begin{Soutput}
[1] 82.5354
\end{Soutput}
\end{Schunk}
\clearsubstlist
With no substitution list:
\begin{Schunk}
\begin{Sinput}
> getLatexStrWidth("The symbol: alpha")
\end{Sinput}
\begin{Soutput}
[1] 82.5354
\end{Soutput}
\end{Schunk}
\end{document}
\documentclass{article}
\begingroup\makeatletter\endlinechar=\m@ne\everyeof{\noexpand}
\edef\x{\endgroup\def\noexpand\TeXpath{\@@input|"which tex" }}\x
\begin{document}
File listing is
{\catcode`_=12 \ttfamily
\input{|"ls /usr" }
}
\TeX{} is \TeXpath
\end{document}
We must use \@@input
(the primitive \input
command) because \input
in LaTeX does assignments. The setting of \endlinechar
is to avoid a spurious space in the expansion of \TeXpath
.
When shell escape is active and the primitive \input
finds a |
, it accepts as input the standard output of the following shell command.
There should be a package by H. Oberdiek that does something of this kind.
Note An assignment is any TeX operation that gives a meaning or a value to a control sequence or register. During the \edef
operation, TeX expands all commands it finds between the braces until only unexpandable tokens remain, but doesn't perform any assignment; rather, something like \catch=22
(where \catch
is the name of a count register) remains completely inaltered. Since the definition of \input
in LaTeX is
\@ifnextchar\bgroup\@iinput\@@input
the implicit assignments performed by \@ifnextchar
would not be performed and both \@input
and \@@input
would be expanded, which results in a complete disaster. Conversely, the \input
primitive (that LaTeX saves as \@@input
) is expandable and its expansion consists in causing TeX to read the named file. One has, of course, to be careful about what this file contains, as also this will be expanded. So other precautions have to be taken when doing this kind of operations, depending on the nature of the tokens produced by the command we want to perform and this "solution" is only a skeleton for possible "real" applications.
Update 2019
After some years, things have changed and better methods are available.
For instance, with xparse
and expl3
the code can be improved:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\captureshell}{som}
{
\sdaau_captureshell:Ne \l__sdaau_captureshell_out_tl { #3 }
\IfBooleanT { #1 }
{% we may need to stringify the result
\tl_set:Nx \l__sdaau_captureshell_out_tl
{ \tl_to_str:N \l__sdaau_captureshell_out_tl }
}
\IfNoValueTF { #2 }
{
\tl_use:N \l__sdaau_captureshell_out_tl
}
{
\tl_set_eq:NN #2 \l__sdaau_captureshell_out_tl
}
}
\tl_new:N \l__sdaau_captureshell_out_tl
\cs_new_protected:Nn \sdaau_captureshell:Nn
{
\sys_get_shell:nnN { #2 } { } #1
\tl_trim_spaces:N #1 % remove leading and trailing spaces
}
\cs_generate_variant:Nn \sdaau_captureshell:Nn { Ne }
\ExplSyntaxOff
\begin{document}
\captureshell*[\TeXpath]{which tex} % we need to stringify it because of _
File listing is
{\ttfamily\captureshell{ls \jobname.*}\par}
\TeX{} is \texttt{\TeXpath}
\end{document}
We could add an error message if the user doesn't pass the -shell-escape
option for the LaTeX run.
Check also texosquery
(requires Java).
Best Answer
You can try
In order to avoid doubled
#
marks and to use%
, you can defineHowever you can't use
\exec
in the argument of another command, because this freezes category codes. Should you need it, one has to work also with\scantokens
. Braces must be balanced, but this should not be a problem.Another possibility, suggested by Martin Scharrer, is to use
\detokenize
:which however might insert unwanted spaces in case backslashes are used in the argument. The advantage is that this macro can be used in arguments to other commands.