An Angular2 codeblock highlighting component using Prismjs.
$ jspm i npm:ng2-prism
$ npm i ng2-prism --save
No additional setup necessary.
Systemjs needs to know the path to ng2-prism
and prismjs
, along with the typical angular dependencies (including http). Use map
, and make sure defaultJSExtensions
is set to true
. Here is an example config, for use with the angular2 quickstart:
<script>
System.config({
defaultJSExtensions: true,
packages: {
app: {
format: 'register'
}
},
map: {
"angular2": "node_modules/angular2",
"rxjs": "node_modules/rxjs",
"ng2-prism": "node_modules/ng2-prism",
"prismjs": "node_modules/prismjs"
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
Import the component:
import {Codeblock} from 'ng2-prism/codeblock';
Import the language definition for your codeblock:
import {Ruby} from 'ng2-prism/languages';
Include the component and language directive in the directives array:
@Component({
selector: 'my-component',
// ...
directives: [Codeblock, Ruby]
})
Add a codeblock
to the template with the language directive attached:
<codeblock ruby>
def my_new_method
p "So Impressive!"
end
</codeblock>
Use angular bindings like normal for variable output.
<input type="text" [(ngModel)]="name">
// {{name}} will be replaced by whatever is typed in the input
<codeblock javascript>
if (name === '{{name}}') {
console.log("Hello, " + name);
}
</codeblock>
If you want to display the binding without processing place a pre
tag around any of the braces.
<input type="text" [(ngModel)]="name">
// {{name}} will not be replaced
<codeblock javascript>
<pre>{</pre>{name}}
</codeblock>
Use the src
directive to set a file to download as the source code for a codeblock
. The language of the codeblock
will be determined from the file extension, unless a language is specified.
First, import the Source
directive:
import {Codeblock, Source} from 'ng2-prism/codeblock';
Then add it to the list of directives:
@Component({
selector: 'my-component',
// ...
directives: [Codeblock, Source]
})
Then use the src
attribute on the codeblock in your template:
<!-- automatically loads as javascript -->
<codeblock src="path/to/main.js"></codeblock>
<!-- tries to highlight the downloaded file as typescript -->
<codeblock typescript src="path/to/main.js"></codeblock>
Notes on Dynamic loading:
- The
codeblock
will automatically update on changes tosrc
. - Updates to src are throttled at 300ms to prevent unnecessary http requests, you can change the time by setting
debounceTime
on the codeblock, or by providingSourceDebounceTime
- more details here - The
src
attribute must have a file extension. - Everything inside the dynamic codeblock will be replaced by the contents of the source file.
- The source contents are treated as text only, not DOM elements. Components, directives, and bindings will not be processed by angular2.
- The source directive relies on the angular2
Http
module. Make sure you have included theHTTP_PROVIDERS
when bootstrapping your app.
Add a theme
attribute to the codeblock
element:
<codeblock javascript theme="dark">
// dark themed
</codeblock>
<codeblock javascript [theme]="selectedTheme">
// uses whichever theme is currently stored in the selectedTheme variable
</codeblock>
Your theme options are:
- standard
- coy
- dark
- funky
- okaidia
- solarizedlight
- tomorrow
- twilight
The list of themes is available at runtime with CodeblockComponent.THEMES
.
To embed HTML
use the language markup.
If you use standard HTML
tags, and carefully close each one, you can write it as normal inside a codeblock
:
<codeblock markup>
<ul class="favorites">
<li>These are</li>
<li>a few of</li>
<li>my favorite</li>
<li>things.</li>
</ul>
</codeblock>
If you want to write a fragment of `HTML` with some unmatched tags the angular interpreter is going to fail to load your template. You must change any opening or closing tag angle brackets, <, to the html entity version:
`< => <`
```html
<codeblock markup>
<html>
<head>
<title>Angular 2 QuickStart</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 1. Load libraries -->
<!-- IE required polyfills, in this exact order -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
...
</codeblock>
Dynamically loaded files do not have this limitation.
Angular2 Components
, such as a codeblock
or an ngIf
, will be processed by angular before highlighting. If you want to show their preprocessed version in the highlighted section instead of their results they should be escaped:
<!-- Will display 'A' only -->
<codeblock markup>
<section *ngIf="true" >A</section>
<section *ngIf="false">B</section>
</codeblock>
<!-- Will display both section elements -->
<codeblock markup>
<section *ngIf="true" >A</section>
<section *ngIf="false">B</section>
</codeblock>
If you want to show bindings without processing use the bind
method on a local variable assigned to the codeblock
:
<codeblock markup #cb>
{{ cb.bind('expression') }}
</codeblock>
// result
{{expression}}
You may optionally specify a language
attribute instead of using a directive:
<codeblock language="ruby">
def my_new_method
p "So Impressive!"
end
</codeblock>
The attribute makes the language easy to change dynamically:
<codeblock [language]="modern ? 'typescript' : 'javascript'">
import {Component} from 'angular2/core';
</codeblock>
Codeblocks without a valid loaded language
attribute or directive get everything except syntax highlighting:
<codeblock>
Just normal text
but themed
with line numbers
</codeblock>
<codeblock language="spanish">
Eso no es un lenguaje de verdad!
</codeblock>
If you choose to use the language
attribute the language must still be imported, but you do not have to list it in the directives array because the template does not need to know about it.
All languages are automatically loaded when any language is imported from ng2-prism/languages. To import only the language(s) you want:
// if you want the directive:
import {Ruby} from 'ng2-prism/languages/ruby';
// If you just want the language:
import 'ng2-prism/languages/ruby';
Ng2-prism automatically adds line numbers to codeblocks. To disable them bind a lineNumbers
attribute to false
:
<codeblock [lineNumbers]="false"></codeblock>
or
<codeblock [lineNumbers]="someBooleanExpression"></codeblock>
Use the shell
attribute to display a shell prompt. Pass in the type of shell, either bash
or powershell
.
<codeblock shell="bash">
ls
</codeblock>
<codeblock shell="powershell">
dir
</codeblock>
The language
attribute is ignored on shell
codeblocks
.
The default theme
for shells is okaidia
.
Change the prompt
to whatever you want:
<codeblock shell="bash" prompt="#">cd ..</codeblock>
# cd ..
<codeblock shell="bash" prompt="[user@host] $">cd ..</codeblock>
[user@host] $ cd ..
Shells can have certain lines treated as console output, so they don't have a prompt. Use the outputLines
attribute. It accepts a comma-separated list of lines or line ranges:
<codeblock shell="bash" outputLines="2,4,5,7-10">
cd ../..
This is output
mkdir hello
so is
this
rm -rf hello
more output
more output
more output
more output
</codeblock>
$ cd ../..
This is output
$ mkdir hello
so is
this
$ rm -rf hello
more output
more output
more output
more output