57

I'm starting to embed LaTeX3 code in my custom classes and packages -- and enjoying it more the further I learn about it --, but at least to me it would make for an even better experience if, as it is common in the computer languages I work with regularly, I could use some editor sensitive to LaTeX3 in terms, at least, of highlighting.

It may be a little too early for this, given that the interface (and the implementation itself, as far as my knowledge goes) is still work in progress and not everything that is already available is stable, but entire stability (if there is such a thing) may be far ahead on the road and it seems to me that we already have elements considered stable enough for us to benefit from such editing features.

True, one could always setup a favorite text editor accordingly (WinEdt is my regular editor for all things TeX, but I'm not committed to any editor in particular), but I'm asking for something already made... and trying to bring the attention of developers to this topic.

Anyone knows of some editor out there with this kind of features? Are there any projects in this direction?

9
  • 1
    If you are after highlighting for expl3, any decent editor allows customisation. There are lots of editors out there, and it's not clear to me that you need a special one for expl3 code, just the appropriate settings if that it how you like to work. (I just use the same TeXworks settings I have for .dtx editing generally. I probably should make some rules for expl3 highlighting!)
    – Joseph Wright
    Aug 21, 2013 at 17:37
  • 2
    @Joseph Wright: Right, I was not asking for a particular editor just for expl3 syntax, but for any who did already embed rules for highlighting that syntax. I believe that in order to be able to set my editor in that regard in an effective way I still need to know a lot more about LaTeX3 than I do now. Btw, let me say that I just read today your TUGboat article on l3keys and it was instrumental in my becoming able to start using LaTeX3 for the keys in my classes and packages. I wonder why these articles are not included in the documentation.
    – Marcos
    Aug 21, 2013 at 18:10
  • 1
    On the articles, they are a bit piecemeal. What we really need is a proper beginners guide, but that's hard to write!
    – Joseph Wright
    Aug 21, 2013 at 20:45
  • 2
    I would like to make an add-on for WinEdt, if I only knew what exactly has to be highlighted... Unfortunately (my fault) I've never started learning LaTeX3. Aug 22, 2013 at 6:00
  • @karlkoeller: Well, to me at least having such an add-on for WinEdt would be great, because this is my favorite editor-(sort of) IDE for everything TeX-based (on Windows). One of the points I was addressing in my answer to Joseph Wright was precisely about what and how to highlight... I still need to take a close look at his answer, which provides much more than I was expecting of any answer for my post. Maybe by inspecting it you can get insight enough to make some choices on what and howto devide the expl3 syntax highlighting... If you come up with something, please do let me know! ;-)
    – Marcos
    Aug 22, 2013 at 6:22

7 Answers 7

37
+550

Update (2017-02-14)

Thanks to the time spent on the answer below, and to some new features in WinEdt 10.2, now WinEdt 10.2 is really "LaTeX3-sensitive".

WinEdt 10.2 incorporates the highlighting scheme in this answer (with many improvements) and features many other functionalities to support LaTeX3 (e.g. command completion for commands and environments defined with \NewDocumentCommand, \NewDocumentEnvironment and alike).


Complete Highlighting Scheme for WinEdt

This is a highlighting scheme for expl3 in WinEdt 8.

New: It is now available as an add-on: LaTeX3


Highlighting LaTeX3 guards in .dtx files

Add the following lines in Switches.ini just before the switch SWITCH="DTX Single Guard"

SWITCH="DTX LaTeX3 Guard"
  ENABLED=1
  MODE_FILTER="DTX"
  START="DTX %"
  STOP=">"
  HIGHLIGHT_START=1
  STEP_OVER_STOP=1
  HIGHLIGHT_STOP=1
  SCOPE=1
  DOMINANT_PRIORITY=0
  STRICT_PRIORITY=1
  PRIORITY=9
  INDENTED=0
  BOLN_ONLY=1
  CASE_SENSITIVE=1
  START1_TRIGGER=""
  START2_TRIGGER="<@@="
  STOP1_TRIGGER=""
  STOP2_TRIGGER=""
    TEXT_COLOR=5
    BACKGROUND_RGB="$F8F8F8"
    TRANSPARENT=144
    DEFAULT_FONT=1

Result:

