I’m thinking of writing a novel. To be able to easily track who appears where, I was thinking of using a function per character. I want the function without argument to just return the name. An argument would either be an alternate name form, or empty for paragraphs where a human would know from context who’s speaking. Something like
#Liz said: "Oh, wow!" // normal case: just returns the name
#Liz[Elizabeth] said: "Oh, wow!" // returns the alternate name
#Liz[She] said: "Oh, wow!" // returns alternate text, but attributed to Liz for analysis
#Liz[] "Oh, wow!" // no name in final document, but attributed to Liz for analysis
As far as I understand it, this argument can not have a default, since then it would have to be named. But, if I have a positional or variadic argument, it seems to default to the function name (value is Liz in a different font.) None of these seem to work
#let Liz(alt) = if alt == Liz { [Liz] } else { alt }
#let Liz(alt: [Liz]) = alt
#let Liz(..alt) = if alt.len() == 0 { [Liz] } else { alt.at(0) }
I’ve read the doc up and down, but it is fairly vague on details. How can I implement such a simple requirement?
As a minor note, with the approach you took, ..alt can be replaced with nomen since the argument is now always given again. The sample showing how to use arguments is still useful though!
That is weird! I get maybe needing that for debugging, but what good can that be in normal type setting? The simplest syntax should be the most useful one, i.e. call without arguments! However, I can live with that crutch, if I find how to format it like normal text (or bold while proof reading.)
My bad, I wrote that from memory. Check again, alt.at(0) is correct.
I expressed myself badly: In those cases I want the name in the source (for scripted analysis,) but not in the output.
This comes from how functions can be used (need to be usable) in a more programming-oriented context.
Consider this:
#let character = Liz
#character comes. #character[She] goes.
This wouldn’t work if Liz on its own was already [Liz], because the latter is not a function that you can call with [She] as a parameter.
Therefore, character is a function, not the content that you get when calling that function. To call a function without parameters you need to write e.g. character().
In your specific case, it would indeed be nice if Liz on its own called the function, but that would lead to problems in many situations where functions are used in a more general way. It may be possible to solve this somehow (e.g. symbols allow you to write both arrow and arrow.l), but functions are not great to use in this specific way.
Indeed, I would have also missed that arguments supports this.
In this case, I think the closest you can get is this:
#let Liz(..alt) = {
if alt.len() == 0 [Liz]
else { alt.at(0) }
}
#Liz() said: "Oh, wow!" // normal case: just returns the name
#Liz[Elizabeth] said: "Oh, wow!" // returns the alternate name
#Liz[She] said: "Oh, wow!" // returns alternate text, but attributed to Liz for analysis
#Liz[] "Oh, wow!" // no name in final document, but attributed to Liz for analysis
Liz is replaced by Liz(), otherwise it looks the way you wanted. As explained above, a plain Liz is probably not possible, unless I am missing a hacky way.