Advertisement

#6 Form Snippets Syntax Highlighting with Prismjs

In this article we will set up syntax highlighting for our code snippets.

Prismjs

  • WebUi
    • Source
      • forms
        • syntax-highlighter.service.ts
    • package.json

One thing that would make our interface look better is some syntax highlighting for our code examples. To add the highlighting we will use prismjs. Our first course of action is to install prism to our project by using the install command (a) or by updating your package.json and installing from there (b).

npm install (1)

npm install --save-dev prismjs
(a) Npm command to install primsjs to our project.

package.json (1)

{
  ...
  "devDependencies": {
    ...
    "prismjs": "^1.14.0",
    ...
  }
}
(b) As of the time of the writing of this article the version number of prismjs was 1.14.0.

Syntax highlighting service

  • WebUi
    • Source
      • forms
        • examples
          • form-examples.module.ts
        • forms.index.ts
        • syntax-highlighting.service.ts

Now that prism is installed we will create a service that we can inject into our components that will perform the highlighting (c). The code that we are using for this service can be found at auralinna.blog. As we are probably used to by now the next thing we will do is to export this service from our index file (d). In order to use the service within our components we will have angular inject. For the injection to work we need to update our module definition to include the service within the providers array (e).

syntax-highlighting.service.ts (1)

/// https://auralinna.blog/post/2017/code-syntax-highlighting-with-angular-and-prismjs

import { Injectable, Inject } from "@angular/core";

import { PLATFORM_ID } from "@angular/core";
import { isPlatformBrowser } from "@angular/common";

import "prismjs";
import "prismjs/components/prism-pug.js";
import "prismjs/components/prism-scss";
import "prismjs/components/prism-typescript";

import "prismjs/plugins/toolbar/prism-toolbar";
import "prismjs/plugins/show-language/prism-show-language";

declare var Prism: any;

@Injectable()
export class SyntaxHighlightingService {
    constructor( @Inject(PLATFORM_ID) private readonly platformId: Object) { }

    public highlightAll() {
        if (isPlatformBrowser(this.platformId)) {
            Prism.highlightAll();
        }
    }
}
(c) Service that we will inject into our components that will perform the syntax highlighting.

forms.index.ts (1)

...
export * from "./syntax-highlighting.service";
...
(d) Exporting our highlighting service from the index file.

form-examples.module.ts (1)

...
import {
    SyntaxHighlightingService
} from "./form-examples.index";
...
@NgModule({
    ...
    providers: [
        SyntaxHighlightingService
    ]
})
export class FormExamplesModule { }
...
(e) Registering the syntax highlighting service with our module.
Advertisement

Problems with the injector

  • WebUi
    • Source
      • forms
        • examples
          • basic
            • basic-example.component.ts

The next step is to add a dependency on our highlighting service inside the constructor call of our basic component (f). At some point a change was made to my setup, whether through an update or whatever, that has caused a problem with angular's dependency injection. If you are like me then you will be seeing an error at this point (g). If you do not see the error you can of course skip the solution or you can implement it as well to avoid any possible errors related to dependency injection in the future. Our problem seems to be related to the emitting of metadata when our components are transpiled from typescript to javascript. I have checked the tsconfig several times and it is set to emit metadata but that does not seem to be enough. So to fix this problem we are going to be explicit about the type of dependency that we need by using the inject decorator (h).

basic-example.component.ts (1)

...
import { ..., SyntaxHighlightingService, ... } from "../../forms.index";
...
export class BasicExampleComponent {
    ...
    constructor(private readonly _syntaxHighlighter: SyntaxHighlightingService) { }
    ...
}
(f) Using the inject decorator from angular core to solve our dependency injection error.

basic-example.component.ts (2)

...
import { ..., Inject, ... } from "@angular/core";
...
export class BasicExampleComponent {
    constructor(@Inject(SyntaxHighlightingService) private readonly _syntaxHighlighter: SyntaxHighlightingService) { }
}
(h) By using the inject decorator we can be explicit about the type of dependency that we need injected.
Imaging showing that we are receiving a dependency injection error.
(g) Imaging showing that we are receiving a dependency injection error.

Let's see that syntax highlighting

  • WebUi
    • Source
      • forms
        • examples
          • basic
            • basic-example.component.ts
      • main.site.scss

Now that we have an instance of the highlighting service we can use it to highlight our code. To do this we are going to implement the AfterViewInit interface and use our syntax highlighting service's highlightAll method within the ngAfterViewInit method (i). The highlighting service will wrap our code samples in some html elements, typically spans, with various class. In order for us to see the correct styling we also need to import a couple of stylesheets into our project. We will do this in the main stylesheet so that they are available throughout our entire application (j).

basic-example.component.ts (3)

import { AfterViewInit, ...} from "@angular/core";
...
export class BasicExampleComponent implements AfterViewInit {
    ...
    public ngAfterViewInit(): void {
        this._syntaxHighlighter.highlightAll();
    }
    ...
}
(i) Calling the highlightAll method when angular calls the ngAfterViewInit lifecycle hook method.

main.site.scss

...
@import "../node_modules/prismjs/themes/prism.css";
@import "../node_modules/prismjs/plugins/toolbar/prism-toolbar.css";
(j) Import a couple of stylesheets into our main file so that they are available throughout our entire application.
Exciton Interactive LLC
Advertisement