enter image description here

Collecting LaTeX3 guards in the "Tree"

Add the following lines in Tree.ini inside the branch BRANCH="Guards-DTX", just between the lines END="</?>" and ITEM="<?>"

  ITEM="<@@=?>"
    MODE_FILTER="DTX"
    CASE_SENSITIVE=1
    LINE_START="%"
    BEGINNING_OF_LINE_ONLY=2
    CURRENT_DOCUMENT_ONLY=1
    ALL_OPENED_DOCUMENTS=0
    COMPLETE_PROJECT_TREE=1
    ICON="ArrowPurple"
    LEVEL=0
    CAPTION="%?"
    MAX_LINE_SPAN=1
    ON_CTRL_CLICK_MACRO="GlobalMark;TreeTrack(2);"
    ON_CLICK_MACRO="TreeTrack(2,1);"
    ON_DBL_CLICK_MACRO="TreeTrack(2,2);"
    ACTION="Find"
      IMAGE="Find"
      MACRO="TreeTrack(2);"
  END="<@@=?>"

Result:

enter image description here

Highlighting LaTeX3 commands

Add the following lines in FilterSets.ini just before the set FILTER_SET="~AlphaNumeric"

FILTER_SET="~Alpha@_:"
  ENABLED=0
  MODE_FILTER=""
  SET=:~(Alpha+["@_:"])
  BEFORE=""
  AFTER=""
  BOLN_NOT_OK=0
  EOLN_NOT_OK=0
  STRICT_PRIORITY=0
  PRIORITY=0
    DEFAULT_FONT=1

Then, in Switches.ini, in the switch SWITCH="\", replace the line

STOP="~Alpha@"

with

STOP="~Alpha@_:"

Finally, in Keywords.ini, replace all occurrences of

AFTER="~Alpha@"

with

AFTER="~Alpha@_:"

Result:

enter image description here

Highlighting LaTeX3 Kernel keywords

Add the following lines in Switches.ini just before the switch SWITCH="\"

SWITCH="LaTeX3 Kernel Engine Prefixes"
  ENABLED=1
  MODE_FILTER="TeX"
  START="\"
  STOP="~Alpha@_:"
  HIGHLIGHT_START=1
  STEP_OVER_STOP=0
  HIGHLIGHT_STOP=0
  SCOPE=0
  DOMINANT_PRIORITY=0
  STRICT_PRIORITY=0
  PRIORITY=5
  INDENTED=0
  BOLN_ONLY=0
  CASE_SENSITIVE=1
  START1_TRIGGER=""
  START2_TRIGGER="luatex_if_engine"
  START2_TRIGGER="pdftex_if_engine"
  START2_TRIGGER="xetex_if_engine"
  STOP1_TRIGGER=""
  STOP2_TRIGGER=""
    TEXT_COLOR=5
    DEFAULT_FONT=1
    BOLD=1

SWITCH="LaTeX3 Kernel Prefixes"
  ENABLED=1
  MODE_FILTER="TeX"
  START="\"
  STOP="~Alpha@_:"
  HIGHLIGHT_START=1
  STEP_OVER_STOP=0
  HIGHLIGHT_STOP=0
  SCOPE=0
  DOMINANT_PRIORITY=0
  STRICT_PRIORITY=0
  PRIORITY=5
  INDENTED=0
  BOLN_ONLY=0
  CASE_SENSITIVE=1
  START1_TRIGGER=""
  START2_TRIGGER="alloc_"
  START2_TRIGGER="bool_"
  START2_TRIGGER="box_"
  START2_TRIGGER="cctab_"
  START2_TRIGGER="char_"
  START2_TRIGGER="chk_"
  START2_TRIGGER="clist_"
  START2_TRIGGER="codedoc_"
  START2_TRIGGER="coffin_"
  START2_TRIGGER="color_"
  START2_TRIGGER="cs_"
  START2_TRIGGER="dim_"
  START2_TRIGGER="driver_"
  START2_TRIGGER="else_"
  START2_TRIGGER="etex_"
  START2_TRIGGER="exp_"
  START2_TRIGGER="expl_"
  START2_TRIGGER="fi_"
  START2_TRIGGER="fp_"
  START2_TRIGGER="group_"
  START2_TRIGGER="hbox_"
  START2_TRIGGER="hcoffin_"
  START2_TRIGGER="if_"
  START2_TRIGGER="insert_"
  START2_TRIGGER="int_"
  START2_TRIGGER="kernel_"
  START2_TRIGGER="keys_"
  START2_TRIGGER="keyval_"
  START2_TRIGGER="lua_"
  START2_TRIGGER="luatex_"
  START2_TRIGGER="mode_"
  START2_TRIGGER="muskip_"
  START2_TRIGGER="or_"
  START2_TRIGGER="pdftex_"
  START2_TRIGGER="peek_"
  START2_TRIGGER="prop_"
  START2_TRIGGER="quark_"
  START2_TRIGGER="reverse_"
  START2_TRIGGER="seq_"
  START2_TRIGGER="skip_"
  START2_TRIGGER="str_"
  START2_TRIGGER="tex_"
  START2_TRIGGER="tl_"
  START2_TRIGGER="token_"
  START2_TRIGGER="use_"
  START2_TRIGGER="vbox_"
  START2_TRIGGER="vcoffin_"
  START2_TRIGGER="xetex_"
  STOP1_TRIGGER=""
  STOP2_TRIGGER=""
    TEXT_COLOR=4
    DEFAULT_FONT=1
    BOLD=1

SWITCH="LaTeX3 File Handling"
  ENABLED=1
  MODE_FILTER="TeX"
  START="\"
  STOP="~Alpha@_:"
  HIGHLIGHT_START=1
  STEP_OVER_STOP=0
  HIGHLIGHT_STOP=0
  SCOPE=0
  DOMINANT_PRIORITY=0
  STRICT_PRIORITY=0
  PRIORITY=5
  INDENTED=0
  BOLN_ONLY=0
  CASE_SENSITIVE=1
  START1_TRIGGER=""
  START2_TRIGGER="file_"
  START2_TRIGGER="g_file_"
  START2_TRIGGER="ior_"
  START2_TRIGGER="iow_"
  START2_TRIGGER="l_ior_"
  START2_TRIGGER="l_iow_"
  STOP1_TRIGGER=""
  STOP2_TRIGGER=""
   TEXT_COLOR=2
   DEFAULT_FONT=1
   BOLD=1

SWITCH="LaTeX3 Package Messages"
 ENABLED=1
 MODE_FILTER="TeX"
 START="\"
 STOP="~Alpha@_:"
 HIGHLIGHT_START=1
 STEP_OVER_STOP=0
 HIGHLIGHT_STOP=0
 SCOPE=0
 DOMINANT_PRIORITY=0
 STRICT_PRIORITY=0
 PRIORITY=5
 INDENTED=0
 BOLN_ONLY=0
 CASE_SENSITIVE=1
 START1_TRIGGER=""
 START2_TRIGGER="msg_"
 STOP1_TRIGGER=""
 STOP2_TRIGGER=""
  TEXT_COLOR=9
  DEFAULT_FONT=1
  ITALIC=1

SWITCH="LaTeX3 NoOp Functions"
 ENABLED=1
 MODE_FILTER="TeX"
 START="\"
 STOP="~Alpha@_:"
 HIGHLIGHT_START=1
 STEP_OVER_STOP=0
 HIGHLIGHT_STOP=0
 SCOPE=0
 DOMINANT_PRIORITY=0
 STRICT_PRIORITY=0
 PRIORITY=5
 INDENTED=0
 BOLN_ONLY=0
 CASE_SENSITIVE=1
 START1_TRIGGER=""
 START2_TRIGGER="prg_"
 START2_TRIGGER="scan_"
 STOP1_TRIGGER=""
 STOP2_TRIGGER=""
  TEXT_COLOR=3
  DEFAULT_FONT=1
  BOLD=1

Then, add the following lines in Keywords.ini just before the group KEYWORD_GROUP="TeX Units"

KEYWORD_GROUP="LaTeX3  Keywords"
  ENABLED=1
  MODE_FILTER="TeX"
  BEFORE="\ (single)"
  AFTER="~Alpha@_:"
  BOLN_NOT_OK=1
  EOLN_NOT_OK=0
  STRICT_PRIORITY=0
  PRIORITY=6
  CASE_SENSITIVE=1
    TEXT_COLOR=0
    DEFAULT_FONT=1
    BOLD=1
    UNDERLINE=1
