Is there a command similar to \lstinputlisting
with sagetex, which would import directly a .sage
file in the relevant block, and have it evaluated by sagetex
?
If not, how would one write such a command?
The idea would be very similar to that of \lstinputlisting
, ie, writing the source code in a sage development environment and having it directly interact with latex via sagetex
.
I came up with the following code:
\newcommand{\sagesilentinput}[1]{%
\newwrite\texfile
\immediate\openout\texfile=#1.tex
\immediate\write\texfile{\noexpand\begin{sagesilent}}
%
\newread\sagefile
\openin\sagefile=#1
\typeout{Reading #1}
%
% %% Taken from https://tex.stackexchange.com/q/63463/9517
\begingroup\endlinechar=-1
\loop\unless\ifeof\sagefile
\read\sagefile to\fileline
\typeout\fileline % For debug purposes, but nothing is typed out either
\immediate\write\texfile{\unexpanded\expandafter{\fileline}}
\repeat
\endgroup
%
\immediate\write\texfile{\noexpand\end{sagesilent}}
\immediate\closeout\texfile
\closein\sagefile
%
\input{#1.tex}
}
which should take as argument the name of a file foo.sage
, create a file foo.sage.tex
with contents
\begin{sagesilent}
<contents of foo.sage>
\end{sagesilent}
and then input it.
However, it doesn't work, the file just contains
\begin{sagesilent}
\end{sagesilent}
and it's all like the loop didn't read a single line. The result is the same if I use \readline
instead of \read
.
MNWE with sagetex:
\documentclass{article}
\usepackage{sagetex}
\usepackage{filecontents}
\begin{filecontents}{example.sage}
def myfunction(a,b):
return a+b;
\end{filecontents}
\newcommand{\sagesilentinput}[1]{%
\newwrite\texfile
\immediate\openout\texfile=#1.tex
\immediate\write\texfile{\noexpand\begin{sagesilent}}
\typeout{Writing #1.tex}
%
\newread\sagefile
\openin\sagefile=#1
\typeout{Reading #1}
%
% %% Taken from https://tex.stackexchange.com/q/63463/9517
\begingroup\endlinechar=-1
\loop\unless\ifeof\sagefile
\read\sagefile to\fileline
\typeout\fileline % For debug purposes, but nothing is typed out either
\immediate\write\texfile{\unexpanded\expandafter{\fileline}}
\repeat
\endgroup
%
\immediate\write\texfile{\noexpand\end{sagesilent}}
\immediate\closeout\texfile
\closein\sagefile
%
\input{#1.tex}
}
\begin{document}
\sagesilentinput{example.sage}
\sage{myfunction(3,4)}
\end{document}
MNWE without sagetex (success can then be seen on the contents of example.sage.tex
):
\documentclass{article}
%\usepackage{sagetex}
\usepackage{filecontents}
\begin{filecontents}{example.sage}
def myfunction(a,b):
return a+b;
\end{filecontents}
\newcommand{\sagesilentinput}[1]{%
\newwrite\texfile
\immediate\openout\texfile=#1.tex
\immediate\write\texfile{\noexpand\begin{sagesilent}}
\typeout{Writing #1.tex}
%
\newread\sagefile
\openin\sagefile=#1
\typeout{Reading #1}
%
% %% Taken from https://tex.stackexchange.com/q/63463/9517
\begingroup\endlinechar=-1
\loop\unless\ifeof\sagefile
\read\sagefile to\fileline
\typeout\fileline % For debug purposes, but nothing is typed out either
\immediate\write\texfile{\unexpanded\expandafter{\fileline}}
\repeat
\endgroup
%
\immediate\write\texfile{\noexpand\end{sagesilent}}
\immediate\closeout\texfile
\closein\sagefile
%
%\input{#1.tex}
}
\begin{document}
\sagesilentinput{example.sage}
%\sage{myfunction(3,4)}
\end{document}