抱歉,下一个代码太长了,但如果我修改代码的一部分,另一部分就会出现另一个问题。这个想法是使用环境来捕获一个示例,然后我显示示例的代码,然后我执行此代码,最后我将示例的代码保存在一个文件中(此处名为 examplefile.tex)
我有两个问题:
1) 我得到的不是 CR,而是^^M
examplefile.tex。我想我在宏中的一些 catcodes 出了问题\CatchTokensDef
2) 我对示例源代码中的注释有一点小问题。我把它们弄丢了。
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{environ}
\makeatletter
\newwrite\example
\newtoks \TokenExample
\def\ExamplePreamble% add at the beginning
{%
\input{preamble.ltx}^^J%
\begin{document}%
}%
\def\ExamplePostamble% add at the end
{%
\end{document}%
}%
\def\ExportExample#1{% create the file
\immediate\openout\example=#1 %
{%
\toks@\expandafter{\ExamplePreamble^^J}%
\toks@\expandafter{\the\expandafter\toks@
\the\@temptokena^^J}%
\toks@\expandafter{\the\expandafter\toks@
\ExamplePostamble}%
\immediate\write\example{\the\toks@}%
}%
\immediate\closeout\example
}%
\def\PrintExample{% display the code
\begin{minipage}[t]{12cm}
\@vobeyspaces
\the\@temptokena
\end{minipage}
}
\def\ExecExample{\the\@temptokena}%
\def\CatchTokensDef#1{%
% instead of \input
% #1 = setup (catcodes) %
% original content in \TokenExample
% result in \@temptokena
\begingroup \endlinechar-1 %
\everyeof{\CatchToken@EOF
\expandafter \endgroup
\noexpand}%
\long\def\CatchToken@Do ##1\CatchToken@EOF{%
\global\@temptokena{##1}%
}%
#1\expandafter\CatchToken@Do
\scantokens\expandafter{\the\TokenExample}\relax
}%
% catch the content with \Collect@Body from environ.sty
\newenvironment{exemple}% this is the main environment
{\begingroup
\obeylines
\obeyspaces
\Collect@Body
\StoreInToken
}
{\endgroup
\process@example
}
\long\def\StoreInToken #1{\global\TokenExample{#1}}
\begin{document}
\def\process@example{% first we catch some tokens
\CatchTokensDef {\let\do
\@makeother
\dospecials
\obeylines
\@vobeyspaces}%
\PrintExample% display the code of the exammple
\ExportExample{examplefile.tex}% export the example in a file
\CatchTokensDef {\catcode`\^^M=9\relax}
% the problem is resolved if I put the last line
% before \ExportExample{examplefile.tex}
\ExecExample% execute the example
}%
\begin{exemple}
\begin{tikzpicture}
% main code
\filldraw[black,fill=green!15]
(0,0) rectangle (5,1)
node [midway] {I say goodbye, you say hello !};% Beatles
\end{tikzpicture}
\end{exemple}
\end{document}
结果 :
正如你所见,我丢失了注释和空白行
但是我进入^^M
了 examplefile.tex
\input {preamble.ltx}
\begin {document}
^^M\begin {tikzpicture}^^M\filldraw [black,fill=green!15]^^M (0,0) rectangle (5,1)^^M node [midway] {I say goodbye, you say hello !}; ^^M\end {tikzpicture}^^M
\end {document}
答案1
我不会重新发明轮子:fancyvrb
已经有了所需的基础设施;只需使其VerbatimOut
文件适应您的需要即可。
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{fancyvrb,etoolbox,standalone}
\makeatletter
\def\exemple{\FV@Environment{}{exemple}}
\DefineVerbatimEnvironment{exemple}{exemple}{}
\let\FVB@exemple\FVB@VerbatimOut
\patchcmd{\FVB@exemple}
{\@bsphack}
{\def\FV@exemple@file{#1}\@bsphack}
{}{\ddt}
\patchcmd{\FVB@exemple}
{\FV@Scan}
{\immediate\write\FV@OutFile{\string\input{preamble.ltx}}%
\immediate\write\FV@OutFile{\string\begin{document}}%
\FV@Scan}
{}{\ddt}
\def\FVE@exemple{\immediate\write\FV@OutFile{\string\end{document}}%
\immediate\closeout\FV@OutFile\endgroup\@esphack
\VerbatimInput{\FV@exemple@file}\input{\FV@exemple@file}%
}
\makeatother
\begin{document}
\begin{exemple}{exemplefile.tex}
\begin{tikzpicture}
% main code
\filldraw[black,fill=green!15]
(0,0) rectangle (5,1)
node [midway] {I say goodbye, you say hello !};% Beatles
\end{tikzpicture}
\end{exemple}
\end{document}
使用此代码,您必须提供一个文件名,但很容易避免它并使用唯一的名称:而不是行\let
和两者\patchcmd
,只需定义\FVB@exemple
复制定义fancyvrb.sty
并进行必要的调整。
\makeatletter
\def\exemple{\FV@Environment{}{exemple}}
\DefineVerbatimEnvironment{exemple}{exemple}{}
\def\FVB@exemple{%
\@bsphack
\begingroup
\FV@UseKeyValues
\FV@DefineWhiteSpace
\def\FV@Space{\space}%
\FV@DefineTabOut
\def\FV@ProcessLine{\immediate\write\FV@OutFile}%
\immediate\openout\FV@OutFile=exemplefile.tex\relax
\let\FV@FontScanPrep\relax
\let\@noligs\relax
\immediate\write\FV@OutFile{\string\input{preamble.ltx}}%
\immediate\write\FV@OutFile{\string\begin{document}}%
\FV@Scan}
\def\FVE@exemple{\immediate\write\FV@OutFile{\string\end{document}}%
\immediate\closeout\FV@OutFile\endgroup\@esphack
\VerbatimInput{exemplefile}\input{exemplefile}%
}
\makeatother