将编程代码与解释结合起来的好方法

将编程代码与解释结合起来的好方法

我经常会写一些(编程)代码,然后想准备一份解释性报告。然后,在编写代码时,我经常还会修改代码,并编写解释性说明。因此,我希望将保存在其他地方的代码内容包含在报告中。我想将我的注释分散在代码片段的几个部分中,而不是全部包含。使用pdflatex,有什么好方法可以做到这一点?

我知道有一个包lstlisting,但有两个缺点(在我看来)。考虑一下

\documentclass[12pt]{article}
\usepackage{listings}

\begin{document}

\begin{lstlisting}
Now including `bar.md`:
\input{bar.md}
\end{lstlisting}

\end{document}

bar.md是我保存在同一目录中的所有内容。首先, 被\input{bar.md}逐字处理,并且bar.md不被包含。其次,正如我所说,被包含的代码块不能分成几个部分。

或者例如我可以实现一个\include_my_code这样使用的功能吗?

\documentclass[12pt]{article}

\begin{document}

\include_my_code{bar.md}{1}{20}
(Now follows line 1 to 20 of `bar.md`)
\include_my_code{bar.md}{21}{40}
(Now follows line 21 to 40 of `bar.md`)

\end{document}

答案1

大约 2 年前,我想调整/升级我的verbatimbox软件包,以便方便地实现您所要求的功能。我一路走来,从未完成过。但为了避免万一我回不来,它就被遗忘了,我将在这里发布代码的最后已知状态

首先,创建输出的文档:

\documentclass{article}
\usepackage{verbatimbox}
\begin{document}
\def\vbxcodestyle{\ttfamily\scriptsize\strut}

\#1

%  \setvbxfieldwidth[.06\linewidth]{.74\linewidth}%
\def\vbxformat{%
  \vbxtitlerule=1pt\relax%
  \setvbxfieldwidth[.06\linewidth]{.74\linewidth}%
  \vbxtitle{%
    Verbbox \thenextvbxcount. This is the title.}%
  \vbxfieldcolor%
  \vbxnum%
  \invbxline{11}{\vbxcommentwidth{.22\vbxfieldwidth}%
    \vbxcomment{I am drawing attention to ``Hello World''}}{}%
  \invbxline{15}{\vbxcommentwidth{.22\vbxfieldwidth}%
    \vbxcomment[\normalsize]{I like \LaTeX{}}}{}%
  \vbxcodestyle%
}

\begin{verbbox}[\vbxformat]
#include <stdio.h>
#define N 10
/* Block
 * comment */

int main()
{
    int i;

    // Line comment.
    puts("Hello world!");

    for (i = 0; i < N; i++)
    {
        puts("LaTeX is also great for programmers!");
    }

    return 0;
}
\end{verbbox}
{\noindent\centering\vbxrebox{\theverbbox}\par}



\#2

%\setvbxfieldwidth[.23\linewidth]{.74\linewidth}%
\def\vbxformat{%
 \setvbxfieldwidth[.23\linewidth]{.74\linewidth}%
 \vbxtitle{%
    Verbbox \thenextvbxcount. This is the title\\ for my code on\\\today{}}%
  \invbxline{1}{%
    \vbxfieldcolor[green!8]\vbxnumcolor{green!75!black}%
  }{%
    \invbxlines{3}{4}{%
      \vbxfieldcolor\vbxnumstyle{\color{red}\normalsize$\rightarrow$}%
    }{%
      \invbxlines{8}{18}{%
        \vbxfieldcolor[blue!12!gray!15]\vbxnumcolor{black!20}%
     }{%
      \vbxfieldcolor[cyan!3]\vbxnum%
     }%
    }%
  }%
  \invbxline{11}{\vbxcommentwidth{.22\vbxfieldwidth}%
    \vbxcomment{I am drawing attention to ``Hello World''}}{}%
  \invbxline{15}{\vbxcommentwidth[-.3\vbxfieldwidth]{.22\vbxfieldwidth}%
    \vbxcomment[\normalsize]{I like \LaTeX{}}}{}%
  \vbxcodestyle\,%
}


