0

please take a look at this plunker: http://plnkr.co/edit/OIFu07GS0ZJQOdmpDnXB?p=preview

i am trying to create a syntax highlighter with angular. I have the filter working 80%. The regex is correct but the .replace() it "writes" the html as text on the pre and not rendering it as html.

take a look and you will understand what I am trying to do.

I know there are codemirror and ace directives but they are just too big for what I need.

anyone know how to fix it?

the correct output should be something like this:

<pre>
    <span class="string">1</span>
    <span class="string">2</span>
    <span class="string">3</span> 
    #This is a mysql syntax highlighter
    -- This is a comment/*
    And this is a multi line comment
    SELECT things FROM table;*/
</pre>

currently everything between pre is rendered as text.

any ideas? thanx

1 Answer 1

1

I don't think you can do this with a filter, try a directive.

Below is an example, fairly straightforward. I first changed the filter to a service (though you can use the filter similarly with $filter if you want but I don't see why). Then I use $interpolate to create an interpolation function, described here:

Compiles a string with markup into an interpolation function. This service is used by the HTML $compile service for data binding. See $interpolateProvider for configuring the interpolation markup.

You can see in the example that the strings '1', '2' and '3' are highlighted because I added style="color:red", and they have the class as well.

Edit: edited solution with usage of ngModelController to make changes to the textarea appear in the element below with angular's data binding. Note the change to the snippet element: <snippet ng-model="txt">


var app = angular.module('plunker', ['syntax']);

app.controller('MainCtrl', function($scope) {
  $scope.txt = "1 2 3 \n #This is a mysql syntax highlighter\n-- This is a comment/*\nAnd this is a multi line comment\nSELECT things FROM table;*/\nSELECT \nag.name AS agent, `d.date`, d.first_payment_date, d.account_number, ";
});


angular.module('syntax', [])
  .service('formatter', function () {
    return function (input) {
      if (input) {
        return input.replace(/(\d+)/g, "<span class=\"string\" style=\"color:red\">$1</span>");
      }
    }
})

.directive('snippet', function($timeout, $interpolate, formatter) {
    return {
        restrict: 'E',
        template:'<pre><code></code></pre>',
        replace:true,
        require: '?ngModel',
        link:function(scope, elm, attrs, ngModel){ 
          ngModel.$render = function(){
            var tmp =  $interpolate(scope.txt)(scope);
            elm.find('code').html(formatter(tmp)); 
          }
        }
    };
}); 

http://plnkr.co/edit/783ML4Y2qH8oMLarf0kg?p=preview

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

4 Comments

thank you very much. that worked. is there any way to make it editable, so whatever I type either in the textarea or the snippet, the snippet uses the classes to highlight the text? I tried the ng-model but it didn't work. thanx again
Edited with a solution that implements this.
i am trying to use this inside a ng-repeat but it doesn't work. anyone know how it can work with an ng-repeat? here is an updated plunker with the ng-repeat. plnkr.co/edit/PRndhLnsx29abPhIIB8c?p=preview
Here is an AngularJS directive that does this: ngmodules.org/modules/angular-highlightjs it uses: highlightjs.org/static/test.html

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.