LIST="END_LIST"
ExplSyntaxOff
ExplSyntaxOn
END_LIST

KEYWORD_GROUP="LaTeX3  Keywords..."
  ENABLED=1
  MODE_FILTER="TeX"
  BEFORE="\ (single)"
  AFTER="~Alpha@_:"
  BOLN_NOT_OK=1
  EOLN_NOT_OK=0
  STRICT_PRIORITY=0
  PRIORITY=6
  CASE_SENSITIVE=1
    TEXT_COLOR=4
    DEFAULT_FONT=1
    BOLD=1
LIST="END_LIST"
DeclareDocumentCommand
DeclareDocumentEnvironment
NewDocumentCommand
NewDocumentEnvironment
ProvideDocumentCommand
ProvideDocumentEnvironment
RenewDocumentCommand
RenewDocumentEnvironment
END_LIST

Result:

enter image description here

Highlight LaTeX3 properties & constants

This is the best that can be done for this one.

Add the following lines in FilterSets.ini just before the set FILTER_SET="="

FILTER_SET="."
  ENABLED=0
  MODE_FILTER=""
  SET=:["."]
  BEFORE=""
  AFTER=""
  BOLN_NOT_OK=0
  EOLN_NOT_OK=0
  STRICT_PRIORITY=0
  PRIORITY=0
    DEFAULT_FONT=1

Then, add the following lines in Switches.ini just before the switch SWITCH="\" (after the newly defined switch SWITCH="LaTeX3 Kernel Prefixes")

SWITCH="LaTeX3 Properties"
  ENABLED=1
  MODE_FILTER="TeX"
  START="."
  STOP=":"
  HIGHLIGHT_START=1
  STEP_OVER_STOP=1
  HIGHLIGHT_STOP=1
  SCOPE=0
  DOMINANT_PRIORITY=0
  STRICT_PRIORITY=0
  PRIORITY=5
  INDENTED=0
  BOLN_ONLY=0
  CASE_SENSITIVE=1
  START1_TRIGGER=""
  START2_TRIGGER="code"
  START2_TRIGGER="choice"
  START2_TRIGGER="choice_code"
  START2_TRIGGER="generate_choices"
  START2_TRIGGER="initial"
  START2_TRIGGER="default"
  START2_TRIGGER="meta"
  START2_TRIGGER="alloc_"
  START2_TRIGGER="bool_"
  START2_TRIGGER="box_"
  START2_TRIGGER="cctab_"
  START2_TRIGGER="char_"
  START2_TRIGGER="chk_"
  START2_TRIGGER="clist_"
  START2_TRIGGER="codedoc_"
  START2_TRIGGER="coffin_"
  START2_TRIGGER="color_"
  START2_TRIGGER="cs_"
  START2_TRIGGER="dim_"
  START2_TRIGGER="driver_"
  START2_TRIGGER="else_"
  START2_TRIGGER="etex_"
  START2_TRIGGER="exp_"
  START2_TRIGGER="expl_"
  START2_TRIGGER="fi_"
  START2_TRIGGER="file_"
  START2_TRIGGER="fp_"
  START2_TRIGGER="group_"
  START2_TRIGGER="hbox_"
  START2_TRIGGER="hcoffin_"
  START2_TRIGGER="if_"
  START2_TRIGGER="insert_"
  START2_TRIGGER="int_"
  START2_TRIGGER="ior_"
  START2_TRIGGER="iow_"
  START2_TRIGGER="kernel_"
  START2_TRIGGER="keys_"
  START2_TRIGGER="keyval_"
  START2_TRIGGER="lua_"
  START2_TRIGGER="luatex_"
  START2_TRIGGER="mode_"
  START2_TRIGGER="msg_"
  START2_TRIGGER="muskip_"
  START2_TRIGGER="or_"
  START2_TRIGGER="pdftex_"
  START2_TRIGGER="peek_"
  START2_TRIGGER="prg_"
  START2_TRIGGER="prop_"
  START2_TRIGGER="quark_"
  START2_TRIGGER="reverse_"
  START2_TRIGGER="scan_"
  START2_TRIGGER="seq_"
  START2_TRIGGER="skip_"
  START2_TRIGGER="str_"
  START2_TRIGGER="tex_"
  START2_TRIGGER="tl_"
  START2_TRIGGER="token_"
  START2_TRIGGER="use_"
  START2_TRIGGER="vbox_"
  START2_TRIGGER="vcoffin_"
  START2_TRIGGER="xetex_"
  STOP1_TRIGGER=""
  STOP2_TRIGGER="n"
  STOP2_TRIGGER="N"
  STOP2_TRIGGER="x"
    TEXT_COLOR=1
    DEFAULT_FONT=1
    ITALIC=1

