Programming LaTeX3: The programming environment

In the previous post, I mentioned that programming LaTeX3 today really means programming using LaTeX3 ideas but on top of LaTeX2e. To do that, we are going to need to load the appropriate code, and then access the LaTeX3 programming environment. The exact detail depends on whether we are programming in the preamble of a LaTeX document or creating a package. I’ll look at both of these before taking a closer look at the LaTeX3 programming environment in general.  What you should notice is that the use of a separate programming environment very much separates out the process of creating code from creating documents: that is quite deliberate and is something that we’ll see again in the series.

In the preamble of a document

The LaTeX3 programming code usable with LaTeX2e is available as a package called expl3 (which for various reasons is distributed as part of l3kernel). This is loaded in the usual way


That loads the code, but does not get us into the programming environment. To do that, we need to use a couple of new macros

% Code goes here

In some ways, this is similar to the LaTeX2e \makeatletter … \makeatother idea, but as we’ll see it’s a bit more advanced.

In a LaTeX2e package

In exactly the same way as in a document, the first stage in using LaTeX3 programming in a package is to load the code.


Once again, that loads the code but does not switch the syntax on. We could use \ExplSyntaxOn here, but for packages a more flexible alternative is to declare the package as being LaTeX3-based:

  {mypkg}               % Package name
  {2011-12-11}          % Release date
  {1.0}                 % Release version
  {Some things I wrote} % Description

This is a special version of the standard \ProvidesPackage macro, which will automatically turn on LaTeX3 programming syntax and more importantly turn it off at the end of the package. It also deals properly with nested package loading, and so is the recommended way to use LaTeX3 syntax inside LaTeX2e packages.

The coding environment

Whether you’re using LaTeX3 syntax in a document or a package, the basic ideas are the same. The first thing to notice is that white space (spaces, tabs and new lines) are ignored inside the programming environment. This means we can use it to lay out our code more clearly, but you might wonder how to actually include a space. This is handled by defining ~ as a ‘normal’ space, rather than as the usual non-breaking version.

The programming environment also makes it possible to use : and _ inside the names of commands, which are more formally called control sequences. TeX decides what is a valid control sequence name based on something called the category code of each character. I’ll be explaining more about category code as we go along, but for the moment the key is to understand that that a control sequence is \ followed either by exactly one non-‘letter’ or by one or more ‘letters’. Inside the code environment : and _ are treated as letters by TeX: this is the same idea as using @ as an extra ‘letter’ in LaTeX2e code.

Not only are : and _ available for use in control sequences but they are required by the conventions of LaTeX3 programming. In contrast to LaTeX2e’s sometimes haphazard use of @ in names, there are guidelines for applying both : and _ in LaTeX3 names. Rather than give a formal list now, I’ll bring in the system in the next couple of posts using some examples.

One difference between programming in a document and in a package is the status of @. LaTeX2e automatically makes it a letter in package code, but in a document this does not happen. LaTeX3 does not assign any special meaning to @, and so these difference are not affected by loading LaTeX3 support.

A standard document

As we’ll be needing the basics here for everything from now on, I’ll assume that you are using a short testing document for LaTeX3 programming:

% Code will go here

6 thoughts on “Programming LaTeX3: The programming environment

  1. Many thanks for this useful, interesting series. Learning LaTeX3 is one thing on the top of my “todo” list.

    In the case of LaTeX3 programming in a package, is still allowed to end the package code with endinput? Is it needed a different command? By the way, I conjecture that it is also possible to write document classes with LaTeX3. Is there a ProvidesExplClass command?

  2. You can put endinput at the end of your packages, if you which: I’ve never understood why people do this!

    There is a ProvidesExplClass macro, but I’ve omitted it deliberately. LaTeX2e is rather loose on separating out code (packages) from design (classes). While we are not at the stage of having a design system set up yet, it’s clear that we’ll want to be much clearer on this. So as far as possible I’d want to see code in packages, not in classes. With LaTeX2e that’s not entirely possible, but as I’m talking about programming LaTeX3 here I’m sticking with code-in-packages.

  3. Programming Environment. LaTeX2e package option:
    (1) What I am used to doing with my newcommand libraries is packing them into an .sty file, call this MyMacros.sty, the top line of which says: ProvidesPackage{MyMacros}. In the preamble of any document that wishes to use MyMacros.sty I have a line saying: usepackage{MyMacros}. This worked for my newcommands and even works for my LaTeX3 NewDocumentCommand s, and also for the macros from you tutorial.
    (2) Unfortunately I can’t get the syntax right to follow your suggestion to use RequirePackage{expl3} and ProvidesExplPackage instead. I tried a number of variants, but none compile. One that would seem perfectly logical to me is: MyMacros.sty again contains my macros. The top of MyMacros.sty says:
    In any document using MyMacros.sty I again say:
    Does not compile. What am I doing wrong?
    P.S. It took me a while to become aware of this series of tutorials. They are great and came at a time when I had concluded that reading interface3 etc. unaided was a hopeless undertaking.

  4. Thanks a lot, Joseph for this very nice introduction to LaTeX3!

    AFAICS in the following MWE, ProvidesExplPackage doesn’t allow to load the package with usepackage. By contrast, loading it with input works like a charm.

    {mypkg} % Package name
    {2014-09-15} % Release date
    {0.1} % Release version
    {Some tests} % Description
    % usepackage{mypkg}

    Did I miss something?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.