我正在编写一个 Latex 文档,其中的伪代码中穿插着定理和讨论。伪代码中的一些注释很长。我想自动以井号、星号或百分号开始(和结束)注释的每个输出行,就像人们在编写 C++ 或 Matlab 时经常做的那样。我知道的唯一方法是使用 \obeylines 并将所需的字符放入 latex 源中。然而,这会导致行过短或过长。
是否有一种方便的方法来实现我的目标?
答案1
alg
包装注释版本(原文通用版本在最后)
间距仍然不是完美的,但它显示了可能性,并且可以进行进一步的改进......
示例文本(由 OP 提供)
\documentclass[12pt,a4paper]{article}
\usepackage{alg,algcom}
\usepackage{color}
\newcommand{\algendif}{\algend\textbf{endif}\\}
%\newcommand{\algcomment}[1]{#1}
\def\a{Not expected X\dotfill X }
\def\atwo{\a\a}
\def\afour{\atwo\atwo}
\def\aeight{\afour\afour}
%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
This tex file shows what can currently be achieved with the {\tt alg}
package
\begin{algtab}
\algif{$e==0$ \algcomment{/* }{ * }{\aeight Exploration of this word is complete and
all rules are satisfied.}{ */}}
\algreturn ;\\
\algelsif{$s==0$}
\algcomment{/* }{ * }{No new information is available for the
checking of \aeight.
However, we do need to check rule if $e$ is odd}{ */}\\
\algcomment{/* }{ * }{Only {\tt TreeLocation} was changed}{ */}\\
\algreturn{\tt ans};\\
\algendif
\end{algtab}
\end{document}
和algcom.sty
包文件
% parameters of algcomment
% #1 "/* " start syntax
% #2 " * " continuation syntax
% #3 the comment text
% #4 " */" end syntax
\long\def\algcomment#1#2#3#4{%
% First use a fake display math to measure the line so far
\abovedisplayskip\z@
\belowdisplayskip\z@
\abovedisplayshortskip\z@
\belowdisplayshortskip\z@
$$\global\dimen1\predisplaysize$$%
% Back up so that the comment will appear to start on the
% already started line.
\vskip-2\baselineskip
% command to output the line number and the continuation marker
\def\addprefix{\alg@putlineno{#2}}%
% start collecting the comment
\setbox2\vbox\bgroup\bgroup
% Reduce the width for line brreaking by the width of #2 to allow for
% the insertion of the prefix string later.
\setbox0\hbox{{#2}}%
\advance\hsize-\wd0
\leavevmode\kern\dimen1\kern-\leftskip\kern-\wd\z@#1#3#4%
% close off the saving of box 2 started above.
\endgraf\egroup\egroup
% So at those point box 2 contains the body of the environment
% with lines broken to a short line length.
%
% count how many lines we're going to add
% need to do this first as we re-add them in reverse order so
% will be decrementing the line count
\dimen0\z@
\@tempcnta\c@algline
\loop
\advance\dimen@\baselineskip
\global\advance\c@algline\@ne
\ifdim\dimen@>\ht2
\else
\repeat
\@tempcntb\c@algline
% Clear box 1 ready to start collecting the modified lines
\global\setbox1\vbox{}%
% Use unbox box2 (onto itself)
\setbox2\vbox{%
\unvbox2
% at this point we are at the end of box 2 now
% loop backwards up the vertical list copying glue and penalties
% but modifying boxesto add the prefix.
\loop
%
% an e-tex primitive that reports the last item in the vertical list.
% type 1 is a box, so remove the box (a lien of text) and then
% put into box 1 a box that is this box together with the prefix which
% was saved in box 0
\ifnum\lastnodetype=1
\global\setbox3\lastbox
\global\setbox1\vbox{%
\hbox{\strut%
\global\advance\c@algline\m@ne
\kern\leftskip
\ifnum\c@algline>\@tempcnta
\addprefix
\else
\global\c@algline\@tempcntb
\global\advance\c@algline\m@ne
\fi
\kern-\leftskip
\box3}%
\unvbox1}%
\fi
%
% type 11 is glue so remove it from this list and add
% equivalent glue to box 1
\ifnum\lastnodetype=11
\skip0\lastskip\unskip
\global\setbox1\vbox{\vskip\skip0\unvbox1}%
\fi
%
% same for penalty
\ifnum\lastnodetype=13
\count0\lastpenalty\unpenalty
\global\setbox1\vbox{\penalty\count0 \unvbox1}%
\fi
%
% other node types are not handled here: either they won't happen
% or they can't be removed anyway so would break the loop \special
% for example would be bad.
%
% -1 means the vertical list is empty: we have reached the top of the box.
\ifnum\lastnodetype=-1
\else
\repeat}%
% Tip the modified box back onto the main list for the page, unbox
% it so that page breaking may still happen (if it could happen in the
% original context).
\vskip\dp\strutbox
\unvbox1
}
原始通用版本
\documentclass{article}
\usepackage{color}
% generate junk filler text for the example
\def\a{Red green blue yellow. }
\def\b{\a\a One two three four. \a\a}
% The code for the start of environment
\def\commentpara#1{%
% save the depth of the previous line (Normally
% TeX uses this automatically but would lose the
% informatiom due to the boxing/reboxing)
\dimen0\prevdepth
% Save the prefix text from `#1` in box 0.
% In this version make it red, probably real code
% should not do that and should just have `#1` you
% could always add colour or font changes in the argument.
\setbox0\hbox{\textcolor{red}{#1}}%
% start saving the paragraph in box 2
\setbox2\vbox\bgroup\bgroup
% by resetting the prevdepth to the saved value
% Tex will automatically insert glue to maintain even spacing
% before the first line.
\prevdepth\dimen0
% Reduce the width for line breaking by the width of box 0 to allow for
% the insertion of the prefix string later.
\advance\hsize-\wd0
% end of begin environment code
}
% The code for the end of the environment.
\def\endcommentpara{%
% close off the saving of box 2 started above.
\endgraf\egroup\egroup
% So at those point box 2 contains the body of the environment
% with lines broken to a short line length.
%
% Clear box 1 ready to start collecting the modified lines
\global\setbox1\vbox{}%
% Use unbox box2 (onto itself)
\setbox2\vbox{%
\unvbox2
% at this point we are at the end of box 2 now
% loop backwards up the vertical list copying glue and penalties
% but modifying boxes to add the prefix.
\loop
%
% an e-tex primitive that reports the last item in the vertical list.
% type 1 is a box, so remove the box (a line of text) and then
% put into box 1 a box that is this box together with the prefix which
% was saved in box 0
\ifnum\lastnodetype=1
\global\setbox3\lastbox
\global\setbox1\vbox{%
\hbox{\copy0\box3}%
\unvbox1}%
\fi
%
% type 11 is glue so remove it from this list and add
% equivalent glue to box 1
\ifnum\lastnodetype=11
\skip0\lastskip\unskip
\global\setbox1\vbox{\vskip\skip0\unvbox1}%
\fi
%
% same for penalty
\ifnum\lastnodetype=13
\count0\lastpenalty\unpenalty
\global\setbox1\vbox{\penalty\count0 \unvbox1}%
\fi
%
% other node types are not handled here: either they won't happen
% or they can't be removed anyway so would break the loop \special
% for example would be bad.
%
% -1 means the vertical list is empty: we have reached the top of the box.
\ifnum\lastnodetype=-1
\else
\repeat}%
% Tip the modified box back onto the main list for the page, unbox
% it so that page breaking may still happen (if it could happen in the
% original context).
\unvbox1
}
\begin{document}
\noindent X \dotfill X
\begin{commentpara}{\# this prefix: }
\b\b
\end{commentpara}
\noindent X \dotfill X
\end{document}
在一个框内,您可以(如本循环所示)剖析框并\lastbox
测量框的宽度等,但在主垂直列表中您不能这样做。一旦框存在,它就存在(直到输出例程,这是另一天的故事),但在显示数学中有一个例外,原始寄存器记录\predisplaysize
显示前部分段落中最后一行文本的长度。
因此,这里的行if e==0
已经设置好了,因此想法是在第一行上用空白设置注释段落,然后将整个框向上移动,-2\baselineskip
使其“插入”到位。
与第一个版本稍有不同,第一行上留下的“间隙”减少了,
\predisplaysize
这\wd0
是连续标记的宽度,因为该标记没有放在第一行,这导致注释的第一个留置权过短。