\begin{verbbox}[\vbxformat]
#include <stdio.h>
#define N 10
/* Block
 * comment */

int main()
{
    int i;

    // Line comment.
    puts("Hello world!");

    for (i = 0; i < N; i++)
    {
        puts("LaTeX is also great for programmers!");
    }

    return 0;
}
\end{verbbox}
{\noindent\centering\vbxrefbox{\theverbbox}\par}


\noindent x\hrulefill x

\#3
\VerbCodeIndent=.06\linewidth\relax
\def\vbxformat{%
 \setvbxfieldwidth[.06\linewidth]{.94\linewidth}%
  \vbxtitlerule=1pt\relax%
  \vbxtitle{%
    Verbbox \thenextvbxcount. This is the title. for a nobox environment,
    which allows for page breaks}%
  \vbxfieldcolor%
  \vbxnum%
  \invbxline{11}{\vbxcommentwidth{.22\vbxfieldwidth}%
    \vbxcomment{I am drawing attention to ``Hello World''}}{}%
  \invbxline{15}{\vbxcommentwidth{.22\vbxfieldwidth}%
    \vbxcomment[\normalsize]{I like \LaTeX{}}}{}%
  \vbxcodestyle%
}
\begin{verbnobox}[\vbxformat]
#include <stdio.h>
#define N 10
int main()
{
    int i;
    // Line comment.
    puts("Hello world!");

    for (i = 0; i < N; i++)
    {
        puts("LaTeX is also great for programmers!");
    }
    return 0;
}
#include <stdio.h>
#define N 10
int main()
{
    int i;
    // Line comment.
    puts("Hello world!");

    for (i = 0; i < N; i++)
    {
        puts("LaTeX is also great for programmers!");
    }
    return 0;
}
\end{verbnobox}
\noindent x\hrulefill x



\#4
\def\vbxformat{%
% \setvbxfieldwidth[.06\linewidth]{.94\linewidth}%
  \vbxtitlerule=1pt\relax%
  \vbxtitle{%
    Verbbox \thenextvbxcount. This is the title.}%
  \vbxfieldcolor%
  \vbxnum%
  \invbxline{4}{\vbxcommentwidth{.22\vbxfieldwidth}%
    \vbxcomment[\normalsize]{I like \LaTeX{}}}{}%
  \vbxcodestyle%
}

\VerbCodeIndent=38pt\relax
\setvbxfieldwidth[.05\linewidth]{.87\linewidth}%

\noindent\verbfilenobox[\vbxformat]{samplecode.txt}


\#5

\verbfilebox[\vbxformat]{samplecode.txt}

{\centering\vbxrefbox{\theverbbox}\par}


\#6

\begin{myverbbox}[\vbxformat]{\myvb}
for (i = 0; i < N; i++)
{
    puts("LaTeX is also great for programmers!");
}
return 0;
\end{myverbbox}
\noindent\myvb

{\centering\vbxrebox{\myvb}\par}

\#7

\fboxrule=2pt
\VerbCodeIndent=66pt\relax

\begin{cverbbox}[\scriptsize\vbxnum]{blue}{cyan!5}{green}
for (i = 0; i < N; i++)
{
    puts("LaTeX is also great for programmers!");
}
return 0;
\end{cverbbox}
\noindent\theverbbox


\#8

\VerbCodeIndent=22pt\relax

\begin{mycverbbox}[\tiny]{blue}{cyan!5}{green}{mycvb}
for (i = 0; i < N; i++)
{
    puts("LaTeX is also great for programmers!");
}
return 0;
\end{mycverbbox}
\noindent\mycvb


\#9

\VerbCodeIndent=44pt\relax

\begin{verbbox}[\tiny]
for (i = 0; i < N; i++)
{
    puts("LaTeX is also great for programmers!");
}
return 0;
\end{verbbox}
\noindent\fbox{\theverbbox}



