18

Is there any Sublime package to syntax-highlight HTML inside JavaScript strings?

(Note the question is only about HTML inside JS strings, not syntax highlighting in general.)

Specifically I am writing Angular components using inline templates

angular.module('compMod', []).component('myComp', {
    template: `<div>Some Text</div>`
});

and looking to highlight HTML syntax inside the ES6 template strings.

4
  • 1
    I don't know if there's a package like that, but I feel like it's not a good idea anyway. You probably want things inside template strings to be highlighted properly when it's not HTML. You could, however, use templateUrl and link to a template file instead of using a template string. Commented Mar 26, 2016 at 0:38
  • @Calvin There is an advantage to inline templates to have everything in one place, it is frequently used, e.g. here, but as far as I know the author of that package uses Webstorm which does exactly that. Commented Mar 26, 2016 at 0:55
  • Open an issue in sublimehq's Packages repo on Github and make a request using the [JavaScript] tag. In the latest version of JavaScript.sublime-syntax, template strings in backticks are marked as such, so it shouldn't be too difficult to import the HTML syntax there. They may or may not agree, but it's worth a shot. Commented Mar 26, 2016 at 21:22
  • 2
    I answered the same question here: stackoverflow.com/questions/38160260/… Commented Jul 2, 2016 at 17:00

3 Answers 3

12

As @Calvin commented above, I wouldn't say this is a good practice, yet I wouldn't necessarily say it's entirely bad one. Anyways, here's my naive solution (haven't tested it for any edge cases):

Install babel package for sublime text and choose it as the default syntax for your your *.js files.

Next, edit JavaScript (Babel).sublime-syntax, which is located inside the Babel package directory, e.g. ~/.config/sublime-text-3/Packages/Babel/.

Search for the section template-string-body:, and add at its beginning the following two lines, similar to @VRPF's suggestion:

- meta_content_scope: text.html.basic.embedded.js
- include: scope:text.html.basic

Now you have a full support in es6 + HTML syntax within template-strings.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked! If you want to achieve it with the default JavaScript syntax, you can use Package Resource Viewer -> Open Resource -> JavaScript -> JavaScript.sublime-syntax, and modify literal-string-template: Set meta_scope to text.html.basic.embedded.js and include to scope:text.html.basic.
5

I would just create a new syntax highlighter as you dont have to worry if they update the normal packages.

Go to Tools > Developer > New Syntax...

%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Javascript HTML
file_extensions:
  - element.js
  - tag.js
  - jsx
  - js
scope: source.js.tag
contexts:
  main:
    - match: ""
      push: Packages/JavaScript/JavaScript.sublime-syntax
      with_prototype:
      - match: '([a-zA-Z$_][\w$_]*)?(`)'
        push:
          - meta_content_scope: text.html.basic.embedded.js
          - include: 'scope:text.html.basic'
          - match: '`'
            pop: true
          - match: '\$\{'
            captures:
              0: punctuation.definition.template-expression.begin.js
            push:
              - meta_scope: meta.template.expression.js
              - include: 'scope:source.js'
              #- meta_content_scope: source.js.embedded.expression
              - match: '\}'
                scope: punctuation.definition.template-expression.end.js
                pop: true

Then save as JavascriptHTML.sublime-syntax

Restart Sublime then you can go to View > Syntax > Open all with this ext as > Javascript HTML

Comments

2

With a recent update in Sublime, the above no longer works due to "Apparent recursion within a with_prototype action: 25000 context sanity limit hit."

I have come up with an update that does the same thing - atleast from what I can tell which looks like this:

%YAML 1.2
---
name: JavaScript HTML
file_extensions:
  - js
scope: source.js
version: 2
extends: Packages/JavaScript/JavaScript.sublime-syntax
contexts:
  literal-string-template-begin:
    - match: '`'
      embed: scope:text.html.basic
      embed_scope: text.html.basic
      escape: '`'
      pop: true

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.