ng-prism
Version:
An Angular2 codeblock highlighting component using Prismjs.
351 lines (264 loc) • 8.41 kB
Markdown
# ng2-prism
An Angular2 codeblock highlighting component using Prismjs.
## Installation
### jspm
```
$ jspm i npm:ng2-prism
```
### npm
```
$ npm i ng2-prism --save
```
## Setup
### jspm and systemjs
No additional setup necessary.
### systemjs only (installed with npm)
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:
```html
<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>
```
## Usage
Import the component:
```ts
import {Codeblock} from 'ng2-prism/codeblock';
```
Import the language definition for your codeblock:
```ts
import {Ruby} from 'ng2-prism/languages';
```
Include the component and language directive in the directives array:
```ts
@Component({
selector: 'my-component',
// ...
directives: [Codeblock, Ruby]
})
```
Add a `codeblock` to the template with the language directive attached:
```html
<codeblock ruby>
def my_new_method
p "So Impressive!"
end
</codeblock>
```
### Angular2 Bindings
Use angular bindings like normal for variable output.
```html
<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.
```html
<input type="text" [(ngModel)]="name">
// {{name}} will not be replaced
<codeblock javascript>
<pre>{</pre>{name}}
</codeblock>
```
### Dynamic Loading
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:
```ts
import {Codeblock, Source} from 'ng2-prism/codeblock';
```
Then add it to the list of directives:
```ts
@Component({
selector: 'my-component',
// ...
directives: [Codeblock, Source]
})
```
Then use the `src` attribute on the codeblock in your template:
```html
<!-- 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 to `src`.
* 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 providing `SourceDebounceTime` - [more details here](https://github.com/tpadjen/ng2-src-directive#debounce-time)
* 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 the `HTTP_PROVIDERS` when bootstrapping your app.
### Themes
Add a `theme` attribute to the `codeblock` element:
```html
<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`.
### HTML
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`:
```html
<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:
```html
<!-- 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`:
```html
<codeblock markup #cb>
{{ cb.bind('expression') }}
</codeblock>
// result
{{expression}}
```
### Language
You may optionally specify a `language` attribute instead of using a directive:
```html
<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:
```html
<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:
```js
// if you want the directive:
import {Ruby} from 'ng2-prism/languages/ruby';
// If you just want the language:
import 'ng2-prism/languages/ruby';
```
### Line Numbers
Ng2-prism automatically adds line numbers to codeblocks. To disable them bind a `lineNumbers` attribute to `false`:
```html
<codeblock [lineNumbers]="false"></codeblock>
or
<codeblock [lineNumbers]="someBooleanExpression"></codeblock>
```
### Shell
Use the `shell` attribute to display a shell prompt. Pass in the type of shell, either `bash` or `powershell`.
```html
<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`.
#### Prompt
Change the `prompt` to whatever you want:
```html
<codeblock shell="bash" prompt="#">cd ..</codeblock>
# cd ..
<codeblock shell="bash" prompt="[user@host] $">cd ..</codeblock>
[user@host] $ cd ..
```
#### Output
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:
```html
<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
```