我编写 Latex 代码的能力非常有限,而且我无法在论坛中搜索或在 Google 上找到解决我的问题的方法。
我的问题:我必须编写一个包含多种算法的文档,并展示源代码和最终的排版。
这是我想要的结果的 MWE:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{algpseudocode}
\begin{document}
The code
\begin{verbatim}
\If{$a > b$}
\State $c \gets a$
\Else
\State $c \gets b$
\EndIf
\end{verbatim}
is typeset as
\begin{algorithmic}
\If{$a > b$}
\State $c \gets a$
\Else
\State $c \gets b$
\EndIf
\end{algorithmic}
\end{document}
但是,我不想复制每个算法的代码,因为这会使维护变得困难并导致不一致。
我想知道是否有办法定义代码并将其呈现为算法和源代码。
以下是我想要的 M(non)WE:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{algpseudocode}
\begin{document}
\newsamplecode{\ExampleOne}{
\If{$a > b$}
\State $c \gets a$
\Else
\State $c \gets b$
\EndIf
}
The code
\begin{Verbatim}
\ExampleOneCode
\end{Verbatim}
is typeset as
\begin{algorithmic}
\ExampleOneAlg
\end{algorithmic}
\end{document}
到目前为止,我尝试存储源代码并将其作为两个不同的宏提供。这显然行不通,我也没有主意了。以下是我得到的结果:
\newcommand{\newsamplecode}[2]{%
\expandafter\def\csname sc#1\endcsname{#2}
\expandafter\newcommand\csname sc#1verb\endcsname{\verb|#2|}
}
这成功了:
\newsamplecode{codigodez}{
\State Input $s$
\If{$s$}
\State \textbf{say} \textit{ok}
\EndIf
}
\begin{algorithmic}
\sccodigodez
\end{algorithmic}
但我无法以任何方式呈现源代码。我尝试使用该xstring
包将参数转换为逐字和/或替换\
为\textbackslash
。到目前为止,内部命令(如\State
)似乎在我尝试应用任何处理之前进行评估。
如果有人能给我指出解决方案,我将不胜感激。
使用我的解决方案进行编辑
我创建了一个新的环境,它按原样保存了代码,并创建了新命令以在不同的上下文中输入保存的文件:将其排版为算法并逐字显示。
\documentclass{article}
\usepackage{algorithm} % numbered algorithms
\usepackage{algpseudocode} % algorithmic typeset
\usepackage{tcolorbox} % to save verbatim
\usepackage{fancyvrb} % to load verbatim preserving tabs
% environment and commands
\newenvironment{definecode}[1]{\begingroup\tcbverbatimwrite{\jobname_code_#1.tmp}}%
{\endtcbverbatimwrite\endgroup}
\newcommand{\algcode}[1]{\input{\jobname_code_#1.tmp}}
\newcommand{\sourcecode}[1]{\VerbatimInput{\jobname_code_#1.tmp}}
\begin{document}
% a code to be stored
\begin{definecode}{mycode}
\State $x \gets 1$
\While{$x < 10$}
\State $x \gets x-1$
\EndWhile
\end{definecode}
% using the stored code
See Alg~\ref{alg:my}.
\begin{algorithm}
\caption{My algorithm.}
\label{alg:my}
\begin{algorithmic}[1]
\algcode{mycode}
\end{algorithmic}
\end{algorithm}
And this is the source for Alg~\ref{alg:my}:
\sourcecode{mycode}
\end{document}
我选择使用命令将代码中的“算法名称”与其实际文件名分离。我知道如果我使用相同的名称,文件将被覆盖,但我现在可以手动管理它。
答案1
您可以使用该filecontents
包:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{algpseudocode}
\usepackage{fancyvrb}% To use \VerbatimInput
\usepackage{filecontents}
\begin{filecontents}{exampleone.alg}
\If{$a > b$}
\State $c \gets a$
\Else
\State $c \gets b$
\EndIf
\end{filecontents}
\begin{document}
The code
\VerbatimInput[firstline=5]{exampleone.alg}
is typeset as
\begin{algorithmic}
\input{exampleone.alg}
\end{algorithmic}
\end{document}
答案2
随着tcolorbox
包裹:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[most]{tcolorbox}
\usepackage{algpseudocode}
\tcbset{%
sidebyside,
before lower={\begin{algorithmic}},
after lower={\end{algorithmic}},
}
\begin{document}
\begin{tcblisting}{title={test}}
\If{$a > b$}
\State $c \gets a$
\Else
\State $c \gets b$
\EndIf
\end{tcblisting}
\end{document}