2

I'm trying to build a syntax highlighting directive.

Basically a directive like so:

<div syntax-highlight="language">{{codeValue}}</div>

Should be turned into:

<div syntax-highlight="language">
    <pre><code>{{codeValue that has been syntax highlighted with span tags}}</code></pre>
</div>

So what I have is:

return {
    scope: {
        'syntaxHighlight': '@'
    },
    template: '<pre><code ng-transclude></code></pre>',
    transclude: true,
    link: function (scope, element, attributes, controller, transclude) {

    }
};

When this code currently runs, everything that is inside the {{codeValue}} which is basically a string gets put into <code ng-transclude></code> while being wrapped in a span element.

This is not good because I don't just want a string inside the code element. I need to modify this value prior to being transcluded.

I need to pass this {{codeValue}} into a syntax highlighting function which will return the syntax highlighted code which will be raw HTML (so a raw string (sanitized and escaped) gets turned into HTML with span tags). This raw HTML then needs to be put inside code element.

I've tried using the transclude function, but it seems like the content has already been transcluded.

1
  • I assume you are calling the syntax highlighting function within your link function? Can you not just append to your element therein? Commented Feb 26, 2014 at 14:17

2 Answers 2

3

This is what I ended up doing:

['$sce', function($sce){

    return {
        scope: {
            'syntaxLanguage': '@'
        }, 
        restrict: 'AE',
        template: codeBlockTemplate, 
        transclude: true, 
        replace: true, 
        link: function (scope, element, attributes, controller, transclude) {

            //transclude's clone is children elements of the directive element, it will wrap any unwrapped text nodes with the span tag
            transclude(scope, function (clone) {

                //get the directive element's content as text, this will be the {{code}}
                var code = angular.element(clone).text();

                //convert the code string into a highlighted code string
                var highlightedCode = hljs.highlight(scope.syntaxLanguage, code, true);

                //bind to the scope as trusted HTML
                scope.highlightedCode = $sce.trustAsHtml(highlightedCode.value);

            });

        }
    };

}]

With this as the template:

<pre><code ng-bind-html="highlightedCode"></code></pre>
Sign up to request clarification or add additional context in comments.

Comments

2

So basically you want to pass CodeValue to the directive and manipulate it in the link function?

what about:

<syntaxhighlight codevalue="codeValue"> </syntaxhighlight>

    return {
     restrict: 'E',
     scope: {'codevalue': '='},
     template: '<div> <pre><code ><span>{{sanitizedText}}</span></code></pre></div> ',
     replace: true,
     link: function (scope, element, attributes, controller) {

       scope.sanitizedText = textEditingFunction(scope.codevalue); //pass codevalue to the modifying function, who will return the sanitized text

    }
};

1 Comment

Whats the point of transclude: true? You end not using any transclusion tools. I did end up doing something very similar. Furthermore, it doesn't match my use case, as the code value would be inside the <syntaxHighlight> element.

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.