结合 expandafter、setlength、csname 和 define@key

结合 expandafter、setlength、csname 和 define@key

我尝试定义一个命令\tes@define@key@length。一切正常,但是当我使用以下行时:

\expandafter\setlength\csname test@#1@length\endcsname{\csname testl@#1\endcsname}%

我收到错误。下面是我注释特殊行的示例:

\setcounter{errorcontextlines}{999}
\RequirePackage{filecontents}
\begin{filecontents*}{testpaket.sty}
\RequirePackage{kvoptions}
\RequirePackage{etoolbox}
\SetupKeyvalOptions{family=test,prefix=test@}

\newlength{\tes@templength}
\def\test@defaultunit{pt}
\def\tes@iflength#1{%
  \afterassignment\tes@iflength@check%
  \tes@templength=#1\test@defaultunit\relax\relax
  \expandafter\endgroup\next
}
\def\tes@iflength@check#1{%
  \begingroup
  \ifx\relax#1\@empty
    \def\next{\@secondoftwo}
  \else
    \def\next{\@firstoftwo}
    \expandafter\tes@iflength@cleanup
  \fi
}
\def\tes@iflength@cleanup#1\relax{}


%#1 Bezeichnung Länge
%#2 Defaultwert Länge
\newrobustcmd*{\tes@optionlength}[2]{%
 \csxdef{test@#1}{#1 wurde definiert}
 \gdef\test@default{#2 ist der Defaultwert}
 \expandafter\newlength\csname test@#1@length\endcsname
 \expandafter\setlength\csname test@#1@length\endcsname{#2}%
}
%#1 option
\newrobustcmd*{\tes@define@key@length}[1]{%
  \define@key{test}{#1}{%
     \def\@tempa{##1}
     \tes@iflength{\@tempa}%
     {\csxdef{testl@#1}{\the\tes@templength}}%
     {\csxdef{testl@#1}{\the\tes@templength}}%
%    \expandafter\setlength\csname test@#1@length\endcsname{\csname testl@#1\endcsname}%
    }
}
\def\tes@define@key@@length{\define@key{mdf}}

\tes@define@key@length{skipabove}

\ProcessKeyvalOptions*

\end{filecontents*}
\documentclass{article}
\usepackage[skipabove=40pt]{testpaket}
\begin{document}
\makeatletter
\tes@iflength{12pt}{ja}{nein}
\tes@iflength{12}{ja}{nein}

\tes@optionlength{skipabove}{4pt}
\test@skipabove\
\test@default\

\the\test@skipabove@length

\advance\test@skipabove@length by 2pt

\the\test@skipabove@length

\testl@skipabove
\makeatother
\end{document}

答案1

\test@skipabove@length直到使用 时才被定义\tes@optionlength{skipabove}{4pt}。但是您在使用 时\tes@define@key@length{skipabove}并没有事先定义长度。

顺便说一句,你可以简单地使用

\setlength{\csname test@#1@length\endcsname}{\csname testl@#1\endcsname}

没有\expandafter

答案2

我看到的错误是\test@#1@length当您尝试设置它时长度尚未定义。

如果我\expandafter\show\csname test@#1@length\endcsname在注释行之前添加,我会得到

> \test@skipabove@length=\relax
<recently read> \test@skipabove@length

相关内容