# Defining Reusable and Easily Editable Keywords

I am writing a paper in which I still haven't made all the stylistic choices. That is I haven't decided which long words I want to abbreviate and how I want to abbreviate them, if the author of the paper is a "me", a "we", a "the author" or the "authors" etc. So what I want to do is define a few keywords that will be reused many times.

I want to at the top of my document do something along the lines of \newcommand{\auth}{we} and whenever I write \auth{} in my document the word "we" should show up. Now, the more seasoned of you will notice that what I am describing here will actually do what I want it to so on to the real question.

What I really want to do is link a word in the english dictionary to a command and when passing an argument to that command being able to slightly change its output. So for instance if I define \auth{} to spit out "we" I want \auth{upper} to spit out "We" instead. I would also like to be able to get possessive forms from it such as "Ours" and "ours" by calling \auth{upper, possessive}, \auth{possessive} or something similar. What would be the best way to achieve this? Can I create a dictionary of sorts or what do you recommend?

Many thanks!

Well, I've tried. BTW, it only works in 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}


This was surprisingly complex, but here is a solution working with any 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
\the\!before\def\noexpand\!result{#2}\the\!after}
}

% 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


You can then define your "dictionary" as follows:

\newvarcommand\auth{
:we
upper:We
possessive:ours
upper,possessive:Ours
}


In each line, you write the comma-separated words that you want to use as arguments, and then after a colon the word that should appear. The default value can be specified with either :val or default:val. Important: The entries should occur in the order of increasing number of specifiers (i.e., you should have all one-word entries first, then the ones with two comma-separated words, then three and so on), otherwise you might get incorrect results.

\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


Let me explain for the upper,possessive:Ours line how the code works. Basically when the line is read, it first creates conditionals \ifkey:auth:upper and \ifkey:auth:possessive. Then, a token list

\ifkey:auth:upper
\ifkey:auth:possessive
\def\!result{Ours}
\fi
\fi


is constructed and appended to a token list named \toks:auth. If you use \auth{upper,possessive}, the arguments are read and the corresponding conditionals \ifkey:auth:upper and ifkey:auth:possessive are set to true, the toks:auth token list is unpacked and \!result is printed.

*It assumes a non-outer \newif` though, like in LaTeX, but for plain TeX some adaptations would be necessary.