使用 \settowidth 创建和定义长度的宏存在问题,然后使其成为 hspace 命令

使用 \settowidth 创建和定义长度的宏存在问题,然后使其成为 hspace 命令

它在标题中。我正在尝试制作一个命令创建宏,它可以快速创建长度并将其设置为某个\settowidth{}{}输出,然后使其成为水平间距的命令。

我也尝试过,\csname#1\endcsname但是也没有用。

\documentclass{article}

\newcommand{\newspace}[2]{%
    \newlength{#1aux}%
    \settowidth{#1aux}{#2}%
    \newcommand{#1}{\hspace*{#1aux}}}

\begin{document}
    
\newspace{\QQspace}{QQ} 

    AQQA
    A\QQspace A
    
\end{document}

答案1

答案的关键在于如何定义一个宏来创建一个新的宏并将名称作为其参数传递?使用#1aux宏需要额外的\csnames 和相关的\expandafters 来确保\csname首先发生。

\newcommand{\newspace}[2]{%
    \expandafter\newlength\expandafter{\csname#1aux\endcsname}%
    \expandafter\settowidth\expandafter{\csname#1aux\endcsname}{#2}%
    \expandafter\newcommand\expandafter{\csname#1\endcsname}{%
        \expandafter\hspace\expandafter*\expandafter{\csname#1aux\endcsname}}}

然而,借助该calc软件包,\widthof可以避免很多令人不快的样板代码

\newcommand{\betternewspace}[2]{%
    \expandafter\newcommand\expandafter{\csname#1\endcsname}{\hspace*{\widthof{#2}}}}

\hphantom{#2}(不需要calc)具有与 类似的效果,\hspace*{\widthof{#2}}但其作用相当于 ,\hspace而不是\hspace*

\documentclass{article}
\usepackage{calc}

\newcommand{\newspace}[2]{%
    \expandafter\newlength\expandafter{\csname#1aux\endcsname}%
    \expandafter\settowidth\expandafter{\csname#1aux\endcsname}{#2}%
    \expandafter\newcommand\expandafter{\csname#1\endcsname}{\expandafter\hspace\expandafter*\expandafter{\csname#1aux\endcsname}}}
 
\newcommand{\betternewspace}[2]{%
    \expandafter\newcommand\expandafter{\csname#1\endcsname}{\hspace*{\widthof{#2}}}}

\begin{document}
    
\newspace{QQspace}{QQ} 
\betternewspace{QQspaceTwo}{QQ} 
\noindent%
AQQA\\
A\QQspace B\\
A\QQspaceTwo B\\
\end{document}

编译后的代码显示一行中有 AQQA,第二行和第三行中有 A 和 B 之间等于 QQ 的间隙

答案2

您不需要分配长度:只需定义\QQspace\hspace*{<width>},其中可以使用划痕长度计算宽度。

\documentclass{article}

\makeatletter
\newcommand{\newspace}[2]{%
  \settowidth{\dimen@}{#2}%
  \ExpandArgs{ne}\newcommand{#1}{\noexpand\hspace*{\the\dimen@}}%
}
\makeatother

\begin{document}

\newspace{\QQspace}{QQ}

AQQA

A\QQspace A

\texttt{\meaning\QQspace}

\end{document}

这使用\ExpandArgs{ne}那个

  1. 跳过下一个标记,这里\newcommand
  2. 跳过下一个括号参数,因为n,这里{#1}
  3. 完全e扩展下一个括号参数的内容。

这就解释了\noexpand前面\hspace\the前面\dimen@

在此处输入图片描述

使用“经典”代码,该\ExpandArgs行可能是

\begingroup\edef\x{\endgroup
  \noexpand\newcommand{\noexpand#1}{\noexpand\hspace*{\the\dimen@}}%
}\x

答案3

这是基于Dai Bowen的答案的解决方案,但backslash在论点中重新建立了。

信用:马丁·沙雷尔

\documentclass{article}
\usepackage{calc} % Provides the useful \widthof command.

\makeatletter % Makes the character "@" a normal letter (here needed to call the \@gobble macro).

\newcommand{\newspace}[2]{%
\expandafter\newcommand\csname\expandafter\@gobble\string#1\endcsname{%
\hspace*{\widthof{#2}}%
                        }%
}

\makeatother % Resets @'s catcode to default.

\begin{document}
    
    \newspace{\QQspace}{QQ} 
    
    AQQA

    A\QQspace A

\end{document}

相关内容