如何将命令的内容写入文件

如何将命令的内容写入文件

这个问题是这个问题的一个可能的解决方案在列表中使用 \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}
}

相关内容