#6 Form Snippets Syntax Highlighting with Prismjs
Friday, July 13, 2018
In this article we will set up syntax highlighting for our code snippets.
Parts
- Part 14: Pipes to the Rescue
- Part 13: Rest of the Examples
- Part 12: Checkbox Example
- Part 11: Adding a Radio Button
- Part 10: Adding a Radio Group
- Part 9: Adding a Select
- Part 8: Adding a Checkbox
- Part 7: Adding a Textarea
- Part 6: Highlighting with Prismjs
- Part 5: Form Snippets Manager
- Part 4: Accessing Form Data
- Part 3: Angular Form Group Interop
- Part 2: The Form Group
- Part 1: Forms Project Creation
Prismjs
-
WebUi
-
Source
-
forms
- syntax-highlighter.service.ts
-
forms
- package.json
-
Source
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
package.json (1)
{
...
"devDependencies": {
...
"prismjs": "^1.14.0",
...
}
}
Syntax highlighting service
-
WebUi
-
Source
-
forms
-
examples
- form-examples.module.ts
- forms.index.ts
- syntax-highlighting.service.ts
-
examples
-
forms
-
Source
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();
}
}
}
forms.index.ts (1)
...
export * from "./syntax-highlighting.service";
...
form-examples.module.ts (1)
...
import {
SyntaxHighlightingService
} from "./form-examples.index";
...
@NgModule({
...
providers: [
SyntaxHighlightingService
]
})
export class FormExamplesModule { }
...
Problems with the injector
-
WebUi
-
Source
-
forms
-
examples
-
basic
- basic-example.component.ts
-
basic
-
examples
-
forms
-
Source
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) { }
...
}
basic-example.component.ts (2)
...
import { ..., Inject, ... } from "@angular/core";
...
export class BasicExampleComponent {
constructor(@Inject(SyntaxHighlightingService) private readonly _syntaxHighlighter: SyntaxHighlightingService) { }
}
Let's see that syntax highlighting
-
WebUi
-
Source
-
forms
-
examples
-
basic
- basic-example.component.ts
-
basic
-
examples
- main.site.scss
-
forms
-
Source
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();
}
...
}
main.site.scss
...
@import "../node_modules/prismjs/themes/prism.css";
@import "../node_modules/prismjs/plugins/toolbar/prism-toolbar.css";