![定义可重复使用且易于编辑的关键字](https://linux22.com/image/410340/%E5%AE%9A%E4%B9%89%E5%8F%AF%E9%87%8D%E5%A4%8D%E4%BD%BF%E7%94%A8%E4%B8%94%E6%98%93%E4%BA%8E%E7%BC%96%E8%BE%91%E7%9A%84%E5%85%B3%E9%94%AE%E5%AD%97.png)
我正在写一篇论文,但我还没有做出所有的文体选择。也就是说,我还没有决定要缩写哪些长单词以及如何缩写它们,论文的作者是“我”、“我们”、“作者”还是“作者们”等等。所以我想做的是定义一些将多次重复使用的关键词。
我想在文档顶部做一些类似的事情,\newcommand{\auth}{we}
每当我\auth{}
在文档中写字时,应该显示“我们”这个词。现在,经验更丰富的你们会注意到,我在这里描述的内容实际上会按照我的意愿去做,所以接下来是真正的问题。
我真正想要做的是将英语词典中的单词链接到命令,并在将参数传递给该命令时能够稍微改变其输出。例如,如果我定义\auth{}
为吐出“我们”,我希望\auth{upper}
吐出“我们”。我还希望能够通过调用 或类似方法从中获取所有格形式,例如“我们的”和“我们的” \auth{upper, possessive}
。\auth{possessive}
实现此目标的最佳方法是什么?我可以创建一个词典吗?或者您有什么建议?
非常感谢!
答案1
嗯,我试过了。顺便说一句,它只在 LuaLaTeX 中有效:
%!TEX program = lualatex
\documentclass{article}
\usepackage{polyglossia}
\usepackage{luacode}
\begin{luacode*}
dofile(kpse.find_file("l-lpeg.lua"))
dofile(kpse.find_file("util-sto.lua"))
dofile(kpse.find_file("util-prs.lua"))
Pronouns = {
["formal"] = {
["possessive"] = "ours",
["nominative"] = "we",
["oblique"] = "us"
},
["informal"] = {
["possessive"] = "mine",
["nominative"] = "I",
["oblique"] = "me"
}
}
function Auth(keywords)
local dummy = utilities.parsers.settings_to_array(keywords)
for i,v in ipairs(dummy) do
if Pronouns[dummy[i]] ~= nil then result = Pronouns[dummy[i]] end
end
for i,v in ipairs(dummy) do
if result[dummy[i]] ~= nil then result = result[dummy[i]] end
end
return result
end
function Upper(string)
return unicode.utf8.upper(unicode.utf8.sub(string,1,1))..unicode.utf8.sub(string,2,utf8.len(string))
end
\end{luacode*}
\def\auth#1{\directlua{tex.print(Auth("#1"))}}
\def\Auth#1{\directlua{tex.print(Upper(Auth("#1")))}}
\begin{document}
\auth{oblique,informal} \Auth{formal,possessive}
\end{document}
答案2
这出乎意料地复杂,但这里有一个适用于任何 TeX* 的解决方案。
\begingroup
\catcode`!=11 % for private macros
\endlinechar=-1
\catcode`\^^M=12 \catcode`\^^?=12\relax
\gdef\!stop{^^?}
\gdef\!fi{\fi}
\newtoks\!before \newtoks\!after
% some convenient shorthands
\gdef\!csnm#1{\csname#1\endcsname}
\gdef\!ecsnm#1#2{\expandafter#1\csname#2\endcsname}
% the main command sets up the catcodes for reading in
% the definitions of the second argument
\gdef\newvarcommand#1{
\begingroup\catcode`\^^M=12 \catcode`\^^?=12\relax
{\escapechar=-1 \xdef\!name{\string#1}}
\!ecsnm\newtoks{toks:\!name}
\gdef#1##1{
{\escapechar=-1 \xdef\!name{\string#1}}
\begingroup
\!processnextkey##1,^^?,
\!ecsnm\the{toks:\!name}
\!result
\endgroup
}
\!newvarcommand
}
% for each modifier in the argument, set the corresponding
% conditional true
\gdef\!processnextkey#1,{\def\arg{#1}
\ifx\!stop\arg\else
\ifx\empty\arg\def\!key{default}\else\def\!key{#1}\fi
\!ecsnm\ifx{ifkey:\!name:\!key}\relax
\errmessage{Unknown key \!key\space for command \!name}
\else\!csnm{key:\!name:\!key true}\fi
\expandafter\!processnextkey\fi
}
% here we read the argument line by line
\gdef\!newvarcommand#1{\!getnext#1^^M^^?^^M}
\gdef\!getnext#1^^M{\def\arg{#1}
\ifx\!stop\arg\endgroup\else
\ifx\empty\arg\else\!parse#1^^M\fi
\expandafter\!getnext\fi
}
% for each entry, new conditionals are created to test whether a
% modifier is present or not, and a token list containing the
% conditionals and the word to be printed is appended to the
% token list read by the command to be defined
\gdef\!parse#1:#2^^M{\!before={}\!after={}\def\arg{#1}
\ifx\empty\arg
{\globaldefs=1 \!ecsnm\newif{ifkey:\!name:default}}
\!before=\expandafter{\csname ifkey:\!name:default\endcsname}
\!after=\expandafter{\!fi}
\else\!setupnextkey#1,^^?,\fi
\edef\!addtoks{\!ecsnm\the{toks:\!name}
\the\!before\def\noexpand\!result{#2}\the\!after}
\global\!csnm{toks:\!name}=\expandafter{\!addtoks}
}
% creating \newifs for each modifier
\gdef\!setupnextkey#1,{\def\arg{#1}
\ifx\!stop\arg\else
{\globaldefs=1 \!ecsnm\newif{ifkey:\!name:#1}}
\!before=\expandafter{\the\expandafter\expandafter
\expandafter\!before\!csnm{ifkey:\!name:#1}}
\!after=\expandafter{\the\expandafter\!after\!fi}
\expandafter\!setupnextkey\fi
}
\endgroup
然后您可以按如下方式定义您的“词典”:
\newvarcommand\auth{
:we
upper:We
possessive:ours
upper,possessive:Ours
}
在每一行中,用逗号分隔要用作参数的单词,然后在冒号后输入应出现的单词。可以使用 或 指定默认:val
值default:val
。重要的:条目应该按照说明符的数量递增的顺序出现(即,您应该首先获得所有单词条目,然后是两个逗号分隔的单词的条目,然后是三个单词的条目,依此类推),否则您可能会得到不正确的结果。
\auth{} \auth{default} % these two are the same, "we"
\auth{upper} % "We"
\auth{possessive} % "ours"
\auth{upper,possessive} \auth{possessive,upper} % both "Ours"
\auth{lower} % this gives an "Unknown key" error
让我解释一下upper,possessive:Ours
该行代码的工作原理。基本上,当读取该行时,它首先创建条件\ifkey:auth:upper
和\ifkey:auth:possessive
。然后,一个标记列表
\ifkey:auth:upper
\ifkey:auth:possessive
\def\!result{Ours}
\fi
\fi
被构造并附加到名为 的标记列表\toks:auth
。如果使用\auth{upper,possessive}
,则读取参数并将相应的条件\ifkey:auth:upper
和ifkey:auth:possessive
设置为 true,toks:auth
然后解包标记列表并\!result
打印。
*它假设非外部
\newif
,就像在 LaTeX 中一样,但对于纯 TeX,需要进行一些调整。