如何将一个代码排版为最终代码和源代码

如何将一个代码排版为最终代码和源代码

我编写 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}

在此处输入图片描述

相关内容