[类似问题] 我在看\lowercase 与 \IfSubStr 和 \StrDel但这些建议不起作用。我显然可能有 expl3,因为我可以使用 \newcommand。
[问题] 我想将变量传递给命令,让命令扩展变量,将值小写,执行 \IfSubStr,如果小写值匹配,则创建新命令。问题是我找不到让 \IfSubStr 将变量值小写的方法。
[工具]
FMPP 版本 0.9.16,构建于 2018-09-03T21:47:30Z 当前使用 FreeMarker 版本 2.3.28
pandoc 2.7.3 使用 pandoc-types 1.17.5.4、texmath 0.11.2.2、skylighting 0.8.1 编译 版权所有 (C) 2006-2019 John MacFarlane
[建造]
在 pdfTex 中执行以下操作
[来源]
\documentclass{report}
\usepackage{xstring}
\begin{document}
\def\abcVariable{abc}
\def\DEFVariable{DEF}
\def\refVariable{nothing}
\def\dbgstr{debug}
\newcommand{\setCmd}[3]{%
\lowercase{\def\tmpa{#1}}%
\lowercase{\edef\tmpb{#2}}%
\IfSubStr{\tmpa}{\tmpb}
{\renewcommand{#3}{#2}}{%
\edef\dbgstr{inputs: #1, #2; lowercased: \tmpa, \tmpb}%
}
}
\newcommand{\setVariable}[1]{%
\setCmd{#1}{\abcVariable}{\refVariable}%
\setCmd{#1}{\DEFVariable}{\refVariable}%
}
\setVariable{thishasdefinthemiddle}
\refVariable
\dbgstr
\end{document}
[回复]
未输入任何内容:thishasadefinthemiddle,DEF;小写:thishasadefinthemiddle,DEF
[预期的]
DEF 输入:thishasadefinthemiddle,DEF;小写:thishasadefinthemiddle,def
【调试1】
使用 是\setCmd{#1}{\abcVariable}{\refVariable}%
可行的,但理由不正确。然后我考虑\setCmd{#1}{\DEFVariable}{\refVariable}%
。我认为\lowercase{\def\tmpa{#1}}%
扩展到\lowercase{\def\tmpa{abcdef}}%
然后分配\tmpa
给abcdef
。太好了。我认为\lowercase{\edef\tmpb{#2}}%
扩展到\lowercase{\edef\tmpb{\DEFVariable}}%
然后
- 小写,
\edef\tmpb{\DEFVariable}}%
因为\lowercase
csnames 不是小写,或者 - 小写为
\edef\tmpb{\defvariable}}%
然后应该抱怨\defvariable
不存在,或者 - 小写并扩展
\defvariable
为DEF
,或 - 由于某种原因只是停止扩张。
然后\IfSubStr{\tmpa}{\tmpb}
扩展到 ,\IfSubStr{abcdef}{\DEFVariable}
然后扩展到\IfSubStr{abcdef}{DEF}
,然后运行 {false} 路径。我需要\DEFVariable
完全扩展到DEF
,然后将其小写\IfSubStr
。
[调试2]
然后我尝试发出一个命令来执行小写转换:
\newcommand{\mylwr}[1]{%
\edef\x{%
\noexpand\edef\noexpand\tmpb{\text_lowercase:n #1}}%
\x}
并替换\lowercase{\edef\tmpb{#2}}%
为\mylwr{#2}
,但得到的是Missing $ inserted / 1.88 dbgstr: \dbgstr
,所以我可能没有带有 的包\text_lowercase:n
。但使用\lowercase
会给出输出:
setVariable:
refVariable: nothing
dbgstr: inputs: abcdef, DEF; lowercased: abcdef, def
看起来很棒,直到您意识到 \IfSubStr 失败,并且只有在写入输出时,完全扩展才会产生小写的def
。
[调试3]
然后我尝试创建该命令的替代命令\IfSubStr
:
\newcommand{\IfSubStrIC}[2]{%
\lowercase{\edef\x{\noexpand\IfSubStr{#1}{\expanded{#2}}}}%
\x}
输出结果为:
setVariable:
refVariable: abc
dbgstr: inputs: abcdef, DEF; lowercased: abcdef, DEF
[调试4]
我尝试了各种\expanded
方法\expandafter
试图\expandafter\expandafter
将变量扩展为小写,但没有任何效果。
有谁知道如何从变量中获取值并将其小写\IfSubStr
,或者以某种方式执行等效操作?
答案1
\lowercase
您需要在处理令牌列表之前扩展宏。
假设你有\def\foo{baz}
。如果你有
\lowercase{\edef\tmpa{\foo}}
你得到的结果与 完全相同\edef\tmpa{\foo}
,因为\lowercase
只有变化字符标记. 你可能会
\lowercase\expandafter{\expandafter\def\expandafter\tmpa\expandafter{\foo}}
所以它\foo
在开始工作之前就被扩展了。但是如果你有更复杂的东西可以扩展为字符标记,比如两个宏,那么\lowercase
这种方法就行不通了。\foo
为了解决这个问题\expanded
,如果您确定使用了较新版本的 pdftex(或其他引擎),您可以使用。
\newcommand{\setCmd}[3]{%
\expanded{\lowercase{\def\noexpand\tmpa{#1}}}%
\expanded{\lowercase{\def\noexpand\tmpb{#2}}}%
\IfSubStr{\tmpa}{\tmpb}
{\renewcommand{#3}{#2}}% true
{\edef\dbgstr{inputs: #1, #2; lowercased: \tmpa, \tmpb}}% false
}
否则,通常的伎俩是:
\newcommand{\setCmd}[3]{%
\begingroup\edef\x{\endgroup
\lowercase{\def\noexpand\tmpa{#1}}%
}\x
\begingroup\edef\x{\endgroup
\lowercase{\def\noexpand\tmpb{#2}}%
}\x
\IfSubStr{\tmpa}{\tmpb}
{\renewcommand{#3}{#2}}% true
{\edef\dbgstr{inputs: #1, #2; lowercased: \tmpa, \tmpb}}% false
}