无空格无大写标记列表

无空格无大写标记列表

这花了我比预期更长的时间来完成本来应该非常简单的任务。我需要一种方法来将 tokenlist 变成小写并删除空格。但str_lowercase:N不存在!尝试生成变体失败了。我尝试过的任何组合\MakeLowercase\tl_remove_all:Nn不能很好地协同工作。我最终使用了两个辅助函数来完成这项工作。解决方案到目前为止有效。我把这个问题分成两部分,一是记录我的解决方案,二是询问是否有更好的方法,最好只使用 expl3。

% this function exists to simplify the call for the other, reducing the number of arguments to 1.
\cs_new_protected:Npn \tl_lowercase:N #1
    { \bob_tl_lowercase:No #1 #1 }

% this function and its generated varient cause arguement 2 to expand once 
% so it can be accepted by \str_lowercase:n, then sets it to itself
\cs_new_protected:Npn \bob_tl_lowercase:Nn #1#2
    { \tl_set:Nx #1 { \str_lowercase:n {#2} } }
\cs_generate_variant:Nn \bob_tl_lowercase:Nn { No }

% just a example use case function
\tl_new:N \itemfilename
\NewDocumentCommand{\getfilename}{s+m} {
    \tl_set:Nn \itemfilename {#2}
    \tl_remove_all:Nn \itemfilename {~}
    \tl_lowercase:N \itemfilename
    \tl_show:N \itemfilename
}

答案1

有,\str_lowercase:n而且它是完全可扩展的,但是(正如约瑟夫正确指出的)还有更好的\str_foldcase:n

\str_new:N \l_bob_itemfilename_str

\NewDocumentCommand{\getfilename}{m}
 {
  \str_set:Nx \l_bob_itemfilename_str { \str_foldcase:n { #1 } }
  \str_replace_all:Nnn \l_bob_itemfilename_str { ~ } { }
  \str_show:N \l_bob_itemfilename_str
 }

\getfilename{SaMPleName WITH upperCase and SPACES}

控制台显示

> \l_bob_itemfilename_str=samplenamewithuppercaseandspaces.

改进的版本可以管理已经构建的令牌列表或字符串:

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\getfilename}{sm}
 {
  \IfBooleanTF { #1 }
   {
    \bob_filename_get:V #2
   }
   {
    \bob_filename_get:n { #2 }
   }
 }

\str_new:N \l_bob_filename_item_str

\cs_new_protected:Nn \bob_filename_get:n
 {
  \str_set:Nx \l_bob_filename_item_str { \str_foldcase:n { #1 } }
  \str_replace_all:Nnn \l_bob_filename_item_str { ~ } { }
  \str_show:N \l_bob_filename_item_str
 }
\cs_generate_variant:Nn \bob_filename_get:n { V }

\getfilename{SaMPleName WITH upperCase and SPACES}

\def\test{SaMPleName WITH upperCase and SPACES}

\getfilename*{\test}

无论哪种情况,控制台都会有

> \l_bob_filename_item_str=samplenamewithuppercaseandspaces.

答案2

环顾四周后,我认为这是该问题的正确答案。

 \tl_set:Nx \itemfilename { \str_foldcase:V \itemfilename }

一个重要的信息是\str_foldcase“该过程的结果留在输入流中。”即使手册中没有提到,这对于 str_lowercase 似乎也是如此。

仔细阅读手册后发现,“[ str_lowercase:n] 函数不应用于不区分大小写的比较”。

然而,我在以下方面也取得了成功。

\cs_generate_variant:Nn \str_lowercase:n {V}
\tl_set:Nx \itemfilename { \str_lowercase:V \itemfilename }.

答案3

这是一种无需 expl3 的方法……相反,它使用标记循环来删除空格并将字符引导至宏\explowercase

这里设置了预扩展其参数,以便它可以与字符串或\def字符串一起使用。

\documentclass{article}
\def\explowerchar#1{%
  \ifcase\numexpr`#1-`A\relax
   a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m\or
   n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\else
   #1\fi
}
\usepackage{tokcycle}
\Characterdirective{\addcytoks[x]{\explowerchar{#1}}}
\Spacedirective{}
\newcommand\getfilename[1]{\expandedtokcyclexpress{#1}\the\cytoks}
\begin{document}
\getfilename{SaMPleName WITH upperCase and SPACES}

\def\test{SaMPleName WITH upperCase and SPACES}
\getfilename{\test}
\end{document}

在此处输入图片描述

相关内容