# user-defined markup aliases with l3

I would like to write a package providing semantic markup for scholarship in the humanities (loosely following TEI-XML). In the source code, users would use macros like \term for a foreign term or \socalled for "scare quotes".

I would like to provide a default set of typesetting commands that each of these macros would expand to (\term -> \emph, \socalled -> \enquote). I would also like provide a simple key-value interface for the user to reconfigure these (for example, to meet a publisher's specifications). And, for future robustness and flexibility I would like to do it in expl3 or at least using xparse. (I must admit I am completely baffled by expl3 but I'm hoping to learn something here.)

I have gotten as far as a \setTagFormat command that creates a new command aliasing the markup tag to its typesetting macro. How could I do this with a key-value interface such as l3keys?

In the current version (MWE below) the user must enter a command like \setTagFormat{\term}{\emph} for each tag. So perhaps an interface like this would be better:

\setSemanticTagFormat{
\term = \emph
\q = \enquote
}


In an alternate approach, since many tags will be aliased to the same typesetting commands (basically italics or quotation marks), you could go in the other direction:

\setSemanticTagFormat{
\emph = \term, \mentioned, \foreign, \worktitle
\enquote = \q, \socalled, \parttitle
}


It also occurs to me that (going back toward plain TeX) I could just do this:

\let\term\emph
\let\q\enquote


Here is a working but not ideal example with xparse but not l3keys:

\documentclass{article}

\usepackage{csquotes}
\usepackage{xparse}

\NewDocumentCommand\setTagFormat{m m}{%
\NewDocumentCommand #1{m}{#2{##1}}%
}
\setTagFormat{\term}{\emph}
\setTagFormat{\q}{\enquote}

\begin{document}

\term{Musica ficta} is the practice of adding accidentals where they are not notated.
The teacher told us, \q{Always sing F-sharp before a cadence on G!}

\end{document}

• Don't use single letter aliases!!! – cfr Aug 27 '15 at 22:58
• @cfr <q> is the TEI-XML tag for quotations, and I had originally hoped to stay close to their element names. But they also use <l> for poetic line which I find unacceptable. – musarithmia Aug 28 '15 at 4:27
• Do you plan also to support LaTeX to Tei conversion? Tei is supported by tex4ht, it would be easy to add support for this markup – michal.h21 Aug 28 '15 at 22:51
• @michal.h21 Yes, the idea was to create a syntax that could be easily converted to TEI or to other formats, possibly using tex4ht (humanities publishers still want .doc files for submission). – musarithmia Aug 29 '15 at 21:17
• @AndrewCashner I've already created configuration file which will automatically configure macros created with Egreg's method for TEI output using tex4ht. It shouldn't be hard to configure it for .odt output as well, which can be converted to .doc easily – michal.h21 Aug 29 '15 at 21:28

A little bit simpler with \keyval_parse:NNn:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \cashner_make_semantic:Nn
{
\tl_map_inline:nn {#2} % for every token in the second argument,
{ \NewDocumentCommand ##1 {} {#1} } % create the alias to the first
}

\NewDocumentCommand \NewSemanticMarkup { m }
% with keyval syntax,
% |          / ignore single keys
% |         |     \           /  and apply our function
% |         |      \         /  /                      \ to our argument
{ \keyval_parse:NNn \use_none:n \cashner_make_semantic:Nn {#1} }

\ExplSyntaxOff

\usepackage{csquotes}

\NewSemanticMarkup {
\textit = \term,
\enquote = \scare \socalled
}

\begin{document}
hi

\term{hi}

\scare{hi}

\socalled{hi}
\end{document}

• This is a good one, I didn't know about it. I had to make things a little bit more complicate because l3keys \detokenizes the key name so I had to remove \ plus the non gobbled spaces. By the way, shouldn't you use \use_none:n rather than \use:n? – Manuel Aug 27 '15 at 22:41
• @Manuel I was wondering what all that was about! :) \keyval_parse: comes in real handy. – Sean Allred Aug 27 '15 at 22:44
• @SeanAllred This is great! When you get a chance it would be helpful if you could add a little explanation of what these few lines of code are doing. The expl3 concepts are so new to me that I really have no idea what is going on. – musarithmia Aug 28 '15 at 4:30
• @AndrewCashner see edit :) – Sean Allred Aug 28 '15 at 11:39
• Would it work with @Manuels syntax as well? I think \enquote={\aa,\bb,\cc} might be an easier to understand syntax than \enquote=\aa\bb\cc (I guess it would need a test to see if something is a comma separated list or not. – daleif Aug 28 '15 at 12:31

I'd avoid grouping macros that should be equivalent to some other macro, because this will make harder changing the meaning: if they are a large number, they'll be difficult to spot in the groups.

A line for each equivalence seems better, and easier to manage for changes.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand \SetSemanticMarkup { m }
{
\clist_map_inline:nn { #1 }
{
\SetEquivalent{ ##1 }
}
}
\NewDocumentCommand{\SetEquivalent}{ >{\SplitArgument{1}{=}} m }
{
\cashner_set_equivalent:nn #1
}
\cs_new_protected:Nn \cashner_set_equivalent:nn
{
\cs_new_eq:NN #1 #2
}
\ExplSyntaxOff

\usepackage{csquotes}

\SetSemanticMarkup {
\term = \textit,
\scare = \enquote,
\socalled = \enquote,
\q = \enquote,
}

\begin{document}
hi

\term{hi}

\scare{hi}

\socalled{hi}

\term{Musica ficta} is the practice of adding accidentals where they are not notated.
The teacher told us, \q{Always sing F-sharp before a cadence on G\@!}

\end{document}


• Off-topic, but I'm curious: how does the \@ before ! affect the end-of-sentence rubber after "? – Sean Allred Aug 28 '15 at 14:13
• @SeanAllred So that the correct space factor is set after G. – egreg Aug 28 '15 at 17:14
• As in the space between the G and the !? I though that macro affected space after the next token? – Sean Allred Aug 28 '15 at 18:54
• @SeanAllred The space factor code of G is 999, which means that ! will set the space factor to 1000 instead of 3000. – egreg Aug 28 '15 at 19:45
• @egreg Thanks! What advantage would this have over \let\term\emph and so on? – musarithmia Aug 28 '15 at 21:15