Search code examples
javascripttextmatetaglibsublimetext

How do I add another tag to be parsed as embedded JS in a tmLanguage file?


Back Story (not really important but it frames the question)

I have a TagLib in a JSP that takes its contents and wraps its containing code in a script block (it does much more but for the sake of the question it is not important). For example:

<aui:script use="some-module">
    //my code
</aui:script>

will be served as

<script type="text/javascript>
    AUI().use('sub-module', function(A) {
        // my code
    }
</script>

The Question

I would like all the code in between <aui:script use="things"></aui:script> and to have JavaScript syntax highlighting. So I tried editing the HTML.tmLanguage file to include this but Sublime Text 2 throws a fit.

Admittedly my regex knowledge is poor.

How can I edit HTML.tmLanguage to include my <aui:script /> taglib?

Site note, the taglib accepts various attributes like use and position.


Solution

  • I have so much trouble with the regex rules but I managed to get it somewhat working using the normal rules. I should add that this is a new block, along with the regular one.

    {
        name = 'source.js.embedded.html';
        begin = '(?:^\s+)?(<)((?i:(aui[\:]script)))\b(?![^>]*/>)';
        end = '(?<=</(aui[\:]script))(>)(?:\s*\n)?';
        beginCaptures = {
            1 = { name = 'punctuation.definition.tag.html'; };
            2 = { name = 'entity.name.tag.script.html'; };
        };
        endCaptures = {
            2 = {
                name = 'punctuation.definition.tag.html';
            };
        };
        patterns = (
            {
                include = '#tag-stuff';
            },
            {
                begin = '(?<!</(?:aui[\:]script))(>)';
                end = '(</)((?i:aui[\:]script))';
                captures = {
                    1 = {
                        name = 'punctuation.definition.tag.html';
                    };
                    2 = {
                        name = 'entity.name.tag.script.html';
                    };
                };
                patterns = (
                    {   name = 'comment.line.double-slash.js';
                        match = '(//).*?((?=</(aui[\:]script))|$\n?)';
                        captures = {
                            1 = {
                                name = 'punctuation.definition.comment.js';
                            };
                        };
                    },
                    {
                        name = 'comment.block.js';
                        begin = '/\*';
                        end = '\*/|(?=</(aui[\:]script))';
                        captures = {
                            0 = {
                                name = 'punctuation.definition.comment.js';
                            };
                        };
                    },
                    {
                        include = '#php';
                    },
                    {
                        include = 'source.js';
                    },
                );
            },
        );
    }
    

    XML Format

    <dict>
        <key>begin</key>
        <string>(?:^\s+)?(&lt;)((?i:(aui[\:]script)))\b(?![^&gt;]*/&gt;)</string>
        <key>beginCaptures</key>
        <dict>
            <key>1</key>
            <dict>
                <key>name</key>
                <string>punctuation.definition.tag.html</string>
            </dict>
            <key>2</key>
            <dict>
                <key>name</key>
                <string>entity.name.tag.script.html</string>
            </dict>
        </dict>
        <key>end</key>
        <string>(?&lt;=&lt;/(aui[\:]script))(&gt;)(?:\s*\n)?</string>
        <key>endCaptures</key>
        <dict>
            <key>2</key>
            <dict>
                <key>name</key>
                <string>punctuation.definition.tag.html</string>
            </dict>
        </dict>
        <key>name</key>
        <string>source.js.embedded.html</string>
        <key>patterns</key>
        <array>
            <dict>
                <key>include</key>
                <string>#tag-stuff</string>
            </dict>
            <dict>
                <key>begin</key>
                <string>(?&lt;!&lt;/(?:aui[\:]script))(&gt;)</string>
                <key>captures</key>
                <dict>
                    <key>1</key>
                    <dict>
                        <key>name</key>
                        <string>punctuation.definition.tag.html</string>
                    </dict>
                    <key>2</key>
                    <dict>
                        <key>name</key>
                        <string>entity.name.tag.script.html</string>
                    </dict>
                </dict>
                <key>end</key>
                <string>(&lt;/)((?i:aui[\:]script))</string>
                <key>patterns</key>
                <array>
                    <dict>
                        <key>captures</key>
                        <dict>
                            <key>1</key>
                            <dict>
                                <key>name</key>
                                <string>punctuation.definition.comment.js</string>
                            </dict>
                        </dict>
                        <key>match</key>
                        <string>(//).*?((?=&lt;/(aui[\:]script))|$\n?)</string>
                        <key>name</key>
                        <string>comment.line.double-slash.js</string>
                    </dict>
                    <dict>
                        <key>begin</key>
                        <string>/\*</string>
                        <key>captures</key>
                        <dict>
                            <key>0</key>
                            <dict>
                                <key>name</key>
                                <string>punctuation.definition.comment.js</string>
                            </dict>
                        </dict>
                        <key>end</key>
                        <string>\*/|(?=&lt;/(aui[\:]script))</string>
                        <key>name</key>
                        <string>comment.block.js</string>
                    </dict>
                    <dict>
                        <key>include</key>
                        <string>#php</string>
                    </dict>
                    <dict>
                        <key>include</key>
                        <string>source.js</string>
                    </dict>
                </array>
            </dict>
        </array>
    </dict>