这个问题是这个问题的一个可能的解决方案在列表中使用 \expandafter\csname 等时,代码因紧急停止而失败,尽管这并不是真正的答案。
我定义了一个命令,它可能包含多达 100 行代码(包括段落换行符),但基本上它只是大量的 LaTeX 代码。我们假设这个命令被称为\printhis
现在我想将的内容导出\printthis
到一个文件中,以便listings
之后加载。
我之前没有使用过任何将内容导出到文件的 tex 代码。如果有人可以提供示例或教程链接那就太好了。
编辑:使用答案包的方法。
\documentclass{scrbook}
\makeatletter
\providecommand{\packagename}{templatedemo}
\RequirePackage{etoolbox}
\RequirePackage{answers}
\providecommand\demo@filename{demofile}
\providecommand\AddDemo[2]{%
% #1 : package/identifier
% #2 : content
\ifcsdef{demo@content@#1}{
\expandafter\renewcommand\csname demo@content@#1\endcsname{#2}%
}{
\expandafter\newcommand\csname demo@content@#1\endcsname{#2}%
}
}
\providecommand{\demo@printhis}{}
\newcommand{\outputtofile}[1]{
\Opensolutionfile{\demo@filename}
\scantokens{\begin{Filesave}{\demo@filename}#1\end{Filesave}}
\Closesolutionfile{\demo@filename}
}
\providecommand\PrintDemo[1]{%
\ifcsdef{demo@content@#1}%
{ % print
\renewcommand{\demo@printhis}{\csuse{demo@content@#1}}
To file: \demo@printhis
\outputtofile{\demo@printhis}
}%
{ % error if not defined
}
}
\AddDemo{text}{Sample text in file}%
\makeatother
\listfiles
\begin{document}
\PrintDemo{text}\par
From File: \IfFileExists{demofile.tex}{\input{demofile.tex}}{}
\end{document}
答案1
经过一些修正后,您的文件编译如下:
\documentclass{scrbook}
\RequirePackage{etoolbox}
\RequirePackage{answers}
\makeatletter
\newcommand\demo@filename{demofile}
\newcommand\AddDemo[2]{%
% #1 : package/identifier
% #2 : content
\@namedef{demo@content@#1}{#2}}
\newcommand{\demo@printhis}{}
\newcommand{\outputtofile}[1]{
\Opensolutionfile{\demo@filename}
\begingroup\makeatletter
\scantokens{\begin{Filesave}{\demo@filename}#1\end{Filesave}}
\endgroup
\Closesolutionfile{\demo@filename}
}
\newcommand\PrintDemo[1]{%
\ifcsdef{demo@content@#1}%
{ % print
\letcs\demo@printhis{demo@content@#1}
To file: \demo@printhis
\expandafter\outputtofile\expandafter{\demo@printhis}
}%
{ % error if not defined
}
}
\makeatother
\AddDemo{text}{Sample text in file \today}%
\begin{document}
\PrintDemo{text}\par
From File: \IfFileExists{demofile.tex}{\input{demofile.tex}}{}
\end{document}
在\AddDemo
条件中是无用的,因为无论如何你都想重新定义标记。因此\@namedef
(LaTeX 内核)或\csdef
(电子工具箱)做需要做的事情。
当你这样做时\scantokens
,当前的已应用类别代码,因此使用\demo@filename
会中断,因为@
不再是文档中的字母。应用\makeatletter
可以解决问题(但请注意@
示例中的字符);它可以成组进行,因为我们只需写入文件,然后 就会\endgroup
撤消它。
然而,这种方法有一个严重的限制:输出文件中不能保留换行符。也就是说,
\AddDemo{text}{Sample text}
和
\AddDemo{text}{%
Sample
text}
将在输出文件中保存相同的内容。
答案2
我认为该answers
软件包可能有你要找的东西。它有许多用于写入文件的命令 - 特别是,你可以使用类似
\begin{Filesave}{myfile}
Any code you like, even paragraph skips!
\end{Filesave}
请参阅下面的 MWE
\documentclass{article}
\usepackage{answers}
% open myfile.tex
\Opensolutionfile{myfile}
% sounds like you won't need this line
%\Newassociation{shortsolution}{shortSoln}{myfile}
\begin{document}
\section{Main body}
Here we are in the body.
\begin{Filesave}{myfile}
This will be written to the file. It can contain
linebreaks, tables, anything at all.
\begin{table}[!h]
\centering
\begin{tabular}{cc}
1 & 2
\end{tabular}
\caption{My table}
\end{table}
\end{Filesave}
\newpage
% close myfile.tex
\Closesolutionfile{myfile}
\section{Inputted file}
% input myfile.tex
\IfFileExists{myfile.tex}{\input{myfile.tex}}{}
\end{document}
编辑
注释之后,printthis
命令可以放在序言中
\newcommand{\printthis}[1]{\scantokens{\begin{Filesave}{myfile}#1\end{Filesave}}}
其使用方法如下:
\printthis{Goes to myfile
\begin{table}[!h]
\centering
\begin{tabular}{cc}
1 & 2
\end{tabular}
\caption{My other table}
\end{table}
}