Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Latex] Support highlighting \ExplSyntaxOn and \ExplSyntaxOff code blocks #2196

Open
evandrocoan opened this issue Nov 10, 2019 · 2 comments

Comments

@evandrocoan
Copy link
Contributor

evandrocoan commented Nov 10, 2019

  • Operating system and version:
    • Windows 10 build 15063 x64
    • Resolution 1920x1080
    • dpi_scale 1.0
    • Sublime Text:
    • Build 3207
    • 64 bit

Example code:

% Some usual latex
\documentclass[english]{article}
\usepackage{babel}
\usepackage{xparse}
\usepackage{hyperref}
\usepackage{cleveref}

% New syntax to support start here
\ExplSyntaxOn

% #1: variant (cref, Cref, crefs or Crefs)
% #2: reference name (label)
\cs_new_protected:Npn \user_name_cref:nn #1#2
  { \use:c { name #1 } {#2} }

\cs_generate_variant:Nn \user_name_cref:nn { xV }

% #1: boolean expression (true: disable hyperlink)
% #2: reference name (label)
\cs_new_protected:Npn \user_name_ref:nn #1#2
  { \bool_if:nTF {#1} { \nameref* } { \nameref } {#2} }

\cs_generate_variant:Nn \user_name_ref:nn { nV }

\seq_new:N \l__user_name_refs_tmpa_seq
\seq_new:N \l__user_name_refs_tmpb_seq
\int_new:N \l__user_name_refs_nbrefs_int
\tl_new:N \l__user_name_refs_firstref_tl

% #1: boolean expression (true: start with capitalized letter, as in \Cref)
% #2: boolean expression (true: disable hyperlinks)
% #3: comma list of refs
\cs_new_protected:Npn \user_name_refs:nnn #1#2#3
  {
    \seq_set_from_clist:Nn \l__user_name_refs_tmpa_seq {#3}
    \int_set:Nn \l__user_name_refs_nbrefs_int
                { \seq_count:N \l__user_name_refs_tmpa_seq }
    \seq_get_left:NN \l__user_name_refs_tmpa_seq \l__user_name_refs_firstref_tl

    % (section, Section, sections or Sections) or (theorem, Theorem, ...) or...
    \user_name_cref:xV
      { \bool_if:nTF {#1} { C } { c }
        ref
       \int_compare:nNnTF { \l__user_name_refs_nbrefs_int } > { 1 } { s } { } }
     \l__user_name_refs_firstref_tl
    \nobreakspace

    % Now print the references.
    \seq_clear:N \l__user_name_refs_tmpb_seq
    \seq_map_inline:Nn \l__user_name_refs_tmpa_seq
      {
        \seq_put_right:Nn \l__user_name_refs_tmpb_seq
                          { \user_name_ref:nn {#2} {##1} }
      }
    \seq_use:Nnnn \l__user_name_refs_tmpb_seq { \crefpairconjunction }
                  { \crefmiddleconjunction } { \creflastconjunction }
  }

\cs_generate_variant:Nn \user_name_refs:nnn { nx }

\cs_new_protected:Npn \__user_name_refs:Nnn #1#2#3
  {
    \user_name_refs:nxn {#1}
      { \IfBooleanTF {#2} { \c_true_bool } { \c_false_bool } }
      {#3}
  }

% “Start in lower case” variant. With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \nameRefs { s m }
  {
    \__user_name_refs:Nnn \c_false_bool {#1} {#2}
  }

% “Start in upper case” variant. With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \NameRefs { s m }
  {
    \__user_name_refs:Nnn \c_true_bool {#1} {#2}
  }

% And it ends here
\ExplSyntaxOff

% More latex normal code
\begin{document}

References:
\begin{itemize}
\item With one reference and hyperlink: \nameRefs{first} (we'll disable
  hyperlinks from now on, because their default appearance is hideous and they
  don't behave very well across line breaks);
\item With one reference: \nameRefs*{first};
\item With two references: \nameRefs*{first, second};
\item With three references: \nameRefs*{first, second, third};
\item With four references: \nameRefs*{first, second, third, fourth};
\item Capitalized variant: \NameRefs*{first, second, third, fourth};
\item etc.
\end{itemize}

% This is a cref command; beware that spaces are not ignored after the commas!
For comparison, the \verb|\cref| command: \cref{first,second,third,fourth}.

\section{First section}
\label{first}

\section{Second section}
\label{second}

\section{Third section}
\label{third}

\section{Fourth section}
\label{fourth}

\end{document}

References:

  1. https://tex.stackexchange.com/questions/108696/what-do-explsyntaxon-and-explsyntaxoff-do
  2. https://tex.stackexchange.com/questions/505351/how-to-nameref-multiple-labels-simultaneously
  3. expl3 syntax highlighting textmate/latex.tmbundle#79 expl3 syntax highlighting
@ngc92
Copy link
Contributor

ngc92 commented Oct 24, 2022

Here is an attempt at making an expl3 sub-language. This does not allow for switching between syntaxes with
\ExplSyntaxOn/ \ExplSyntaxOff, but applies instead to the entire file.

%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Expl3
scope: text.tex.latex.expl3

file_extensions:
  - sty
  - cls
  - tex

extends: Packages/LaTeX/LaTeX.sublime-syntax

variables:
  scoped_var_name: '(__)?(_)?(?:([A-Za-z]+)(_))?([A-Za-z_]+)(_)(bool|box|cctab|clist|coffin|dim|fp|ior|iow|int|muskip|prop|seq|skip|str|tl)'

contexts:
  general-commands:
      - meta_prepend: true
      - include: expl3-fun
      - include: expl3-var

  general-constants:
    - meta_prepend: true
    # we need to ensure that \__ will be matched as the start of a command name,
    # not as an escaped underscore !
    - match: '(?=(\\)__)'
      push:
        # try to match a function, and immediately leave the context
        - include: expl3-fun
        - match: ''
          pop: true

  expl3-fun:
    - match: '(\\)(__)?([A-Za-z]+)(_)([A-Za-z_]+)(:)([nNpTFDwcVvxefo]+)'
      scope: variable.function.expl3
      captures:
        1: punctuation.definition.backslash.expl3
        2: storage.modifier.private.expl3
        3: entity.name.namespace.expl3
        4: punctuation.accessor.underscore.expl3
        6: punctuation.separator.annotation.expl3
        7: meta.annotation.parameters.expl3

  expl3-var:
    - match: '(\\)([lg]){{scoped_var_name}}'
      scope: variable.other.readwrite.expl3 support.function.expl3
      captures:
        1: punctuation.definition.backslash.expl3
        2: storage.modifier.expl3
        3: storage.modifier.expl3
        4: punctuation.separator.expl3
        5: entity.name.namespace.expl3
        6: punctuation.separator.expl3
        8: punctuation.separator.annotation.expl3
        9: variable.annotation.expl3
    - match: '(\\)(c){{scoped_var_name}}'
      scope: variable.other.constant.expl3 support.function.expl3
      captures:
        1: punctuation.definition.backslash.expl3
        2: storage.modifier.expl3
        3: storage.modifier.expl3
        4: punctuation.separator.expl3
        5: entity.name.namespace.expl3
        6: punctuation.separator.expl3
        8: punctuation.separator.annotation.expl3
        9: variable.annotation.expl3

The expl3 part of the example above then looks like
Example

@mgkurtz
Copy link

mgkurtz commented Nov 14, 2023

Nice ♥️

Are there any chances of adding this to the latex syntax highlighting? That would be really great for viewing the lots of LaTeX3 code that exists nowadays.

Given that @ngc92’s syntax definition is rather precise and the fact that _ is usually not allowed outside math mode, there should be only rather few regressions: some\abc_x: appearing in a math formula, or when giving file names including a macro like \url{http://example.org/\basename_xyz:new.html}. Both seems rather rare.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants