Home Download Buy Blog Forum Support

Creating a syntax definition for an embedded language

Creating a syntax definition for an embedded language

Postby kirbysayshi on Tue Mar 20, 2012 10:14 pm

I'd like to write a syntax definition for a JS template compiler I wrote. It emulates Razor syntax, and is called Vash. It's available: https://github.com/kirbysayshi/vash

As an example, this is what a snippet of Vash (Razor code in JS) would look like:
Code: Select all
<table>
@model.blank_order_items.forEach(function(item){
   <tr>
      <td class="item-color">@item.color[0].long_value</td>
      <td class="item-size">@item.size[0].long_value</td>
      <td class="item-type">@item.type[0].long_value</td>
      <td class="item-quantity">
         @if( item.status !== 'consumed' ){
            <input name="item-quantity-@item.id" type="text" value="@item.quantity" maxlength="5" size="6" />   
         } else {
            @item.quantity
         }
      </td>
      <td class="item-price">$@item.unit_price</td>
      <td class="item-status">@(item.status === 'consumed' ? 'In Inventory' : 'Outstanding')</td>
   </tr>
})
</table>


As you can see, it's main trigger character is the @ symbol, and then is just a combination of HTML and JS.

I'd like to make a syntax definition for it to enable syntax highlighting, but have never done so for Sublime or Textmate. Typically JS templates are separate files, but often they are included inside of HTML source, contained within script tags, like so:

Code: Select all
<script type="text/tpl-vash">
   <input type="hidden" name="order-id" value="@model.id" />

   <div class="row-fluid">
      <div class="span4">
         <h3 class="order-id">ORDER #: @model.id</h3>
      </div>
   </div>
</script>


So the question is, how do you create a syntax file that can be active on a buffer, but only for a portion? I wouldn't want to have to make several syntax files, one for each language you could have this embedded in... for example: HTML (Vash), PHP (Vash), etc. Would this be handled by something like the 'include' directive as explained here: http://sublimetext.info/docs/en/extensibility/syntaxdefs.html?

Is this something that can be done, or will the user have to explicitely set their buffer syntax to HTML (Vash) etc?
kirbysayshi
 
Posts: 3
Joined: Tue Mar 20, 2012 10:04 pm

Re: Creating a syntax definition for an embedded language

Postby atomi on Wed Mar 21, 2012 9:37 pm

I think the easiest way to handle all cases would be to edit the default HTML.tmLanguage file by adding syntax definitions for Vash.

You could also create a new HTML (Vash).tmLanguage file based on the default HTML.tmLanguage file. In this case the user would only have to change the buffer's syntax once as Sublime will remember the selection.
atomi
 
Posts: 342
Joined: Thu Jan 20, 2011 5:06 pm
Location: Los Angeles CA US

Re: Creating a syntax definition for an embedded language

Postby facelessuser on Wed Mar 21, 2012 9:43 pm

Do it like the HTML language does. Create a separate syntax file with all of your Vash tmLanguage stuff in it, and simply use the <key>#include</key> key like is done for javascript and other languages. You will have to modify the HTML tmLanguage, but only to add an embedded code entry for Vash.
facelessuser
 
Posts: 1576
Joined: Tue Apr 05, 2011 7:38 pm

Re: Creating a syntax definition for an embedded language

Postby atomi on Thu Mar 22, 2012 4:22 am

You can also do what @facelessuser suggests but I think it's better to include the text.html.basic in your own definition so you won't have to edit the HTML.tmLanguage file which will get over-written when users update Sublime.
atomi
 
Posts: 342
Joined: Thu Jan 20, 2011 5:06 pm
Location: Los Angeles CA US

Re: Creating a syntax definition for an embedded language

Postby kirbysayshi on Thu Mar 22, 2012 5:37 pm

There's one other tricky bit, and that is that Vash is really just a combination of javascript + html with a few special characters to tell between the two. I was hoping to be able to use the JavaScript and HTML tmLanguages to handle that, so I wouldn't have to reimplement.

Ideally, I would want the user to not have to worry about switching buffer syntaxes, and thus Vash would be an include referenced from HTML.tmLanguage. But I assume that it's pretty difficult to get something like that added into the trunk code. I would still want snippets and everything else to function properly, which might not if the main buffer is set to Vash (a lot more things to handle?).

I'm really new at this, so my assumptions might be totally off. Maybe a better place to start is to just get syntax highlighting working for Vash, and then worry about where to put it.
kirbysayshi
 
Posts: 3
Joined: Tue Mar 20, 2012 10:04 pm

Re: Creating a syntax definition for an embedded language

Postby atomi on Thu Mar 22, 2012 5:51 pm

kirbysayshi wrote:There's one other tricky bit, and that is that Vash is really just a combination of javascript + html with a few special characters to tell between the two. I was hoping to be able to use the JavaScript and HTML tmLanguages to handle that, so I wouldn't have to reimplement.

Ideally, I would want the user to not have to worry about switching buffer syntaxes, and thus Vash would be an include referenced from HTML.tmLanguage. But I assume that it's pretty difficult to get something like that added into the trunk code. I would still want snippets and everything else to function properly, which might not if the main buffer is set to Vash (a lot more things to handle?).

I'm really new at this, so my assumptions might be totally off. Maybe a better place to start is to just get syntax highlighting working for Vash, and then worry about where to put it.


HTML and JS Completions use the current scope regardless if it's embedded. If you would rather users not have to switch grammar you will need to add the syntax to the HTML.tmLanguage file if VASH uses the html file extension. I'm not familiar with VASH enough but I would still suggest you create a new grammar file since once you change the syntax for the current file Sublime will remember the setting. So it would only have to be changed once and this prevents you from having to change the default HTML.tmLanguage file that could get over-written during an update.

Something like this HTML (Vash).tmLanguage

Code: Select all
header stuff filetype html etc...
...

<key>begin</key>
<string>(vash regex start js string)</string>
<key>end</key>
<string>(vash regex end js string)</string>
... use beginCaptures endCaptures for scoping here
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>source.js</string>
</dict>
<dict>
<key>include</key>
<string>text.html.basic</string>
</dict>
</array>
...
<key>include</key>
</string>text.html.basic</string>


I'm pretty sure if you play with the tmLanguage file a while you'll get it working just as you like. GL HTH
Last edited by atomi on Thu Mar 22, 2012 7:36 pm, edited 1 time in total.
atomi
 
Posts: 342
Joined: Thu Jan 20, 2011 5:06 pm
Location: Los Angeles CA US

Re: Creating a syntax definition for an embedded language

Postby kirbysayshi on Thu Mar 22, 2012 7:07 pm

Thanks, atomi!

I'll start playing...
kirbysayshi
 
Posts: 3
Joined: Tue Mar 20, 2012 10:04 pm


Return to Plugin Development

Who is online

Users browsing this forum: No registered users and 6 guests