我依赖于第三方工具的输出,目前我无法真正修改它。它会生成一组与某些源代码的语义注释翻译相对应的命令。通过调整各种命令的定义,我可以将其呈现为语义突出显示的源代码。
我的问题是,每一行源代码都以对换行符命令的调用而终止,这意味着我在代码环境中总是以尾随换行符结束。
下面是显示问题和期望输出的 MWE:
\documentclass{article}
\usepackage{mdframed}
\usepackage{xcolor}
\newenvironment{code}{%
\begin{mdframed}[backgroundcolor=yellow!5, linewidth=0pt]%
}{%
\end{mdframed}%
}
\newcommand{\CodeKeyword}[1]{\texttt{\textbf{#1}}}
\newcommand{\CodeSpace}{\texttt{\hphantom{ }}}
\newcommand{\CodeIdentifier}[1]{\texttt{\color{purple}{#1}}}
\newcommand{\CodeData}[1]{\texttt{\color{red}{#1}}}
\newcommand{\CodeNewline}{\\}
\begin{document}
Current output:
\begin{code}
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}\CodeNewline
\end{code}
I wish it were equivalent to:
%% Same code except for the last \CodeNewline
\begin{code}
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}%\CodeNewline
\end{code}
\end{document}
编辑:我当前的解决方案是使用Makefile
生成perl
的文件进行后处理,如下所示:
perl -0777 -i -pe 's/\\CodeNewline{}\n\\end{code}/\n\\end{code}/igs'
(来源:这个 SO 答案https://unix.stackexchange.com/a/26289/159035)
答案1
重新定义\CodeNewline
为\par
并删除标准缩进。
\documentclass{article}
\usepackage{mdframed}
\usepackage{xcolor}
\newenvironment{code}{%
\setlength{\parindent}{0pt}%
\begin{mdframed}[backgroundcolor=yellow!5, linewidth=0pt]%
}{%
\end{mdframed}%
}
\newcommand{\CodeKeyword}[1]{\texttt{\textbf{#1}}}
\newcommand{\CodeSpace}{\texttt{\hphantom{ }}}
\newcommand{\CodeIdentifier}[1]{\texttt{\color{purple}{#1}}}
\newcommand{\CodeData}[1]{\texttt{\color{red}{#1}}}
\newcommand{\CodeNewline}{\par}
\begin{document}
Current output:
\begin{code}
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}\CodeNewline
\end{code}
I wish it were equivalent to:
%% Same code except for the last \CodeNewline
\begin{code}
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}%\CodeNewline
\end{code}
\end{document}
答案2
您可以重新定义\CodeNewline
以查看下一个标记;如果相等\end
则不执行任何操作。否则插入换行符。
\newcommand{\CodeNewline}[1]{\ifx#1\end\relax\else\\\fi#1}
但是,这样做只会删除环境末尾的最后一个换行符。如果您以多个换行符结束环境,我认为您也希望删除所有换行符。因此,我们可以进一步编辑定义以跟踪我们看到的换行符数量。
在此基础上,我们还可以使多个连续的\CodeNewline
s 插入比完整空白行更多或更少的空间。
\documentclass{article}
\usepackage{mdframed}
\usepackage{xcolor}
% One can use two consecutive \CodeNewline to get a blank line,
% but maybe we don't want a full blank line and just want some extra space
% this length defines how tall the blank line(s) ought to be.
\newlength\codeextrabaselineskip
\setlength\codeextrabaselineskip{0.6\baselineskip}
\newcounter{gallaisNLcount}
\newenvironment{code}{%
\begin{mdframed}[backgroundcolor=yellow!5, linewidth=1pt]% changed linewidth so you can see effect
\setcounter{gallaisNLcount}{0}
}{%
\end{mdframed}%
}
\newcommand{\CodeKeyword}[1]{\texttt{\textbf{#1}}}
\newcommand{\CodeSpace}{\texttt{\hphantom{ }}}
\newcommand{\CodeIdentifier}[1]{\texttt{\color{purple}{#1}}}
\newcommand{\CodeData}[1]{\texttt{\color{red}{#1}}}
% Tests for the next token. If it is equal to \end we do nothing.
% If it is equal to another \CodeNewline we increment the count of currently seen newlines.
% For anything else, it prints a linebreak with extra space proportional to the number of newlines seen, and resets the counter.
% Whatever we do, put the next token back where it ought to be, since we are just peeking, not processing.
\newcommand{\CodeNewline}[1]{\ifx#1\end\relax\else\ifx#1\CodeNewline\stepcounter{gallaisNLcount}\else\\[\thegallaisNLcount\codeextrabaselineskip]\setcounter{gallaisNLcount}{0}\fi\fi#1}
\begin{document}
Current output:
\begin{code}
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}\CodeNewline\CodeNewline\CodeNewline
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}\CodeNewline\CodeNewline
\CodeKeyword{let}\CodeSpace{}\CodeIdentifier{x}\CodeSpace{}\CodeNewline
\CodeSpace{}\CodeSpace{}\CodeKeyword{=}\CodeSpace{}\CodeData{1}\CodeNewline\CodeNewline
\end{code}
\end{document}