我怎样才能定义一个宏,比如说\address
,以便我可以像这样使用它:
\address
27/7 Montague Street
Edinburgh
它会将后面的行放入另一个宏中,比如说\addrinfo
?我最终想要做的是修改 Knuth 的字母宏,这样我就可以在字母中指定一次地址,然后以不同的字体生成地址。目前我有
\newbox\theiraddressbox
\def\address{\beginlinemode%
\global\setbox\theiraddressbox=\vtop\bgroup\raggedright
\hsize=\longindentation \everypar{\hangindent1cm}
\def\endmode{\egroup\endgroup\bigskip\copy\theiraddressbox}}
但这意味着地址标签设置为相同的字体。
答案1
你可以做的是将每一行放入单独的定义中,作为 定义的一部分\address
。在 Knuth 的信件格式中,他将地址的第一行放在 的定义中\addressee
。
这个想法是针对整个地址执行此操作。然后,您将获得 etc 的定义, \ToName, \ToStreet
以便以后以任何您喜欢的方式使用。
以下是一个可以说明这个想法的最小示例:
\def\beginlinemode{\endmode\begingroup\obeylines\def\endmode{\par\endgroup}}
\let\endmode=\par
\def\address{\beginlinemode\getToAddress}
% Populates the \To* definitions.
{\obeylines\gdef\getToAddress#1
#2
#3
#4
{\gdef\ToName{#2\unskip}%
\gdef\ToStreet{#3\unskip}%
\gdef\ToCity{#4\unskip}%
\def\beginletter{\endgroup\bigskip}}}
\address
Some Name
27/7 Montague Street
Edinburgh
\beginletter
And now you can use the different fields as you wish. For example:
\bigskip
\moveright2cm\vbox{\hbox{\ToName}\hbox{\ToStreet}\hbox{\ToCity}}
\bigskip
This letter is addressed to {\bf \ToName}.
\bye
您还可以使用\FromAddress
类似于 的宏\address
,但其结尾标记是\address
而不是\beginletter
。因此,您可以这样开始您的信件:
\FromAddress
My Name
My Street
My City
\address
To Name
To Street
To City
\beginletter
etc
答案2
实际上,您的\address
宏不是无界的:无论如何,\endmode
宏必须在之后被调用。在 Knuth 的字母宏中,这项工作由\body
宏完成。因此,您可以做的是\address
像这样界定宏:
\def\address{\beginlinemode\getaddress}
\def\getaddress#1\body{\gdef\theaddress{#1}\body}
然后宏\theaddress
将包含未格式化的地址。希望你能找出遗漏的细节。