在自定义环境中删除尾随换行符

在自定义环境中删除尾随换行符

我依赖于第三方工具的输出,目前我无法真正修改它。它会生成一组与某些源代码的语义注释翻译相对应的命令。通过调整各种命令的定义,我可以将其呈现为语义突出显示的源代码。

我的问题是,每一行源代码都以对换行符命令的调用而终止,这意味着我在代码环境中总是以尾随换行符结束。

下面是显示问题和期望输出的 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}

但是,这样做只会删除环境末尾的最后一个换行符。如果您以多个换行符结束环境,我认为您也希望删除所有换行符。因此,我们可以进一步编辑定义以跟踪我们看到的换行符数量。

在此基础上,我们还可以使多个连续的\CodeNewlines 插入比完整空白行更多或更少的空间。

\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}

在此处输入图片描述

相关内容