Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
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 '13 at 17:37
1  
@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 '13 at 18:10
    
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 '13 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. –  karlkoeller Aug 22 '13 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 '13 at 6:22

3 Answers 3

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

share|improve this answer

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

share|improve this answer
1  
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 '13 at 6:50
    
I should add that suggestions for improvements would be more than welcome! –  Loop Space Aug 22 '13 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? –  Sean Allred Aug 22 '13 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. –  Loop Space Aug 22 '13 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. –  Loop Space Aug 22 '13 at 17:48

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!

share|improve this answer
1  
Note: I am no regex expert. My edits to the TeXworks standard set up work more by luck than design :-) –  Joseph Wright Aug 21 '13 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? –  karlkoeller Aug 22 '13 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 '13 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 '13 at 6:34
    
Obviously, any other editor using a regex-based approach can be modified in a similar way. –  Joseph Wright Aug 22 '13 at 6:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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