# Directly input a sage file in a sagetex block

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}}
%
\openin\sagefile=#1
%
% %% Taken from https://tex.stackexchange.com/q/63463/9517
\begingroup\endlinechar=-1
\loop\unless\ifeof\sagefile
\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}
%
\openin\sagefile=#1
%
% %% Taken from https://tex.stackexchange.com/q/63463/9517
\begingroup\endlinechar=-1
\loop\unless\ifeof\sagefile
\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}
%
\openin\sagefile=#1
%
% %% Taken from https://tex.stackexchange.com/q/63463/9517
\begingroup\endlinechar=-1
\loop\unless\ifeof\sagefile
\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}
• If nobody can help here, you might try going to the AskSagemath site.
– DJP
Jun 26, 2019 at 22:37
• @DJP Thanks for the suggestion. I have found a workaround which I will post here, but apparently it cannot be made into a macro. Anyway, I have no reason to believe that the problem I have is related to sage, it is about using (La)TeX to copy the contents of a file. Maybe I should edit the title to make it more clear. Jun 27, 2019 at 15:49

This is not an answer, but at least a workaround. It does not solve the specific copying problem asked in the question, but it achieves the final purpose, and does not create an external file.

The problem is that one cannot use LaTeX's \input to load a sage file in the relevant blocks, because \input would not be expanded before the contents are evaluated by Sage. However, it is possible to use Sage syntax for the same outcome:

\begin{sagesilent}