SWITCH="LaTeX3 Kernel Constants"
  ENABLED=1
  MODE_FILTER="TeX"
  START="\"
  STOP="~Alpha@_:"
  HIGHLIGHT_START=1
  STEP_OVER_STOP=0
  HIGHLIGHT_STOP=0
  SCOPE=0
  DOMINANT_PRIORITY=0
  STRICT_PRIORITY=0
  PRIORITY=5
  INDENTED=0
  BOLN_ONLY=0
  CASE_SENSITIVE=1
  START1_TRIGGER=""
  START2_TRIGGER="c_"
  STOP1_TRIGGER=""
  STOP2_TRIGGER=""
    TEXT_COLOR=6
    DEFAULT_FONT=1
    ITALIC=1

Result:

enter image description here

2
  • 3
    I've recently started to (try to) learn something about LaTeX3, and this add-on you've made for WinEdt is great. As the others you've made, which I daily use for my work, they have saved me a lot of time. So I've decided to award you a bounty, not only for this answer, but for all the add-ons you've made and I use. This is nothing for me compared with the help you've given me with your work. Thanks, Karl.
    – Sterry
    Jan 15, 2015 at 18:31
  • @Sterry I don't have words to thank you, both for the bounty and for the compliments!!!! Jan 15, 2015 at 18:39
30

For the record, here's my font-lock settings for Emacs with LaTeX3. To make use of these, I define a latex3-mode which is derived from the inbuild latex-mode. (Note: I don't use AucTeX, I use the simple TeX modes.) The idea of the font-locking is similar to Joseph's in that it adds more matches for highlighting. I've added a specials for core functions (probably not included them all as yet). There's also a distinction between macros with a _ and ones without (such as ordinary LaTeX2e macros/functions and the xparse ones). I could probably do with defining a few more faces to further distinguish, but this is currently working well enough for me.

(defconst latex3-font-lock-keywords
   (eval-when-compile
     (let* (;; Commands relevant to data structures
            (specials "\\(bool\\|char\\|clist\\|cs\\|exp\\|file\\|group\\|keys\\|prop\\|q\\|seq\\|tl\\)_[a-zA-Z_:]+")
            (general "\\([a-zA-Z_:]+\\)")
            (camel "\\([a-zA-Z@]+\\)")
            (nocamel "\\(?:[^a-zA-Z@_:]\\)")
            (slash "\\\\")
            )
       (list
        (list (concat "\\(" slash specials "\\)")
              1 'font-lock-function-name-face)
        (list (concat "\\(" slash camel "\\)" nocamel) 1 'font-lock-function-name-face)
        (list (concat "\\(" slash general "\\)") 1 'font-lock-variable-name-face)
        )
       )
     )
  "Extra commands to highlight in LaTeX3 modes."
  )

(define-derived-mode latex3-mode latex-mode "LaTeX3"
  "Major mode to edit LaTeX3 files."
  (set (make-local-variable 'font-lock-defaults)
       '((tex-font-lock-keywords latex3-font-lock-keywords) 
         nil nil ((?$ . "\"")) nil
         ;; Who ever uses that anyway ???
         (font-lock-mark-block-function . mark-paragraph)
         (font-lock-syntactic-face-function
          . tex-font-lock-syntactic-face-function)
         (font-lock-unfontify-region-function
          . tex-font-lock-unfontify-region)
         (font-lock-syntactic-keywords
          . tex-font-lock-syntactic-keywords)
         (parse-sexp-lookup-properties . t)))
 )

(add-hook 'latex3-mode-hook (function (lambda () (setq ispell-parser 'tex))))
(add-hook 'latex3-mode-hook '(lambda () (flyspell-mode 0)))

