angularsyntax-highlightinghighlight.js

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/


Solution

  • 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 ]
    })
    (...)