Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

highlight.js does not work with Angular 2

I am trying to add syntax highlighting to my application using highlight.js but it doesn't seem to work with Angular 2.

Could you please let me know what I might be doing incorrectly?

Here is the Plnkr: https://plnkr.co/edit/G3NFFPGXKyc9mV1a6ufJ?p=preview

This is the component:

import {Component} from 'angular2/core';
@Component({
selector: "my-app",
template: `
Hello!
<pre>
            <code class="html">
              &lt;html&gt;
                &lt;body&gt;

                &lt;h1&gt;My First Heading&lt;/h1&gt;
                &lt;p&gt;My first paragraph.&lt;/p&gt;

                &lt;/body&gt;
              &lt;/html&gt;
            </code>
          </pre>
`
})
export class AppComponent{
}

This is where I am adding highlight.js using cdn:

<!DOCTYPE html>
<html>
   <head>
      <!-- IE required polyfills, in this exact order -->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.25/system-polyfills.js"></script>
      <script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
      <!-- Angular polyfill required everywhere -->
      <script src="https://code.angularjs.org/2.0.0-beta.13/angular2-polyfills.js"></script>
      <script src="https://code.angularjs.org/tools/system.js"></script>
      <script src="https://code.angularjs.org/tools/typescript.js"></script>
      <script src="https://code.angularjs.org/2.0.0-beta.13/Rx.js"></script>
      <script src="https://code.angularjs.org/2.0.0-beta.13/angular2.dev.js"></script>
      <link rel="stylesheet" href="style.css" />
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/styles/solarized-light.min.css">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/highlight.min.js"></script>
      <script>hljs.initHighlightingOnLoad();</script>
      <script>
         System.config({
           transpiler: 'typescript', 
           typescriptOptions: { emitDecoratorMetadata: true }, 
           packages: {
             'api': {defaultExtension: 'ts'}, 
             'app': {defaultExtension: 'ts'} 
           } 
         });
         System.import('app/main')
             .then(null, console.error.bind(console));
      </script>
   </head>
   <body>
      <my-app>loading...</my-app>
   </body>
</html>

https://highlightjs.org/usage/

like image 993
takeradi Avatar asked May 18 '16 18:05

takeradi


4 Answers

I have published highlight.js module for angular, install it from npm

npm install --save ngx-highlightjs

It is very simple to use, it loads highlight.js automatically for you and works with lazy modules, check out the demo

like image 140
Murhaf Sousli Avatar answered Nov 04 '22 05:11

Murhaf Sousli


You need to explicitly apply highlightjs on a block this way:

import {Component, ElementRef, ViewChild} from 'angular2/core';

declare var hljs: any;

@Component({
  selector: "my-app",
  template: `
    Hello!
    <pre>
      <code #code class="html">
        &lt;html&gt;
          &lt;body&gt;

          &lt;h1&gt;My First Heading&lt;/h1&gt;
          &lt;p&gt;My first paragraph.&lt;/p&gt;

          &lt;/body&gt;
        &lt;/html&gt;
      </code>
    </pre>
  `
})
export class AppComponent{
  @ViewChild('code')
  codeElement: ElementRef;

  ngAfterViewInit() {
    hljs.highlightBlock(this.codeElement.nativeElement);
  }
}

See this plunkr

A good approach would be to create a custom directive for this:

@Directive({
  selector: 'code[highlight]'
})
export class HighlightCodeDirective {
  constructor(private eltRef:ElementRef) {
  }

  ngAfterViewInit() {
    hljs.highlightBlock(this.eltRef.nativeElement);
  }
}

and use it this way:

@Component({
  selector: "my-app",
  template: `
    Hello!
    <pre>
      <code highlight class="html">
        (...)
      </code>
    </pre>
  `,
  directives: [ HighlightCodeDirective ]
})
(...)
like image 24
Thierry Templier Avatar answered Nov 04 '22 04:11

Thierry Templier


I think that you have to fire highlight manually.

To do that you can delegate this function to special directive like:

@Directive({
  selector: 'pre'
})
class PreHighlight implements AfterViewInit {
  constructor(private elRef: ElementRef) {}

  ngAfterViewInit() {
    hljs.highlightBlock(this.elRef.nativeElement);
  }
} 

Plunker Example

like image 4
yurzui Avatar answered Nov 04 '22 06:11

yurzui


Angular 12+

Another way of doing this is custom usage of highlight.js

First, install the library

 npm install highlight.js

Add styles file to angular.json

"styles": [
   "./node_modules/highlight.js/styles/default.css" // I choose default but you can choose your favorite one.
],

In the component, you want to use highlighter import highlight.js

import hljs from 'highlight.js';

...

 constructor(@Inject(DOCUMENT) private document: Document) { }

 ngOnInit(): void {
    setTimeout(() => {
          this.document.querySelectorAll('pre code').forEach((el) => {
            hljs.highlightElement(el);
          });
        }, 500)
  }

Note: If you fetch data from an API please make sure your data is rendered on the page then run forEach()

like image 3
Ali Norouzi Avatar answered Nov 04 '22 04:11

Ali Norouzi