我正在运行 MacTeX 2022,并应用了所有更新。我有一个大型项目,上次正确构建是在 2022 年 9 月 3 日。今天我Missing \endcsname inserted
在某一行上遇到了一个神秘的错误,我找不到原因。按下H
控制台显示\let
控制序列错误地存在,\csname...\endcsname
但我的代码中没有\let
。MWE 代码已从源项目直接复制并粘贴到 MWE.sty
和.tex
文件中。唯一的变化是不断重命名某些变量。MWE 完全复制了错误。
自 2022 年 9 月以来,此代码一直未被触及,因此自 9 月以来的更新中出现的问题可能是罪魁祸首。我看到的唯一可能相关的事情是使用\MakeUppercase
(因为我知道最近对此进行了一些修改)或密钥处理机制。是什么导致了此错误?
编辑:我需要单词alternate
、base
和derived
在通过 回显到控制台时全部小写,typeout
但在用于调用相应宏时首字母大写。这就是为什么我最初使用 的原因,\MakeUppercase
现在似乎不起作用。我无法\MakeTitlecase
工作。
这是 MWE 包文件。将其命名为keymwe.sty
。
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\usepackage{pgfopts}
\usepackage{iftex}
\RequireLuaTeX
\newcommand*{\keymwe@selectunits}{}
\newcommand*{\keymwe@selectprecision}{}
\newcommand*{\keymwe@selectapproximate}[2]{#1}
\newcommand*{\keymwe@selectprecise}[2]{#2}
\newcommand*{\keymwe@selectbaseunits}[3]{#1}
\newcommand*{\keymwe@selectderivedunits}[3]{#2}
\newcommand*{\keymwe@selectalternateunits}[3]{#3}
\NewDocumentCommand{\AlwaysUseBaseUnits}{}
{\renewcommand*{\keymwe@selectunits}{\keymwe@selectbaseunits}}%
\NewDocumentCommand{\AlwaysUseDerivedUnits}{}
{\renewcommand*{\keymwe@selectunits}{\keymwe@selectderivedunits}}%
\NewDocumentCommand{\AlwaysUseAlternateUnits}{}
{\renewcommand*{\keymwe@selectunits}{\keymwe@selectalternateunits}}%
\NewDocumentCommand{\AlwaysUseApproximateConstants}{}
{\renewcommand*{\keymwe@selectprecision}{\keymwe@selectapproximate}}%
\NewDocumentCommand{\AlwaysUsePreciseConstants}{}
{\renewcommand*{\keymwe@selectprecision}{\keymwe@selectprecise}}%
\NewDocumentCommand{\HereUseBaseUnits}{ m }{\begingroup\AlwaysUseBaseUnits#1\endgroup}%
\NewDocumentCommand{\HereUseDerivedUnits}{ m }{\begingroup\AlwaysUseDerivedUnits#1\endgroup}%
\NewDocumentCommand{\HereUseAlternateUnits}{ m }{\begingroup\AlwaysUseAlternateUnits#1\endgroup}%
\NewDocumentCommand{\HereUseApproximateConstants}{ m }{\begingroup\AlwaysUseApproximateConstants#1\endgroup}%
\NewDocumentCommand{\HereUsePreciseConstants}{ m }{\begingroup\AlwaysUsePreciseConstants#1\endgroup}%
\NewDocumentEnvironment{UseBaseUnits}{}{\AlwaysUseBaseUnits}{}%
\NewDocumentEnvironment{UseDerivedUnits}{}{\AlwaysUseDerivedUnits}{}%
\NewDocumentEnvironment{UseAlternateUnits}{}{\AlwaysUseAlternateUnits}{}%
\NewDocumentEnvironment{UseApproximateConstants}{}{\AlwaysUseApproximateConstants}{}%
\NewDocumentEnvironment{UsePreciseConstants}{}{\AlwaysUsePreciseConstants}{}%
\newif\ifusingpreciseconstants
\pgfkeys{%
/keymwe/options/.cd,
initial@setup/.style={%
/keymwe/options/buffered@units/.initial=alternate,%
},%
initial@setup,%
preciseconstants/.is if=usingpreciseconstants,%
units/.is choice,%
units/.default=derived,%
units/alternate/.style={/keymwe/options/buffered@units=alternate},%
units/base/.style={/keymwe/options/buffered@units=base},%
units/derived/.style={/keymwe/options/buffered@units=derived},%
.unknown/.code={%
\typeout{}%
\typeout{keymwe: You used unknown option '\pgfkeyscurrentname'.}%
},%
}%
\ProcessPgfPackageOptions{/keymwe/options}
\newcommand*{\keymwe@do@setup}{%
\csname AlwaysUse\expanded{\noexpand\MakeUppercase%
\pgfkeysvalueof{/keymwe/options/buffered@units}}Units\endcsname%
\typeout{keymwe: You will get \pgfkeysvalueof{/keymwe/options/buffered@units}\space units.}%
\ifusingpreciseconstants
\AlwaysUsePreciseConstants
\typeout{keymwe: You will get precise constants.}%
\else
\AlwaysUseApproximateConstants
\typeout{keymwe: You will get approximate constants.}%
\fi
\typeout{}%
}%
\keymwe@do@setup
\NewDocumentCommand{\keymwesetup}{ m }%
{%
\IfValueT{#1}%
{%
\pgfqkeys{/keymwe/options}{#1}
\typeout{}%
\typeout{keymwe: keymwesetup options...}
\keymwe@do@setup
}%
}%
这是使用测试包的 MWE 文档。将其命名为keymwe.tex
。
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{keymwe}
\begin{document}
Hello, world.
\end{document}
答案1
定义一个可扩展的字符串大小写转换函数。这里
\ExplSyntaxOn
\NewExpandableDocumentCommand{\Titlecasestring}{m}
{
\str_uppercase:f { \str_head:e { #1 } } \str_tail:e { #1 }
}
\cs_generate_variant:Nn \str_head:n { e }
\cs_generate_variant:Nn \str_tail:n { e }
\ExplSyntaxOff
首先\str_head:e
展开参数,然后取出所获字符串中的第一个项。这里使用字符串是因为构造要在 内部使用\csname
。
完整代码。
\usepackage{pgfopts}
\usepackage{iftex}
\RequireLuaTeX
\newcommand*{\keymwe@selectunits}{}
\newcommand*{\keymwe@selectprecision}{}
\newcommand*{\keymwe@selectapproximate}[2]{#1}
\newcommand*{\keymwe@selectprecise}[2]{#2}
\newcommand*{\keymwe@selectbaseunits}[3]{#1}
\newcommand*{\keymwe@selectderivedunits}[3]{#2}
\newcommand*{\keymwe@selectalternateunits}[3]{#3}
\NewDocumentCommand{\AlwaysUseBaseUnits}{}
{\renewcommand*{\keymwe@selectunits}{\keymwe@selectbaseunits}}
\NewDocumentCommand{\AlwaysUseDerivedUnits}{}
{\renewcommand*{\keymwe@selectunits}{\keymwe@selectderivedunits}}
\NewDocumentCommand{\AlwaysUseAlternateUnits}{}
{\renewcommand*{\keymwe@selectunits}{\keymwe@selectalternateunits}}
\NewDocumentCommand{\AlwaysUseApproximateConstants}{}
{\renewcommand*{\keymwe@selectprecision}{\keymwe@selectapproximate}}
\NewDocumentCommand{\AlwaysUsePreciseConstants}{}
{\renewcommand*{\keymwe@selectprecision}{\keymwe@selectprecise}}
\NewDocumentCommand{\HereUseBaseUnits}{ m }{\begingroup\AlwaysUseBaseUnits#1\endgroup}
\NewDocumentCommand{\HereUseDerivedUnits}{ m }{\begingroup\AlwaysUseDerivedUnits#1\endgroup}
\NewDocumentCommand{\HereUseAlternateUnits}{ m }{\begingroup\AlwaysUseAlternateUnits#1\endgroup}
\NewDocumentCommand{\HereUseApproximateConstants}{ m }{\begingroup\AlwaysUseApproximateConstants#1\endgroup}
\NewDocumentCommand{\HereUsePreciseConstants}{ m }{\begingroup\AlwaysUsePreciseConstants#1\endgroup}
\NewDocumentEnvironment{UseBaseUnits}{}{\AlwaysUseBaseUnits}{}
\NewDocumentEnvironment{UseDerivedUnits}{}{\AlwaysUseDerivedUnits}{}
\NewDocumentEnvironment{UseAlternateUnits}{}{\AlwaysUseAlternateUnits}{}
\NewDocumentEnvironment{UseApproximateConstants}{}{\AlwaysUseApproximateConstants}{}
\NewDocumentEnvironment{UsePreciseConstants}{}{\AlwaysUsePreciseConstants}{}
\newif\ifusingpreciseconstants
\pgfkeys{
/keymwe/options/.cd,
initial@setup/.style={
/keymwe/options/buffered@units/.initial=alternate,
},
initial@setup,
preciseconstants/.is if=usingpreciseconstants,
units/.is choice,
units/.default=derived,
units/alternate/.style={/keymwe/options/buffered@units=alternate},
units/base/.style={/keymwe/options/buffered@units=base},
units/derived/.style={/keymwe/options/buffered@units=derived},
.unknown/.code={%
\typeout{}%
\typeout{keymwe: You used unknown option '\pgfkeyscurrentname'.}%
},
}
\ProcessPgfPackageOptions{/keymwe/options}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\Titlecasestring}{m}
{
\str_uppercase:f { \str_head:e { #1 } } \str_tail:e { #1 }
}
\cs_generate_variant:Nn \str_head:n { e }
\cs_generate_variant:Nn \str_tail:n { e }
\ExplSyntaxOff
\newcommand*{\keymwe@do@setup}{%
\csname AlwaysUse\Titlecasestring{\pgfkeysvalueof{/keymwe/options/buffered@units}}Units\endcsname
\typeout{keymwe: You will get \pgfkeysvalueof{/keymwe/options/buffered@units}\space units.}%
\ifusingpreciseconstants
\AlwaysUsePreciseConstants
\typeout{keymwe: You will get precise constants.}%
\else
\AlwaysUseApproximateConstants
\typeout{keymwe: You will get approximate constants.}%
\fi
\typeout{}%
}%
\keymwe@do@setup
\NewDocumentCommand{\keymwesetup}{ m }%
{%
\IfValueT{#1}%
{%
\pgfqkeys{/keymwe/options}{#1}%
\typeout{}%
\typeout{keymwe: keymwesetup options...}%
\keymwe@do@setup
}%
}