Skip to content

Commit

Permalink
Big release—adds support for Nunjucks highlighter, adds options to al…
Browse files Browse the repository at this point in the history
…low specifying using only some of the syntax highlighter pack (Fixes #2), adds `options.init` to make it possible to further customize Prism (Fixes #4)
  • Loading branch information
zachleat committed Sep 28, 2018
1 parent a523832 commit 9dbd54a
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 79 deletions.
37 changes: 27 additions & 10 deletions .eleventy.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
const liquidPlain = require("./src/liquidSyntaxHighlightPlain");
const liquidPrismJs = require("./src/liquidSyntaxHighlightPrism");
const Prism = require("prismjs");
const hasTemplateFormat = require("./src/hasTemplateFormat");
const HighlightPairedShortcode = require("./src/HighlightPairedShortcode");
const LiquidHighlightTag = require("./src/LiquidHighlightTag");
const markdownPrismJs = require("./src/markdownSyntaxHighlight");

module.exports = function(eleventyConfig, pluginNamespace) {
eleventyConfig.namespace(pluginNamespace, () => {
// compatibility with existing {% highlight js %} and others
eleventyConfig.addLiquidTag("highlight", liquidPrismJs);
eleventyConfig.addMarkdownHighlighter(markdownPrismJs);
module.exports = {
initArguments: { Prism },
configFunction: function(eleventyConfig, options = {}) {
// TODO hbs?
if( hasTemplateFormat(options.templateFormats, "liquid") ) {
eleventyConfig.addLiquidTag("highlight", (liquidEngine) => {
// {% highlight js 0 2 %}
let highlight = new LiquidHighlightTag(liquidEngine);
return highlight.getObject();
});
}

// Deprecated, use {% highlight text %} instead.
eleventyConfig.addLiquidTag("highlight-plain", liquidPlain);
});
if( hasTemplateFormat(options.templateFormats, "njk") ) {
eleventyConfig.addPairedNunjucksShortcode("highlight", (content, args) => {
// {% highlight "js 0 2-3" %}
let [language, ...highlightNumbers] = args.split(" ");
return HighlightPairedShortcode(content, language, highlightNumbers.join(" "));
});
}

if( hasTemplateFormat(options.templateFormats, "md") ) {
eleventyConfig.addMarkdownHighlighter(markdownPrismJs);
}
}
};
134 changes: 120 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,36 @@ You are responsible for including [your favorite PrismJS theme CSS](https://gith

Read more about [Eleventy plugins.](https://www.11ty.io/docs/plugins/)

### Options

Optionally pass in an options object as the second argument to `addPlugin` to further customize this plugin pack.

```
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(syntaxHighlight, {
// Change which syntax highlighters are installed
templateFormats: ["*"], // default
// Or, just njk and md syntax highlighters (do not install liquid)
// templateFormats: ["njk", "md"],
// init callback lets you customize Prism
init: function({ Prism }) {
Prism.languages.myCustomLanguage = /* */;
}
});
};
```

## Usage

### This plugin provides:

* Markdown Highlighter: syntax highlights using PrismJS
* Liquid Tag `{% highlight %}`: syntax highlights using PrismJS.
* Liquid Custom Tag `{% highlight %}`: syntax highlights using PrismJS.
* Nunjucks Paired Shortcode `{% highlight %}`: syntax highlights using PrismJS.

### Markdown Highlighter

Expand All @@ -37,6 +61,7 @@ Optionally specify a language after the start of the markdown fenced code block.
* [List of supported PrismJS languages](http://prismjs.com/#languages-list)

````
<!-- Markdown Template -->
``` js
function myFunction() {
return true;
Expand All @@ -45,8 +70,12 @@ function myFunction() {
````

````
// Line highlighting classes (single highlight)
// Adds `highlight-line-active` class to lines 1,3,4,5 (for line highlighting)
<!--
Line highlighting classes (single highlight)
Adds `highlight-line-active` class to lines 1,3,4,5 (for line highlighting)
-->
<!-- Markdown Template -->
``` js/1,3-5
function myFunction() {
// …
Expand All @@ -56,9 +85,13 @@ function myFunction() {
````

````
// Line highlighting classes (add and remove mode)
// Adds `highlight-line-add` class to lines 1,3
// Adds `highlight-line-remove` class to lines 5,6,7,8
<!--
Line highlighting classes (add and remove mode)
Adds `highlight-line-add` class to lines 1,3
Adds `highlight-line-remove` class to lines 5,6,7,8
-->
<!-- Markdown Template -->
``` js/1,3/5-8
function myFunction() {
// …
Expand All @@ -85,6 +118,7 @@ function myFunction() {
* [List of supported PrismJS languages](http://prismjs.com/#languages-list)

```
<!-- Liquid Template -->
{% highlight js %}
function myFunction() {
return true;
Expand All @@ -93,8 +127,12 @@ function myFunction() {
```

```
// Line highlighting classes (single highlight)
// Adds `highlight-line-active` class to lines 1,3,4,5 (for line highlighting)
<!--
Line highlighting classes (single highlight)
Adds `highlight-line-active` class to lines 1,3,4,5 (for line highlighting)
-->
<!-- Liquid Template -->
{% highlight js 1,3-5 %}
function myFunction() {
// …
Expand All @@ -104,9 +142,13 @@ function myFunction() {
```

```
// Line highlighting classes (add and remove)
// Adds `highlight-line-add` class to lines 1,3
// Adds `highlight-line-remove` class to lines 5,6,7,8
<!--
Line highlighting classes (add and remove)
Adds `highlight-line-add` class to lines 1,3
Adds `highlight-line-remove` class to lines 5,6,7,8
-->
<!-- Liquid Template -->
{% highlight js 1,3 5-8 %}
function myFunction() {
// …
Expand All @@ -120,6 +162,7 @@ function myFunction() {
Use `text` to use the line highlighting features without PrismJS.

```
<!-- Liquid Template -->
{% highlight text 1-2 %}
function myFunction() {
let highlighted = true;
Expand All @@ -128,16 +171,79 @@ function myFunction() {
{% endhighlight %}
```

### Sample Line Highlighting CSS
### Nunjucks Paired Shortcode: Prism Syntax Highlighter

* [List of supported PrismJS languages](http://prismjs.com/#languages-list)

```
<!-- Nunjucks Template -->
{% highlight "js" %}
function myFunction() {
return true;
}
{% endhighlight %}
```

```
<!--
Line highlighting classes (single highlight)
Adds `highlight-line-active` class to lines 1,3,4,5 (for line highlighting)
-->
<!-- Nunjucks Template -->
{% highlight "js 1,3-5" %}
function myFunction() {
// …
return true;
}
{% endhighlight %}
```

```
<!--
Line highlighting classes (add and remove)
Adds `highlight-line-add` class to lines 1,3
Adds `highlight-line-remove` class to lines 5,6,7,8
-->
<!-- Nunjucks Template -->
{% highlight "js 1,3 5-8" %}
function myFunction() {
// …
return true;
}
{% endhighlight %}
```

#### Plain text

Use `text` to use the line highlighting features without PrismJS.

```
<!-- Nunjucks Template -->
{% highlight "text 1-2" %}
function myFunction() {
let highlighted = true;
return highlighted;
}
{% endhighlight %}
```

### Sample Line Highlighting CSS

```css
.highlight-line {
display: block;
padding: 0.125em 1em;
text-decoration: none; /* override del, ins, mark defaults */
color: inherit; /* override del, ins, mark defaults */
}
.highlight-line:not(:empty) + br {

/* allow highlighting empty lines */
.highlight-line:empty:before {
content: " ";
}
/* avoid double line breaks when using display: block; */
.highlight-line + br {
display: none;
}

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"ava": "^0.25.0"
},
"dependencies": {
"@11ty/eleventy": "^0.3.5",
"prismjs": "^1.13.0"
"@11ty/eleventy": "^0.5.4",
"prismjs": "^1.15.0"
}
}
4 changes: 2 additions & 2 deletions src/HighlightLinesGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class HighlightLinesGroup {
this.init(str, delimiter);
}

init(str, delimiter) {
init(str = "", delimiter = " ") {
this.str = str;
this.delimiter = delimiter || " ";
this.delimiter = delimiter;

let split = str.split(this.delimiter);
this.highlights = new HighlightLines(split.length === 1 ? split[0] : "");
Expand Down
24 changes: 24 additions & 0 deletions src/HighlightPairedShortcode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const Prism = require("prismjs");
const PrismLoader = require("prismjs/components/index.js");
const HighlightLinesGroup = require("./HighlightLinesGroup");

module.exports = function(content, language, highlightNumbers) {
let highlightedContent;
if( language === "text" ) {
highlightedContent = content.trim();
} else {
if( !Prism.languages[ language ] ) {
PrismLoader([language]);
}

highlightedContent = Prism.highlight(content.trim(), Prism.languages[ language ]);
}

let group = new HighlightLinesGroup(highlightNumbers);

let lines = highlightedContent.split("\n").map(function(line, j) {
return group.getLineMarkup(j, line);
});

return `<pre class="language-${language}"><code class="language-${language}">` + lines.join("<br>") + "</code></pre>";
};
35 changes: 5 additions & 30 deletions src/LiquidHighlight.js → src/LiquidHighlightTag.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
const HighlightLinesGroup = require("./HighlightLinesGroup");
const HighlightPairedShortcode = require("./HighlightPairedShortcode");

class LiquidHighlight {
class LiquidHighlightTag {
constructor(liquidEngine) {
this.liquidEngine = liquidEngine;
this.hooks = [];
this.classHooks = [];
}

addHook(hookFunction) {
this.hooks.push(hookFunction);
}

addClassHook(hookFunction) {
this.classHooks.push(hookFunction);
}

getObject() {
Expand All @@ -22,7 +13,7 @@ class LiquidHighlight {
let split = tagToken.args.split(" ");

this.language = split.shift();
this.highlights = new HighlightLinesGroup(split.join(" "));
this.highlightLines = split.join(" ");

this.tokens = [];

Expand All @@ -46,23 +37,7 @@ class LiquidHighlight {
let tokens = this.tokens.map(token => token.raw);
let tokenStr = tokens.join("").trim();

for( let hook of highlighter.hooks ) {
tokenStr = hook.call(this, this.language, tokenStr);
}

let lines = tokenStr.split("\n").map(function(line, j) {
let classHookClasses = [];
for( let classHook of highlighter.classHooks ) {
let ret = classHook(this.language, line, j);
if( ret ) {
classHookClasses.push(ret);
}
}

return this.highlights.getLineMarkup(j, line, classHookClasses);
}.bind(this));

return Promise.resolve(`<pre class="language-${this.language}"><code class="language-${this.language}">` + lines.join("<br>") + "</code></pre>");
return Promise.resolve(HighlightPairedShortcode(tokenStr, this.language, this.highlightLines));
}
};
};
Expand All @@ -71,4 +46,4 @@ class LiquidHighlight {
}
}

module.exports = LiquidHighlight;
module.exports = LiquidHighlightTag;
13 changes: 13 additions & 0 deletions src/hasTemplateFormat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = function(templateFormats = ["*"], format = false) {
if(!Array.isArray(templateFormats)) {
templateFormats = [templateFormats];
}

if( Array.isArray(templateFormats) ) {
if( templateFormats.indexOf("*") > -1 || templateFormats.indexOf(format) > -1 ) {
return true;
}
}

return false;
};
21 changes: 0 additions & 21 deletions src/liquidSyntaxHighlightPrism.js

This file was deleted.

Loading

0 comments on commit 9dbd54a

Please sign in to comment.