\#10

\VerbCodeIndent=66pt\relax

\begin{myverbbox}[\tiny]{\myvb}
for (i = 0; i < N; i++)
{
    puts("LaTeX is also great for programmers!");
}
return 0;
\end{myverbbox}
\noindent\fbox{\myvb}




\end{document}

以下是试验改编verbatimbox.sty

\def\verbatimboxVersionNumber{v4.00 }
\ProvidesPackage{verbatimbox}
        [2015/01/31 \verbatimboxVersionNumber
Routines for placing verbatim text into boxes, useful in places where
the verbatim environment is inaccessible.  Secondarily, for adding
vertical buffer around an object.]
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Steven B. Segletes.
%
% verbatimbox.sty is based on boxedverbatim environment found
% in moreverb.sty.
%
% An enabling routine, \addvbuffer[]{} shares some functional
% similarities to \raisebox, but it is not the same.
%
% 2.01 -Added LPPL License info to package
% 3.0  -Added myverbbox environment
%      -Corrected problem when no optional arguments are passed to
%         verbbox environment
%      -Added optional arguments to \addvbuffer
%      -Fixed \verbfilebox so that it restored \verbatim@processline
%      -Produced real documentation
% 3.01 -renamed \macro@name so as not to conflict with (I think) ltxdoc
%       package
% 3.1  -Corrected default argument to \addvbuffer so that it wouldn't
%       break.  Also, gave better guidance in documentation to use
%       of optional argument to \addvbuffer
%      -Added verbnobox environment and \verbfilenobox macro
%      -Improved documentation showing line-specific optional arguments
% 3.11 -Eliminated the use of the stringstrings package, which resets
%       the definition of \|
% 3.12 -Corrected bug introduced in V3.11, which occured with [t] 
%       option to \theverbbox
%      -When using two lengths in \addvbuffer optional argument,
%       they MUST be individually in {}, rather than "~" or "\ " between
% 3.13 -Corrected residual bug from V3.11, when \addvbuffer called
%       without an optional argument.
% 4.00 -Added cverbbox and mycverbbox environments for color
%      -Added host of code highlighting routines.
\NeedsTeXFormat{LaTeX2e}
\@ifundefined{verbatim@processline}{\RequirePackage{verbatim}}{}
\RequirePackage{xcolor}
\RequirePackage{readarray}

