解析前导硬空格

解析前导硬空格

这个问题与这个问题相关(但不同):将 \$ 解析为改进的 \getargs 命令的一部分,我之前问过。

我尝试从字符串结果中删除所有空格(常规空格和硬空格),结果中出现了残留空格。当参数仅包含常规空格时,该例程效果很好;当参数包含不在前导位置的硬空格时,该例程效果很好。但它无法删除前导硬空格。如果我在参数前加上多个硬空格,它会删除除一个之外的所有硬空格。

如果可能的话,我希望保留这种逻辑方法(递归)来解决问题,因为它速度快,并且适合正在开发的更大的算法。我不确定是什么让前导硬空间与其他硬空间不同,或者我的编码只是没有构造来捕捉前导空间(我认为是的)。

以下是输入(注意:重新编辑以最小化 MWE 的内容):

\documentclass{article}
\usepackage{ifnextok}
\usepackage{ifthen}
\makeatletter
\def\stringend{$}
\def\add@space{\protected@edef\thestring{\thestring\@sptoken}}
\newcommand\noblanksF[2][v]{%
  \def\thestring{}\expandafter\eat@Block#2\stringend%
  \if v#1\thestring\fi} 
\def\eat@Block{\IfNextToken\stringend%
  {\@gobble}%
  {\add@tostring{\eat@Block}}%
}
\def\add@tostring#1#2{%
  \ifthenelse{\equal{#2}{~}}%
    {}%
    {\if\@sptoken#2\else\protected@edef\thestring{\thestring#2}\fi}%
  #1}
\makeatother
\parindent 0in\def\bl{\rule{1ex}{1ex}}
\begin{document}
Testing noblanks: \\
\bl\noblanksF{This is a test with 0 leading spaces}\bl\\
\bl\noblanksF{ This is a test with 1 leading space}\bl\\
\bl\noblanksF{  This is a test with 2 leading spaces}\bl\\
\bl\noblanksF{  This  is  a  test  with  2  spaces  (lead+everywhere)}\bl\\
FROM HERE OUT, RESULTS LEAVE ONE LEADING SPACE:\\
\bl\noblanksF{~This is a test with 1 leading hardspace}\bl\\
\bl\noblanksF{~~This is a test with 2 leading hardspaces}\bl\\
\bl\noblanksF{~~~This is a test with 3 leading hardspaces}\bl\\
\bl\noblanksF{~~~~This is a test with 4 leading hardspaces}\bl\\
\bl\noblanksF{~~This~~is~~a~~test~~with~~2~~hardspaces~~(lead+everywhere)}\bl
\end{document}

答案1

经典 TeX 实际上没有“硬空格”,也就是说 U+00a0(html 中的 nbsp)~是一个宏,它扩展为一些命令,这些命令会创建空格并防止换行,但实际上这并不是一回事。由于~是一个宏,因此让它消失的最简单方法是将其定义为扩展为零。我建议使用下面的一些代码,它会产生

[Thisisatestwith2hardspaces(lead+everywhere)]

您应该能够将它与代码结合起来以删除

\documentclass{article}

\makeatletter

\def\remtilde#1{{%
\let~\@empty
\protected@xdef\thestring{#1}%
\typeout{[\thestring]}}}


\remtilde{~~This~~is~~a~~test~~with~~2~~hardspaces~~(lead+everywhere)}

\stop

答案2

如果只是为了删除空格,如果你想节省时间,为什么不在读取参数时更改它们的 catcode?没有循环,没有递归,最重要的是,没有\edef全局变量来存储参数\thestring

\documentclass{article}
\usepackage[T1]{fontenc}
\makeatletter
\newcommand\noblanksF[1][v]{%
    \edef\opt@arg{\expandafter\@car\detokenize{#1}\@nil}%
    \begingroup
        \ifnum\catcode`\~=\active\catcode`\~9 \fi
        \catcode32=9
        \afterassignment\noblankF@i
        \def\thestring}

\newcommand\noblankF@i{%
        \expandafter
    \endgroup
    \expandafter\def\expandafter\thestring\expandafter{\thestring}%
    \if\string v\opt@arg\expandafter\thestring\fi}
\makeatother
\def\bl{\vrule height1ex width1ex depth0pt }
\begin{document}
\parindent 0pt
Testing noblanks: \par
\bl\noblanksF{This is a test with 0 leading spaces}\bl\par
\bl\noblanksF{ This is a test with 1 leading space}\bl\par
\bl\noblanksF{  This is a test with 2 leading spaces}\bl\par
\bl\noblanksF{  This  is  a  test  with  2  spaces  (lead+everywhere)}\bl\par
FROM HERE OUT, RESULTS LEAVE ONE LEADING SPACE:\par
\bl\noblanksF{~This is a test with 1 leading hardspace}\bl\par
\bl\noblanksF{~~This is a test with 2 leading hardspaces}\bl\par
\bl\noblanksF{~~~This is a test with 3 leading hardspaces}\bl\par
\bl\noblanksF{~~~~This is a test with 4 leading hardspaces}\bl\par
\bl\noblanksF{~~This~~is~~a~~test~~with~~hardspaces~~~and~maths$1+1=2$!}\bl\par
\catcode`\~12 % "~" become a "other" char
HERE, "~" IS A NORMAL CHAR:\par
\bl\noblanksF{~~This~~is~~a~~test~~with~NO~hardspaces~~~and~maths$1+1=2$!}\bl
\end{document}

相关内容