Reputation: 421
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
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