I want to start all of this out by saying that I have no idea where to begin
actually implementing all of this in the code-behind and that I marvel at the
reality of xtemplate
as it stands implemented in expl3
. That said,
interface design is nothing to scoff at (as I’m sure members of this list are
aware), so I’m continuing under the assumption that this kind of proposal is of
substance.
This is an opinion piece meant for constructive purposes :)
This file is best viewed within emacs under org-mode
. Sorry, vi (et al.).
Please see the Org source for the original question and Joseph Wright’s answer, but to keep this file short (as viewed on GitHub), I’ve commented it out here.
In brief, the discussion revolves around the current limitation of xtemplate
’s
object declaration syntax. Since TeX restricts the number of arguments a single
macro can take, an object is limited to nine qualities. This is unacceptably
restrictive, especially when considering things such as ‘optional’ pieces of
data in an object.
Workarounds such as including the optional data in a template declaration is a violation of the separation between content and presentation. Objects should be data and only data; templates should be presentation and only presentation.
I know of no other solutions to the problem of optional data.
I believe Joseph is Wright on several points:
- this is potentially an edge case,
- long argument listings is unreasonable on the author level,
- the code is experimental, and that
- these are hard questions.
He gives two suggestions that I’ll flesh out here momentarily. First, I want to
make sure that we are all on the same page about the roles involved here. The
role that xtemplate
gets involved in is every role except the author level:
- objects
- logic (document designer)
- instances
- design (typographer)
- templates
- programming (programmer)
We should not be overly-concerned with verbosity on these levels. Purity and consistency should, in my honest opinion, be top goals. (Consider this the spirit of Guy Steele speaking.)
Right now, we have a parameter-based system. Objects (\DeclareObjectType
) are
given a set of required attributes as \def
-style parameters and template code
(\DeclareTemplateCode
) uses these parameters along with key–value input
targeted specifically for layout parameters (such as a font or length). This
paradigm is possibly the simplest to understand when the user (in this case, the
document designer) already has a background in TeX.
Unfortunately, this style has the inherent limitation set out in the
introduction: an object can have no more than nine parameters. This is caused
by TeX’s own (more or less arbitrary) limitation in the primitive \def
. There
is no clean way of getting around this.
\DeclareObjectType { name }
{
first : tokenlist ,
middle : tokenlist ,
last : tokenlist ,
first : .required ,
last : .required ,
}
Note that everything is given as an xtemplate
-style key listing. This
maintains consistency. Note also that the keys first
and last
are given the
.required
property; I opted against the possibly more consistent (for varying
definitions of ‘consistent’) .value_required:
(reminiscent of expl3
) because
expl3
is on an entirely different design level from xtemplate
. I opted to
keep the .
because it well conveys the ‘meta’ quality of being a ‘required
argument’. If it makes more sense to do so, I’m not against incorporating the
required-ness into the type (in this case, tokenlist
). Perhaps something like
tokenlist*
or tokenlist!
.
This is more-or-less stream-of-consciousness as far as specific input syntax ideas go, but the idea of notating this (and potentially other) meta-information into this listing is the main idea I’d like to propose (again, partly from Joseph’s own prompting).
Templates would be created as normal:
\DeclareTemplateInterface { name } { full }
{
reversed : boolean = false ,
use-first-name : boolean = true ,
use-middle-name : boolean = true ,
use-last-name : boolean = true ,
first-name-format : tokenlist ,
middle-name-format : tokenlist ,
last-name-format : tokenlist ,
}
This is included only to make a complete example use.
This is another proposed change in the interface.
<<declare-template-code:variables>>
\DeclareTemplateCode { name } { full }
{
first = \l_names_first_name_tl ,
middle = \l_names_middle_name_tl ,
last = \l_names_last_name_tl ,
}
{
reversed = \l_names_reversed_bool ,
use-first-name = \l_names_use_first_bool ,
use-middle-name = \l_names_use_middle_bool ,
use-last-name = \l_names_use_last_bool ,
first-name-format = \l_names_first_format_tl ,
middle-name-format = \l_names_middle_format_tl ,
last-name-format = \l_names_last_format_tl ,
}
{
<<declare-template-code:code>>
}
(adapted from Clemens Niederberger’s tutorial.)
It is only on this level do we see the re-introduction of LaTeX syntax. We marry the key–value interface with traditional 2e syntax as one would naturally expect.
\DeclareInstance { name } { standard } { full } { }
\DeclareDocumentCommand \Name { >{\SplitArgument{1}{~}}m }
{
\UseInstance { name } { standard }
{
first = \use_i:nn #2,
last = \use_ii:nn #2,
}
}
\DeclareDocumentCommand \SpecialName { m m m m }
{
\UseTemplate { name } { full } { #1 }
{
first = #2,
last = #3,
middle = #4,
}
}
Given that the option .value_required:
pattern exists (from l3keys
), I’m not
a big fan of this option. Still, it is conceivable that absolutely required
arguments are given as TeX-style parameters where optional ones are given in
key–value format. I include this possibility for completion’s sake.