% Following 3 lines thanks to Prof. Enrico Gregorio, from: 
% http://tex.stackexchange.com/questions/42318/
%   removing-a-backslash-from-a-character-sequence
\begingroup\lccode`\|=`\\
\lowercase{\endgroup\def\removebs#1{\if#1|\else#1\fi}}
\newcommand{\@macro@name}[1]{\expandafter\removebs\string#1}
%

\newcounter{VerbboxLineNo}
\newlength\VerbCodeIndent
\newcommand\vbxstartline[1]{\setcounter{VerbboxLineNo}{\numexpr#1-1\relax}}
\newcommand\vbxContinueLineNoAfter{\let\vbx@lineprotocol\vbx@continuelineno}
\newcommand\vbxResetLineNoAfter{\let\vbx@lineprotocol\vbx@resetlineno}
\newcommand\vbx@continuelineno{\resetvbxtitle}
\newcommand\vbx@resetlineno{\setcounter{VerbboxLineNo}{0}\resetvbxtitle}
\vbxResetLineNoAfter
\vbxstartline{1}
\global\newsavebox{\savedverbbox}
%%%%%ORIGINAL FORM%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The verbbox environment is based on 
% the boxedverbatim environment found in moreverb.sty
% The optional argument allows the user to modify properties of the text
%   such as fontsize
%
\newenvironment{origverbbox}[1][]{%
  \def\verbatim@processline{%
    {\setbox0=\hbox{\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \setbox0=\vbox\bgroup #1 \verbatim
}
{%
  \endverbatim
  \unskip\setbox0=\lastbox %
  \egroup
  \global\sbox{\savedverbbox}{\box0}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% David Carlisle provided the \verbbox@inner approach to avoid
% problem when no optional argument is provided to verbbox environment:
% http://tex.stackexchange.com/questions/109030/optional-arguments-in
%   -verbatim-environments
\newcommand\verbbox@inner[1][]{{\nfss@catcodes\scantokens{\gdef\@tmp{#1}}}}
\def\@tmp{}

\newenvironment{verbbox}{%
  \addtocounter{VerbboxLineNo}{-1}%
% FOR SOME REASON, USING \my@par INSTEAD OF \par PREVENTS EXTRA SPACE
% ABOVE verbbox WHEN USING OPTIONAL ARGUMENTS
  \let\my@par\par%
  \def\verbatim@processline{%
%   FIRST \@tmp APPLIES OPTIONAL ARGUMENT TO EACH VERBATIM LINE
%   SECOND \@tmp MAKES SURE ANY PRINTED MATTER OF OPTIONAL ARGUMENT
%   IS ACCOUNTED FOR IN VERBATIM BOX WIDTH
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    \@tmp\setbox0=\hbox{\@tmp\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\my@par}}%
  \@minipagetrue%
  \@tempswatrue%
  \setbox0=\vbox\bgroup \verbatim\verbbox@inner%
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \global\sbox{\savedverbbox}{\box0\rule{\VerbCodeIndent}{0pt}}%
  \global\def\@tmp{}%
  \global\vbx@lineprotocol%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The myverbbox environment is altered from verbbox environment
% The optional argument allows the user to modify properties of 
%   the text such as fontsize
% The mandatory argument is a command which is formed so as to
%   regurgitate the boxed content created within the environment
%
\newenvironment{myverbbox}[2][]{%
%  \addtocounter{VerbboxLineNo}{-1}%
  \def\verbatim@processline{%
% THE FIRST #1 ACCOUNTS FOR NON-PRINTING COMMANDS; THE SECOND #1 IS FOR
% PRINTED OPTIONAL MATERIAL
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \global\edef\sv@name{\@macro@name{#2}}%
  \@ifundefined{\sv@name content}{%
    \expandafter\newsavebox\expandafter{\csname\sv@name content\endcsname}%
  }%
  \expandafter\global\expandafter\edef\csname\sv@name\endcsname{\usebox{%
  \csname\sv@name content\endcsname}}%
  \setbox0=\vbox\bgroup \verbatim
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \global\sbox{\csname\sv@name content\endcsname}{%
    \box0\rule{\VerbCodeIndent}{0pt}}%
  \global\vbx@lineprotocol%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The verbfilebox command is like the verbbox environment, but takes
% a file as input, rather than text typed into an environment.
% The optional argument allows the user to modify properties of the text
% such as fontsize
% Example: \verbfilebox[\scriptsize]{myfile}

\let\sv@verbatim@processline\verbatim@processline

\newcommand\verbfilebox[2][]{%
%  \addtocounter{VerbboxLineNo}{-1}%
  \def\verbatim@processline{%
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \setbox0=\vbox\bgroup \verbatiminput{#2}
  \unskip\setbox0=\lastbox %
  \egroup
  \global\sbox{\savedverbbox}{\box0}
  \let\verbatim@processline\sv@verbatim@processline
  \global\vbx@lineprotocol%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand\theverbbox[1][x]{%
  \if #1t%
%   The t option is for outputting the savedverbbox inside a tabular
%   environment (else insufficent vertical space above box)
    \addvbuffer[{\boxtopsep} {\boxbottomsep}]{\usebox{\savedverbbox}}%
  \else%
    \usebox{\savedverbbox}%
  \fi%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \addvbuffer is based on \fbox, 
% but without a frame.  Empty buffer space
% is added above and below the object, making a new box.
% An optional argument can specify the buffer spaces or, if no
% optional argument is specified:
% above the box is added \boxtopsep (initially 3pt) vertical space;
% below the box is added \boxbottomsep (initially 0pt) vertical space.
%
\newdimen\boxtopsep
\newdimen\boxbottomsep
\newdimen\ps@tempdima
\newbox\ps@tempboxa
\setlength\boxtopsep{3pt}
\setlength\boxbottomsep{0pt}
\long\def\add@vbuffer#1{\leavevmode\setbox\ps@tempboxa\hbox{#1}\ps@tempdima
   0pt \advance\ps@tempdima \dp\ps@tempboxa \hbox{\lower\ps@tempdima\hbox
  {\vbox{\hbox{\vbox{\vskip\boxtop@sep \box\ps@tempboxa \vskip 
  \boxbottom@sep}}}}}}

\global\newlength\boxtop@sep
\global\newlength\boxbottom@sep
\newcommand\addvbuffer[2][{\boxtopsep} {\boxbottomsep}]{%
  \getargsC{#1}%
  \setlength\boxtop@sep{\argi}%
  \if1\narg\setlength\boxbottom@sep{\argi}\else%
           \setlength\boxbottom@sep{\argii}\fi%
  \add@vbuffer{#2}%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The following two "nobox" commands are basically versions of
% \verbatiminput and \verbatim that have been adapted to take the
% optional argument style of this package.  No boxes are created,
% but breaking across page boundaries is not a problem here, as
% it would be with a box.

\newcommand\verbfilenobox[2][]{%
%  \addtocounter{VerbboxLineNo}{-1}%
  \def\verbatim@processline{%
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \verbatiminput{#2}
  \let\verbatim@processline\sv@verbatim@processline
  \global\vbx@lineprotocol%
}

\newenvironment{verbnobox}{%
  \addtocounter{VerbboxLineNo}{-1}%
% FOR SOME REASON, USING \my@par INSTEAD OF \par PREVENTS EXTRA SPACE
% ABOVE verbbox WHEN USING OPTIONAL ARGUMENTS
  \let\my@par\par%
  \def\verbatim@processline{%
%   FIRST \@tmp APPLIES OPTIONAL ARGUMENT TO EACH VERBATIM LINE
%   SECOND \@tmp MAKES SURE ANY PRINTED MATTER OF OPTIONAL ARGUMENT
%   IS ACCOUNTED FOR IN VERBATIM BOX WIDTH
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    \@tmp\setbox0=\hbox{\@tmp\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\my@par}}%
\verbatim\verbbox@inner%
}
{%
  \endverbatim%
  \global\def\@tmp{}%
  \global\vbx@lineprotocol%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The cverbbox and mycverbbox macros add color capability to 
% verbbox'es.  In addition to the standard optional argument
% that is supported by this package, cverbbox additionally
% takes 3 mandatory arguments: font color, background color,
% and frame color. The mycverbbox environment additionally
% takes a verbbox name as a final argument.

\newenvironment{mycverbbox}[5][]{%
%  \addtocounter{VerbboxLineNo}{-1}%
  \def\verbatim@processline{%
% THE FIRST #1 ACCOUNTS FOR NON-PRINTING COMMANDS; THE SECOND #1 IS FOR
% PRINTED OPTIONAL MATERIAL
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \global\edef\sv@name{\@macro@name{#5}}%
  \global\edef\cverbboxColor{#3}%
  \global\edef\cverbboxFColor{#4}%
  \@ifundefined{\sv@name content}{%
    \expandafter\newsavebox\expandafter{\csname\sv@name content\endcsname}%
  }%
  \expandafter\global\expandafter\edef\csname\sv@name\endcsname{\usebox{%
  \csname\sv@name content\endcsname}}%
  \setbox0=\vbox\bgroup\color{#2} \verbatim
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \setbox1=\hbox{%
    \colorbox{\cverbboxColor}{\box0\rule{\VerbCodeIndent}{0pt}}}%
  \global\sbox{\csname\sv@name content\endcsname}%
    {%
      \fboxsep=\fboxrule\colorbox{\cverbboxFColor}{\box1}}%
  \global\vbx@lineprotocol%
}
\newenvironment{cverbbox}[4][]{%
%  \addtocounter{VerbboxLineNo}{-1}%
  \def\verbatim@processline{%
% THE FIRST #1 ACCOUNTS FOR NON-PRINTING COMMANDS; THE SECOND #1 IS FOR
% PRINTED OPTIONAL MATERIAL
    {\addtocounter{VerbboxLineNo}{1}%
    \rule{\VerbCodeIndent}{0pt}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \global\edef\cverbboxColor{#3}%
  \global\edef\cverbboxFColor{#4}%
  \setbox0=\vbox\bgroup\color{#2} \verbatim
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \setbox1=\hbox{%
    \colorbox{\cverbboxColor}{\box0\rule{\VerbCodeIndent}{0pt}}}%
  \global\sbox{\savedverbbox}{%
    \fboxsep=\fboxrule\colorbox{\cverbboxFColor}{\box1}}%
  \global\vbx@lineprotocol%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Here are a series of macros for highlighting code (not syntax
% highlighting),

\newlength\@vbxcolorfieldoverlap
\newlength\vbxfieldwidth
\newlength\@vbxcommentindent
\newlength\@vbxcommentwidth
\newlength\vbxcommentrule
\newlength\vbxcommentsep
\newlength\vbxtitlerule
\newlength\vbxtitlesep
\newlength\vbxnumbergap
\newlength\vbxleftfieldwidth
\newlength\gvbxfieldwidth
\newlength\gvbxleftfieldwidth
\newsavebox\@thevbxcolorfield
\setlength\@vbxcolorfieldoverlap{.1pt}% PREVENTS THIN WHITE LINES IN LISTING
\setlength\@vbxcommentindent{.75\vbxfieldwidth}
\setlength\@vbxcommentwidth{.24\vbxfieldwidth}
\newcounter{vbxcount}
% USER MODIFIABLE
\def\vbxdefaultcolorfield{black!5}
\setlength\vbxnumbergap{2pt}
\def\vbxnumberformat{\arabic{VerbboxLineNo}:}
\def\vbxnumberstyle{\sffamily\scriptsize}
\def\vbxcodestyle{\ttfamily\footnotesize\strut}
\setlength\vbxleftfieldwidth{0pt}
\setlength\vbxfieldwidth{\linewidth}
%
\def\vbxcommentstyle{\vbxcodestyle\rmfamily}
\def\vbxcommenttextcolor{blue!70!black}
\def\vbxcommentfieldcolor{yellow!13}
\def\vbxcommentrulecolor{red}
\setlength\vbxcommentrule{1pt}
\setlength\vbxcommentsep{1pt}
%
\def\vbxtitlestyle{\centering\rmfamily\small}
\def\vbxtitletextcolor{black}
\def\vbxtitlefieldcolor{yellow!25}
\def\vbxtitlerulecolor{black}
\setlength\vbxtitlerule{.5pt}
\setlength\vbxtitlesep{1pt}

%%%%%
\newcommand\@setcolorvbxfield[1]{%
  \savebox{\@thevbxcolorfield}{%
    \smash{\makebox[0pt][l]{\vbxcodestyle\textcolor{#1}{%
    \rule[\dimexpr-\@vbxcolorfieldoverlap-\dp\strutbox]{\vbxfieldwidth}%
      {\dimexpr\ht\strutbox+\dp\strutbox+2\@vbxcolorfieldoverlap}}}}}%
}

\newcommand\vbxfieldcolor[1][\vbxdefaultcolorfield]{\@setcolorvbxfield{#1}\usebox{\@thevbxcolorfield}}

\newcommand\vbxnum[1][0ex]{\makebox[#1][r]{\smash{%
  \vbxnumberstyle\vbxnumberformat}\hspace{\vbxnumbergap}}}

\newcommand\vbxnumstyle[2][0ex]{\makebox[#1][r]{\smash{%
  \vbxnumberstyle#2\vbxnumberformat}\hspace{\vbxnumbergap}}}

\newcommand\vbxnumcolor[2][0ex]{\makebox[#1][r]{\smash{%
  \textcolor{#2}{\vbxnumberstyle\vbxnumberformat}}\hspace{\vbxnumbergap}}}

\newcommand*\invbxline[3]{\ifnum\value{VerbboxLineNo}=#1\relax#2\else#3\fi}

\newcommand*\invbxlines[4]{%
  \ifnum\value{VerbboxLineNo}<#1\relax#4\else%
    \ifnum\value{VerbboxLineNo}>#2#4\else#3\fi%
  \fi%
}

\newcommand\vbxcomment[2][]{\vbxcodestyle#1\fboxsep=0pt\smash{\rlap{%
  \textcolor{\vbxcommentrulecolor}{%
     \rule[-\vbxcommentrule]{\@vbxcommentindent}{\vbxcommentrule}%
     \ifdim\@vbxcommentindent<0pt\relax%
       \rlap{\rule[-\vbxcommentrule]{-\@vbxcommentindent}{\vbxcommentrule}}%
     \fi%
  }%
  \raisebox{\dimexpr\dp\strutbox+\vbxcommentsep}{%
    \textcolor{\vbxcommentrulecolor}{\colorbox{\vbxcommentfieldcolor}{%
      \fboxsep=\vbxcommentsep%
      \fboxrule=\vbxcommentrule%
      \fbox{\parbox[b]{%
        \dimexpr\@vbxcommentwidth-2\vbxcommentrule-2\vbxcommentsep}%
        {\color{\vbxcommenttextcolor}\vbxcommentstyle%
         #1\strut#2\strut}}}}}}}%
}

\newcommand\setvbxfieldwidth[2][0pt]{%
  \setlength\vbxfieldwidth{#2}%
  \global\setlength\gvbxfieldwidth{\vbxfieldwidth}%
  \setlength\vbxleftfieldwidth{#1}%
  \global\setlength\gvbxleftfieldwidth{\vbxleftfieldwidth}%
}

\newcommand\vbxcommentwidth[2][-\textwidth]{%
  \setlength\@vbxcommentwidth{#2}%
  \ifdim#1>-\textwidth\setlength\@vbxcommentindent{#1}\else%
    \setlength\@vbxcommentindent{%
      \dimexpr\vbxfieldwidth-#2-\vbxtitlerule\relax}\fi%
}

\newcommand\mastervbxtitle[1]{\fboxsep=0pt%
  \rule{-\vbxleftfieldwidth}{0pt}%
  \textcolor{\vbxtitlerulecolor}{\colorbox{\vbxtitlefieldcolor}{%
      \fboxsep=\vbxtitlesep%
      \fboxrule=\vbxtitlerule%
      \fbox{\parbox{\dimexpr\vbxfieldwidth-2\vbxtitlerule-2\vbxtitlesep%
        +\vbxleftfieldwidth\relax}{%
    \vbxtitlestyle\textcolor{\vbxtitletextcolor}{#1}}}}}\\%
  \rule{\VerbCodeIndent}{0pt}%
  \global\let\vbxtitle\@gobble%
}

\def\resetvbxtitle{\global\let\vbxtitle\mastervbxtitle}
\resetvbxtitle

\newcommand\vbxrebox[1]{%
  \hspace{\dimexpr\gvbxleftfieldwidth-\VerbCodeIndent\relax}%
  \makebox[\dimexpr\gvbxfieldwidth+\VerbCodeIndent\relax][l]{#1}}


\newcommand\vbxrefbox[1]{%
  \fboxrule=\vbxtitlerule\relax%
  \fboxsep=-\fboxrule%
  \textcolor{\vbxtitlerulecolor}{\fbox{\vbxrebox{#1}}}%
}

\def\thenextvbxcount{\stepcounter{vbxcount}\thevbxcount}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\endinput

输出如下:

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

相关内容