Here's a screenshot (where you can see that I should add box and vbox to my list of special functions):

Emacs with L3 font-locking

13
  • 3
    There is a list of all module prefixes in github.com/latex3/svn-mirror/blob/master/l3kernel/… if you want to have a 'definitive' reference for the kernel ones.
    – Joseph Wright
    Aug 22, 2013 at 6:50
  • 1
    I should add that suggestions for improvements would be more than welcome! Aug 22, 2013 at 6:52
  • In a way, I'm glad you beat me to it. +1! One question though: Is the pilcrow being inserted by the settings you've given, or are those your own personal preference? Aug 22, 2013 at 13:31
  • @SeanAllred I'm guessing that the pilcrow is the newline mark. It's put there by longlines-mode, which I use to make it so that I can write one sentence per line in my normal LaTeX documents. I guess it doesn't make as much sense in a package but then I never claimed to have everything set up perfectly. Aug 22, 2013 at 13:44
  • 1
    @SeanAllred The pilcrow's distinguish between "hard" new lines and "soft" new lines. Those with a pilcrow are "hard" and will be preserved when the file is written out. Those without are "soft" and will be removed when the file is written out. Aug 22, 2013 at 17:48
24

TeXworks uses a simple regex-based approach to syntax highlighting, with the information stored in the file syntax-patterns.txt inside the folder TeXworks/configuration, which lives in a system-dependent location. I have a set of patterns for working with .dtx (LaTeX documented source) files, which include highlighting for expl3 code:

[LaTeX DTX]

# comments
red        Y    \^\^A.*

# Guards
orange         N    %<(?:[A-Za-z0-9!\|]+|.)>
limegreen      N    %<\*(?:[A-Za-z0-9!\|]+|.)>
crimson        N    %</(?:[A-Za-z0-9!\|]+|.)>
darkviolet     N    %<@@=(?:[A-Za-z]+|.)>

# special characters
darkred        N    \^\^\^\^\^[0-9a-z]{5}
darkred        N    \^\^\^\^[0-9a-z]{4}
darkred        N    \^\^\^[0-9a-z]{3}
darkred        N    \^\^[0-9a-z]{2}
darkred        N    [$#^_{}&]
gray        N    ^%%.*
gray        N    ^%

# Macrocode
green        N    \\(?:begin|end)\{macrocode\}

# LaTeX environments
darkgreen    N    \\(?:begin|end)\s*\{[^}]*\}

# control sequences
blue        N    \\(?:[A-Za-z@:_]+|.)

(The colour scheme is based on that used by WinEdt for .dtx editing, as I used to use WinEdt.)

The key line is the last one, as regex \\(?:[A-Za-z@:_]+|.) matches both expl3 and 'standard' LaTeX2e macro names. If you wanted to only highlight expl3 code-level macros in one colour, you could go with something like

# functions
blue        N    \\(?:[A-Za-z_]+):(?:[A-Za-z_:]+|.)
# Variables
blue    N    \\(?:[A-Za-z_]+)_(?:[A-Za-z_]+|.)

which then won't highlight document/design level (just letter in the name) or LaTeX2e internal (@ in the name) control sequences. You could of course get more sophisticated and give them all different highlighting! You could also extend the regexes in the way Andrew Stacey does in his answer to differentiate expl3 core and 'additional' names, using a more sophisticated set of regexes.

Note that I've also extended the .dtx guards recognised to cover the %<@@=...> one that l3doscrip adds to the 'standard' set, for marking internal names. It's covered by the line

darkviolet     N    %<@@=(?:[A-Za-z]+|.)>

where I had to find a new colour to fit in with those that were already in use!

