修剪环境中常见的前导空格

修剪环境中常见的前导空格

我有一个可执行文件,它对包含文学代码的文件执行语义突出显示。它输出一个.tex文件,我可以使用 catchfilebetweentags 从中获取代码片段。

我面临的一个问题是缩进的代码总是以空格开头。我想摆脱共享前缀对应于缩进,同时保留某些行中可能存在的进一步的前导空格,因为在源语言中缩进是有意义的。

以下是作为 MWE 的一个典型示例:

\documentclass[11pt]{article}

%%% Code typesetting preamble

\newcommand{\CodeSpace}{\hphantom{ }}
\newcommand{\CodeNewLine}{\\}
\newcommand{\CodeKeyword}[1]{\textbf{#1}}
\newcommand{\CodeIdentifier}[1]{\textit{#1}}

\newenvironment{code}
    {\vspace{1em}\noindent\begin{minipage}{\linewidth}\obeyspaces\ttfamily}
    {\end{minipage}}

%%%

\begin{document}

\section{No leading whitespace}

\begin{code}
\CodeKeyword{let}\CodeSpace\CodeIdentifier{id}\CodeSpace\CodeIdentifier{xs}\CodeNewLine
\CodeSpace\CodeSpace\CodeKeyword{=}\CodeSpace\CodeIdentifier{xs}
\end{code}

\section{Annoying leading whitespace}

\begin{code}
\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeKeyword{let}\CodeSpace\CodeIdentifier{id}\CodeSpace\CodeIdentifier{xs}\CodeNewLine
\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeKeyword{=}\CodeSpace\CodeIdentifier{xs}
\end{code}

\end{document}

它的渲染方式如下,理想情况下,两个部分应该看起来相同:

在此处输入图片描述

code我很高兴改变环境或原始命令的定义\CodeX

答案1

改编

  • 添加布尔值firstlinestartlinestart(使用\newtoggleetoolbox
  • 添加计数器currentcodespacescodespaces
  • 扩展\CodeSpace
    • 用计数器计算空格数currentcodespaces
    • 如果在第一行的开头 ( firstlinestart) 或者在另一行的开头 ( linestart) 并且currentcodespaces<= 则忽略空格codespaces
  • 定义了一个命令\CodeNoSpace,该命令应由每个代码命令调用,但以下命令除外\CodeSpace
    • 切换linestart为 false
    • codespaces如果是第一行,则设置计数器
  • 扩展\CodeNewLine
    • 重置currentcodespaces为 0 和linestarttrue
    • 调试时可选:显示原来的前导空格(红色)
  • code环境将两个切换设置为 true,并将计数器设置currentcodespaces为 0

代码

\documentclass[11pt]{article}

\usepackage{xcolor}
\usepackage{etoolbox}

%%% Code typesetting preamble
\newtoggle{firstlinestart}
\newtoggle{linestart}
\newcounter{currentcodespaces}
\newcounter{codespaces}

\newcommand{\CodeNoSpace}{%
    % This command should be called by each Code command that is not \CodeSpace
    \togglefalse{linestart}%
    \iftoggle{firstlinestart}{%
        \togglefalse{firstlinestart}%
        \setcounter{codespaces}{\thecurrentcodespaces}%
    }{}%
}

\newcommand{\CodeSpace}{%
    \stepcounter{currentcodespaces}%
    \ifboolexpe{
        togl{firstlinestart} or (
            togl{linestart} and test{ \ifnumless{ \value{currentcodespaces} }{ \value{codespaces} + 1 } } 
        )
    }{%
        % ignore spaces
    }{%
        \hphantom{ }%
    }%
}

\newcommand{\CodeNewLine}{%
    \CodeNoSpace%
    \quad\textcolor{red}{\footnotesize\textrm{(originally: \arabic{codespaces} leading spaces)}}% this line is just for debugging
    \\%
    \setcounter{currentcodespaces}{0}%
    \toggletrue{linestart}%
}

\newcommand{\CodeKeyword}[1]{\CodeNoSpace\textbf{#1}}
\newcommand{\CodeIdentifier}[1]{\CodeNoSpace\textit{#1}}

\newenvironment{code}{%
    \vspace{1em}%
    \noindent%
    \begin{minipage}{\linewidth}%
    \obeyspaces%
    \ttfamily%
    \setcounter{currentcodespaces}{0}
    \toggletrue{firstlinestart}
    \toggletrue{linestart}
}{%
    \end{minipage}%
}

%%%

\begin{document}

\section{No leading whitespace}

\begin{code}
\CodeKeyword{let}\CodeSpace\CodeIdentifier{id}\CodeSpace\CodeIdentifier{xs}\CodeNewLine
\CodeSpace\CodeSpace\CodeKeyword{=}\CodeSpace\CodeIdentifier{xs}
\end{code}

\section{No annoying leading whitespace anymore}

\begin{code}
\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeKeyword{let}\CodeSpace\CodeIdentifier{id}\CodeSpace\CodeIdentifier{xs}\CodeNewLine
\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeKeyword{=}\CodeSpace\CodeIdentifier{xs}
\end{code}

\begin{code}
\CodeSpace\CodeSpace\CodeKeyword{let}\CodeSpace\CodeIdentifier{id}\CodeSpace\CodeIdentifier{xs}\CodeNewLine
\CodeSpace\CodeSpace\CodeSpace\CodeSpace\CodeKeyword{=}\CodeSpace\CodeIdentifier{xs}
\end{code}

\end{document}

结果

在此处输入图片描述

相关内容