5

I would like to write a LaTeX3 function \f, which takes a single argument #1 whose type is a LaTeX3 string, and prints

Hello, #1!

A first attempt is

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
    \cs_new:Nn \f:n {Hello, #1}
    \cs_gset_eq:NN \f \f:n
\ExplSyntaxOff
\begin{document}
\f {world!}
\end{document}

This typesets

Hello,world!

Note that there's no space between the comma and the following word. This is due to the fact that the \ExplSyntaxOn macro changes the space character's category code so that it is ignored. (The \ExplSyntaxOff macro undoes this effect.)

This can be easily remedied by using tilde (~) instead of the space character between the \ExplSyntaxOn and the \ExplSyntaxOff, thus:

...
    \cs_new:Nn \f:n {Hello,~#1}
...

Now the document typesets

Hello, world!

as desired.

This solved the problem in this simple, contrived case. However, when this example is generalized to the problem of creating a parameterized text template, the solution breaks, since replacing every space with a tilde in a long stretch of text is inconvenient, and additionally it makes it cumbersome to create the template from text that occurs naturally in the body of the document by simply copy-and-pasting it.

For instance I have a document with many similar definitions of mathematical concepts, an instance of which is

\begin{definition}[Doubling]
Let $S$ be a type.
We denote with \dbl the \emph{doubling} function $\dbl:S \rightarrow S\times S$,
which to every $s:S$, assigns $(s,s)$.
(Hacker's note: you can use the TeX macro named "dbl"
to generate this function's symbol.)
\end{definition}

I would like to create a template out of this sample definition by parameterizing the name of the defined term (Doubling in this example), the macro that is used to typeset the symbol denoting the defined term (\dbl in this example), and the term's defining formula ((s,s) in this case). In other words, I'd like to be able to typeset the above definition by writing, say,

\MyDef {Doubling} \dbl {(s,s)}

and then create another, similar definition by writing

\MyDef {Starring} \star {s*}

So am I supposed to replace every space character in the definition's text with a tilde? And suppose I do so. What if I later wish to use one sentence from the definition inside the document's body? Will I need to change all the tildes in the copied sentence back to spaces?

  • 1
    You could define it in a expl3 block and use ~ but most naturally your \MyDef wold be defined outside such a region (it is a document level command \MyDef not my_def:n ) defined with xparse at a point that normal white space rules apply. – David Carlisle Oct 9 '17 at 8:38
  • @DavidCarlisle: But xparse is just a wrapper to help deal with optional values. Inside the body of the xparse function I need to be able to use LaTeX3 variables, control structures, etc, so this doesn't solve the problem. For instance, in the example above, I'd like to use \token_to_str:N to convert the argument \dbl to the string "\dbl". – Evan Aad Oct 9 '17 at 8:41
  • No that is the wrong way to view xparse, expl3 is the programming layer and xparse is the interface for defining document level commands, although it's true that you need to access expl3 comands inside – David Carlisle Oct 9 '17 at 8:45
  • @DavidCarlisle: And how can I change the argument "Doubling" to lowercase "doubling" using the xparse interface? – Evan Aad Oct 9 '17 at 8:56
  • 1
    well you should have provided a MWE if you wanted that example rather than the first in answers:-) – David Carlisle Oct 9 '17 at 9:09
5

Just split the code into two parts. On the other hand, I consider this a recipe to produce dull texts.

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath,amsthm}

\theoremstyle{definition}
\newtheorem{definition}{Definition}

% the text
\NewDocumentCommand{\definitiontext}{mmmm}{%
  \begin{definition}[#1]
  Let $S$ be a type.
  We denote with $#2$ the \emph{\ExpLowercase{#1}} function 
  $#2\colon S\rightarrow #3$,
  which to every $s:S$, assigns $#4$.
  (Hacker's note: you can use the \TeX\ macro \texttt{\ExpString#2}
  to generate this function's symbol.)
  \end{definition}
}

\ExplSyntaxOn
\cs_set_eq:NN \ExpLowercase \tl_lower_case:n
\cs_set_eq:NN \ExpString \token_to_str:N

\NewDocumentCommand{\MyDef}{mmmm}
 {
  \cs_new:Npx #2
   {
    \exp_not:N\mathrm{\cs_to_str:N #2}
   }
  \definitiontext{#1}{#2}{#3}{#4}
 }
\ExplSyntaxOff

\begin{document}

\MyDef{Doubling}{\dbl}{S\times S}{(s,s)}
\MyDef{Star}{\sstar}{S}{s^*}

\end{document}

(Sorry, I can't meet you on redefining without warning existing commands.)

(Image will be added later, imgur seems to be rejecting them)

  • As I wrote in a comment to David's answer, I find it unreasonable that every time a TeX user wants to access the power of LaTeX3 inside a document-command, they need to write wrapper functions. If this is indeed how LaTeX3 is meant to be used, then these wrappers should be provided as part of LaTeX3 itself, to make their use uniform and easy. – Evan Aad Oct 9 '17 at 9:37
  • 1
    @EvanAad What you find unreasonable has been decided upon from the start of the LaTeX3 project. By the way, i find unreasonable to do so much work for a handful of definitions. – egreg Oct 9 '17 at 9:40
  • @clemens: I agree with you. It doesn't sound reasonable to me either. And yet it seems to be a key concept of LaTeX3 to delegate this unreasonable task to each and every end user separately. – Evan Aad Oct 9 '17 at 9:43
  • 1
    @EvanAad You seem to be unaware of the fact that the user interface is far from being decided upon; some wrappers to frequently used functions are already available, see the xfp package. It is likely that functions such as \ExpLowercase (maybe with a different name) will be provided. – egreg Oct 9 '17 at 9:45
  • I've accepted your answer not because I think it is a good solution to the problem I posed, but because I think it is unfortunately the best solution available to it at this point of time. I hope LaTeX3 finds a better way to address situations such as these. – Evan Aad Oct 10 '17 at 8:02
5

You can use ~ but if there are long document level strings it's an indication that the command lives in the document level interface not in the expl3 code layer so you could define it outside the expl3 code convention block as long as you do expose a suitable code command that can be called in that environment, eg

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
    \cs_new:Nn \f:nn {#1#2}
    \cs_gset_eq:NN \fnn \f:nn
\ExplSyntaxOff
\NewDocumentCommand\f{m}{\fnn{Hello }{#1}}
\begin{document}
\f {world!}
\end{document}

For the second example, something like

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn

\ExplSyntaxOff

\newtheorem{definition}{definition}

\def\dbl{\mathrm{DbL}}%?
\def\star{\mathrm{star}}%?

\NewDocumentCommand\mydef{mmm}{%
\begin{definition}[#1]
Let $S$ be a type.
We denote with \texttt{\string#2} the \emph{\lowercase{#1}} function $#2:S \rightarrow S\times S$,
which to every $s:S$, assigns $(s,s)$.
\end{definition}}

\begin{document}


\mydef {Doubling}\dbl{(s,s)}

\mydef {Starring} \star {s*}

\end{document}
  • The "Hello, world!" example is simplistic. Try the other example with the \begin{definition} ... \end{definition}. – Evan Aad Oct 9 '17 at 8:52
  • @EvanAad can't that just be defined directly with xparse, why do you need expl3 there? – David Carlisle Oct 9 '17 at 8:56
  • 1
    @EvanAad In a LaTeX2e document, TeX primitives may well take the form of document commands. In a 'pure' LaTeX3 formate we might expect the same document commands to exist but as wrappers around code-level implementation. (In the case of \string, that might well end up back with the primitive!) – Joseph Wright Oct 9 '17 at 9:13
  • 1
    @EvanAad That's one of the key concepts for LaTeX3 work: we have a set of defined code-level interfaces which can be exposed at the document level using xparse (or in other ways). Document commands tend to have optional arguments, etc., whereas code level ones have a strictly fixed list of arguments. – Joseph Wright Oct 9 '17 at 9:27
  • 1
    @EvanAad That's LaTeX3 as a new format: you are using LaTeX3-in-2e, and we are constrained by needing to respect existing behaviours and not break documents. We have for example created xfp as a small package to expose \fp_eval:nas \fpeval for wider use: that's OK as it has a low chance of a name clash. See for example xgalley as some experimental code which does break things: it's fine to use in tests, but cannot be loaded in an arbitrary LaTeX2e document. Redefining \lowercase would be a disaster! – Joseph Wright Oct 9 '17 at 9:35
0

Based on egreg's answer I've created a file expl3x.tex (the extra x in the file name standing for "export"), whose sole purpose is to "export" select expl3 functions and variables, which is to say to rename them in a systematic way so they can be used inside the body of document commands. Specifically, the renaming process does away with underlines and colons, which are symbols that are often used in mathematical writing (which is the kind of writing that I use TeX mostly for), and instead makes use of camel case in tandem with the ampersand symbol. So, for instance, the expl3 function \cs_if_exist:NTF is renamed as \CSIfExist@NTF.

Here's the contents of the file expl3x.tex as it stands now (it is extended as needed):

\input expl3-generic
\ExplSyntaxOn
\makeatletter
    \cs_new_eq:NN \CSIfExist@NTF \cs_if_exist:NTF
    \cs_new_eq:NN \CSNewEq@NN \cs_new_eq:NN
    \cs_new_eq:NN \CSSetEq@NN \cs_set_eq:NN
    \cs_new_eq:NN \CSToStr@N \cs_to_str:N

    \cs_new_eq:NN \GroupBegin@ \group_begin:
    \cs_new_eq:NN \GroupEnd@ \group_end:

    \cs_new_eq:NN \StrClearNew@N \str_clear_new:N
    \cs_new_eq:NN \StrLowerCase@f \str_lower_case:f
    \cs_new_eq:NN \StrSet@Nn \str_set:Nn

    \cs_new_eq:NN \TLClearNew@N \tl_clear_new:N
    \cs_new_eq:NN \TLSet@Nn \tl_set:Nn
\makeatother
\ExplSyntaxOff

I then include it in my main document as follows:

\documentclass{article}
\usepackage{xparse}
\input expl3x

\makeatletter
    \NewDocumentCommand \MyCommand {m s}
    {% I can use \CSIfExist@NTF, etc. here       
    }
\makeatother
\begin{document}
    % I can use \MyCommand here
\end{document}

Ideally the file expl3x.tex would be provided by the LaTeX3 project for ease and uniformity of use and so that the list is always comprehensive and up-to-date. It can be generated automatically, or semi-automatically.

OP's second example can now be programmed as follows.

\documentclass{article}
\usepackage{xparse}
\input expl3x
\makeatletter
\NewDocumentCommand \MyDef {m m m m}
{\begin{definition}[#1]
Let $S$ be a type.
We denote with #2 the \emph{\StrLowerCase@f{#1}} function $#2:S \rightarrow #4$,
which to every $s:S$, assigns $#3$.
(Hacker's note: you can use the TeX macro named "\CSToStr@N #2"
to generate this function's symbol.)
\end{definition}}
\makeatother
\NewDocumentCommand \Dbl {} {\ensuremath{\mathbf{D}}}
\NewDocumentCommand \Star {} {\ensuremath{\mathbf{S}}}
\newtheorem{definition}{Definition}
\begin{document}
\MyDef {Doubling} \Dbl {(s,s)} {S\times S}
\MyDef {Starring} \Star {(s,s,\dots)} {S^\aleph}
\end{document}

This typesets thus:

A document command written with renamed expl3 functions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.