13
  • 2
    Note: I am no regex expert. My edits to the TeXworks standard set up work more by luck than design :-)
    – Joseph Wright
    Aug 21, 2013 at 20:47
  • Since I've made the DTX highlighting scheme in WinEdt, can you tell me what is missing there so I will be able to enhance it? Aug 22, 2013 at 6:29
  • This makes for much more than I was expecting from an answer to my question. I still have to look more closely into it, but I'm sure it's going to prove very helpful as a reference to develop some configuration script for an editor. Although it is discouraged doing so on this site, let me thank you for your answer and for your great work on the LaTeX3 stuff.
    – Marcos
    Aug 22, 2013 at 6:31
  • @karlkoeller To the '.dtx set' from WinEdt I've added one thing and made one alteration. l3docstrip has an additional guard type, %<@@=...>, which is covered by %<@@=(?:[A-Za-z]+|.)> and I made dark violet. For command names, I had to extend the characters included to not just a-zAZ and @ but also _ and :, which is what \\(?:[A-Za-z@:_]+|.) does. Note that I started 'from scratch', taking only the colour scheme from WinEdt but not any actual matching code (does WinEdt use regexes?).
    – Joseph Wright
    Aug 22, 2013 at 6:34
  • Obviously, any other editor using a regex-based approach can be modified in a similar way.
    – Joseph Wright
    Aug 22, 2013 at 6:37
7

Visual Studio Code with the extension LaTeX Workshop (> v3.5.0) can support LaTeX3 syntax now:

enter image description here

5

TeXstudio

Since the commit 1f9841 TeXstudio now also has some basic syntax highlighting for expl3 code. I assume that this new feature will be included in TeXstudio 4.7.4 onward.

Here an example using the code fragment kindly provided by @Skillmon with the current development version of TeXstudio:

enter image description here

(note that the alternative syntax highlighting gets triggered by \ExplSyntaxOn ... \ExplSyntaxOff, so you'll notice in case you are missing them somewhere because the syntax highlighting won't work there)

2
  • Does it change syntax highlighting outside of \ExplSyntaxOn...\ExplSyntaxOff?
    – Skillmon
    Apr 16 at 18:34
  • @Skillmon No, as far as I understand the code, the \ExplSyntaxOn...\ExplSyntaxOff is used as trigger to switch to a different highlighting scheme Apr 16 at 18:45
5

TeXShop

Beginning with version 5.27, TeXShop can color expl3 code. All of chapter 24 of the TeXShop Manual (accessed via Help -> TeXShop Manual) is devoted to this feature. It can be toggled on and off by selecting the Source -> Syntax Color expl3 Code menu option. Included is a screenshot showing the source for siunitx.sty.

TeXShop's source window showing expl3 syntax highlighting

2
  • Thanks for adding this. I came here to add an answer, since I was the person who convinced Dick to add it in the first place. :)
    – Alan Munn
    Apr 17 at 15:35
  • I learned the hard way not to request features. Apr 17 at 16:55
4

VIM with vimtex

vimtex supports expl3 syntax highlighting (inside of \ExplSyntaxOn...\ExplSyntaxOff or after \ProvidesExpl...).

enter image description here

(as you can see, above \ExplSyntaxOn the L3 code isn't recognised and only \cs, \_, and \group are considered macros; Nn, fontspec, and calc are considered typos if you have spell checking active)


Code used in above's screenshot is part of (some version of) fontspec (I just typed it from stone-zeng's answer to get comparable code):

\cs_new:Nn \__fontspec_calc_scale:n
  {
    \group_begin:
\ExplSyntaxOn
\cs_new:Nn \__fontspec_calc_scale:n
  {
    \group_begin:

      \fontencoding { \encodingdefault }
      \fontfamily { \rmdefault }
      \selectfont

      \__fontspec_set_font_dimen:NnN \l__fontspec_tmpa_dim {#1} \font
      \__fontspec_set_font_dimen:NnN \l__fontspec_tmpb_dim {#1} \l_fontspec_font

      \tl_gset:Nx \l__fontspec_scale_tl
        {
          \fp_eval:n { \dim_to_fp:n {\l__fontspec_tmpa_dim} /
                       \dim_to_fp:n {\l__fontspec_tmpb_dim} }
        }

      \__fontspec_info:n {set-scale}
    \group_end:
  }
\cs_new:Nn \__fontspec_set_font_dimen:NnN
  {
    \dim_set:Nn #1 { \fontdimen #2 #3 }
    \dim_compare:nNnT #1 = {0pt}
      {
        \settoheight #1
          {
3

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .