user2062455
user2062455

Reputation: 421

angularjs regex filter syntax highlighter

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

Upvotes: 0

Views: 1360

Answers (1)

Mosho
Mosho

Reputation: 7078

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

Upvotes: 1

Related Questions