Skip to content

Commit

Permalink
fix: correct jekyll highlight tag implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bglw committed Oct 8, 2021
1 parent 605aa3f commit 020d8c2
Show file tree
Hide file tree
Showing 27 changed files with 195 additions and 23 deletions.
1 change: 1 addition & 0 deletions bookshop-packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"javascript-modules/gen": {},
"javascript-modules/generator-plugins/eleventy/cloudcannon-eleventy-bookshop": {},
"javascript-modules/generator-plugins/eleventy/eleventy-bookshop": {},
"javascript-modules/helpers": {},
"javascript-modules/live": {},
"javascript-modules/styles": {},
"javascript-modules/toml-narrator": {}
Expand Down
2 changes: 2 additions & 0 deletions javascript-modules/bookshop-sass/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/sass",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Standalone sass compiler for Bookshop",
"type": "module",
Expand All @@ -22,6 +23,7 @@
},
"dependencies": {
"@bookshop/builder": "2.0.6",
"@bookshop/helpers": "2.0.6",
"commander": "^8.1.0"
},
"engines": {
Expand Down
2 changes: 2 additions & 0 deletions javascript-modules/browser/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/browser",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Component browser for bookshop components",
"type": "module",
Expand All @@ -24,6 +25,7 @@
},
"dependencies": {
"@bookshop/builder": "2.0.6",
"@bookshop/helpers": "2.0.6",
"@codemirror/basic-setup": "^0.18.2",
"@codemirror/commands": "^0.18.3",
"@codemirror/legacy-modes": "^0.18.1",
Expand Down
2 changes: 2 additions & 0 deletions javascript-modules/builder/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/builder",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "esbuild wrapper for bringing bookshop components and engines throught to a frontend",
"type": "module",
Expand All @@ -18,6 +19,7 @@
"nyc": "^15.1.0"
},
"dependencies": {
"@bookshop/helpers": "2.0.6",
"@bookshop/styles": "2.0.6",
"esbuild": "^0.12.17",
"normalize-path": "^3.0.0"
Expand Down
1 change: 1 addition & 0 deletions javascript-modules/cloudcannon-structures/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/cloudcannon-structures",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Convert a Bookshop object into a CloudCannon structure",
"main": "main.js",
Expand Down
2 changes: 2 additions & 0 deletions javascript-modules/engines/eleventy-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/eleventy-engine",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Bookshop frontend Eleventy renderer",
"type": "module",
Expand All @@ -22,6 +23,7 @@
"nyc": "^15.1.0"
},
"dependencies": {
"@bookshop/helpers": "2.0.6",
"esbuild": "^0.11.23",
"liquidjs": "9.28.0",
"slugify": "^1.5.3"
Expand Down
6 changes: 4 additions & 2 deletions javascript-modules/engines/jekyll-engine/lib/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import translateLiquid from './translateLiquid.js';
/**
* LiquidJS plugins
*/
import {liquidHighlight} from '@bookshop/helpers';

import jsonify from './plugins/jsonify.js';
import slugify from './plugins/slugify-plugin.js';
import unbind from './plugins/unbind.js';
import loop_context from './plugins/loop_context.js';
import emulateJekyll from './plugins/emulate-jekyll.js';
import local from './plugins/local.js';
import highlight from './plugins/highlight.js';


export class Engine {
constructor(options) {
Expand All @@ -24,7 +26,7 @@ export class Engine {
this.name = options.name;
this.files = options.files;
this.plugins = options.plugins || [];
this.plugins.push(jsonify, slugify, unbind, emulateJekyll, local, highlight, loop_context);
this.plugins.push(jsonify, slugify, unbind, emulateJekyll, local, liquidHighlight, loop_context);

this.initializeLiquid();
this.applyLiquidPlugins();
Expand Down
21 changes: 0 additions & 21 deletions javascript-modules/engines/jekyll-engine/lib/plugins/highlight.js

This file was deleted.

7 changes: 7 additions & 0 deletions javascript-modules/engines/jekyll-engine/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const files = {
[component('include-title-deep-bind')]: "{% bookshop title bind=include.book %}",
[component('uses-helper')]: "{% bookshop_include helper help=include.label %}",
[shared('helper')]: "<span data-helper=\"{{include.help}}\"></span>",
[shared('highlight')]: "{% highlight %}<{% endhighlight %}",
}
const livePost = `<!--bookshop-live end-->`

Expand Down Expand Up @@ -72,3 +73,9 @@ test("should render bookshop_includes", async t => {
const livePre = `<!--bookshop-live name(helper) params(help: include.label)-->`
t.is(targetElementStub.innerHTML, `${livePre}<span data-helper=\"include-testing\"></span>${livePost}`);
});

test("should support highlight tag", async t => {
const targetElementStub = {};
await je.render(targetElementStub, "highlight");
t.regex(targetElementStub.innerHTML, /&lt;/);
});
2 changes: 2 additions & 0 deletions javascript-modules/engines/jekyll-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/jekyll-engine",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Bookshop frontend Jekyll renderer",
"type": "module",
Expand All @@ -22,6 +23,7 @@
"nyc": "^15.1.0"
},
"dependencies": {
"@bookshop/helpers": "2.0.6",
"esbuild": "^0.11.23",
"js-base64": "^3.6.1",
"liquidjs": "9.28.0",
Expand Down
2 changes: 2 additions & 0 deletions javascript-modules/engines/svelte-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/svelte-engine",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Bookshop frontend Svelte renderer",
"type": "module",
Expand All @@ -19,6 +20,7 @@
},
"devDependencies": {
"@bookshop/builder": "2.0.6",
"@bookshop/helpers": "2.0.6",
"ava": "^3.15.0",
"nyc": "^15.1.0"
},
Expand Down
1 change: 1 addition & 0 deletions javascript-modules/gen/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict = true
5 changes: 5 additions & 0 deletions javascript-modules/gen/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/gen",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "",
"main": "src/index.js",
Expand All @@ -20,7 +21,11 @@
"access": "public"
},
"dependencies": {
"@bookshop/helpers": "2.0.6",
"ejs": "^3.1.6",
"yargs": "^17.2.1"
},
"engines": {
"node": ">=14.16"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/cloudcannon-eleventy-bookshop",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Eleventy plugin for generating CloudCannon Array Structures from Bookshop components",
"main": "main.js",
Expand All @@ -17,6 +18,7 @@
},
"dependencies": {
"@bookshop/cloudcannon-structures": "2.0.6",
"@bookshop/helpers": "2.0.6",
"@bookshop/toml-narrator": "2.0.6",
"@ltd/j-toml": "^1.17.0",
"fast-glob": "^3.2.7",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/eleventy-bookshop",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Eleventy plugin for consuming Bookshop components",
"main": "main.js",
Expand All @@ -15,6 +16,9 @@
"ava": "^3.15.0",
"nyc": "^15.1.0"
},
"dependencies": {
"@bookshop/helpers": "2.0.6"
},
"engines": {
"node": ">=14.16"
}
Expand Down
1 change: 1 addition & 0 deletions javascript-modules/helpers/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict = true
1 change: 1 addition & 0 deletions javascript-modules/helpers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Bookshop helpers
46 changes: 46 additions & 0 deletions javascript-modules/helpers/lib/plugins/liquid/highlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Rough skeleton for the highlight tag in Jekyll.
* This won't perform any code highlighting, but should create the same outer DOM structure.
* This should also escape any HTML within.
*/

const escapeHtml = (input) => {
return input
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}

export const liquidHighlight = function (Liquid) {
this.registerTag('highlight', {
parse: function(token, remainingTokens) {
this.lang = token.args.split(' ')[0];
this.contents = [];

const stream = this.liquid.parser.parseStream(remainingTokens)
.on('tag:endhighlight', () => stream.stop())
.on('template', (tpl) => this.contents.push(tpl))
.on('end', () => {
throw new Error(`tag ${token.raw} not closed`)
});

stream.start();
},
render: function*(ctx, hash) {
const r = this.liquid.renderer;
const html = yield r.renderTemplates(this.contents, ctx);
const langAttrs = this.lang
? ` class="language-${this.lang}" data-lang="${this.lang}"`
: '';
return `<figure class="highlight">
<pre>
<code${langAttrs}>
${escapeHtml(html)}
</code>
</pre>
</figure>`;
}
});
}
56 changes: 56 additions & 0 deletions javascript-modules/helpers/lib/plugins/liquid/highlight.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import test from 'ava';
import { Liquid } from 'liquidjs';
import { liquidHighlight } from './highlight.js';

test("should escape HTML", async t => {
const liquid = new Liquid({});
liquid.plugin(liquidHighlight);

const result = await liquid.parseAndRender(`
{%- highlight -%}
<h1>Hello World</h1>
{%- endhighlight -%}
`);
t.notRegex(result, /<h1>Hello World<\/h1>/);
t.regex(result, /&lt;h1&gt;/);
});

test("should evaluate inner liquid", async t => {
const liquid = new Liquid({});
liquid.plugin(liquidHighlight);

const result = await liquid.parseAndRender(`
{%- highlight -%}
<h1>Hello {{ test }}</h1>
{%- endhighlight -%}
`, {test: "Bookshop"});
t.regex(result, /&lt;h1&gt;Hello Bookshop&lt;\/h1&gt;/);
});

test("should respect raw tags", async t => {
const liquid = new Liquid({});
liquid.plugin(liquidHighlight);

const result = await liquid.parseAndRender(`
{%- highlight -%}
{% raw %}<h1>Hello {{ test }}</h1>{% endraw %}
{%- endhighlight -%}
`, {test: "Bookshop"});
t.regex(result, /&lt;h1&gt;Hello {{ test }}&lt;\/h1&gt;/);
});

test("should handle no language", async t => {
const liquid = new Liquid({});
liquid.plugin(liquidHighlight);

const result = await liquid.parseAndRender(`{% highlight %}{% endhighlight %}`);
t.regex(result, /<code>/);
});

test("should handle language", async t => {
const liquid = new Liquid({});
liquid.plugin(liquidHighlight);

const result = await liquid.parseAndRender(`{% highlight ruby %}{% endhighlight %}`);
t.regex(result, /<code class="language-ruby" data-lang="ruby">/);
});
1 change: 1 addition & 0 deletions javascript-modules/helpers/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {liquidHighlight} from './lib/plugins/liquid/highlight.js';
24 changes: 24 additions & 0 deletions javascript-modules/helpers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@bookshop/helpers",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "",
"type": "module",
"main": "main.js",
"scripts": {
"test": "nyc ava -v"
},
"author": "CloudCannon",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"devDependencies": {
"ava": "^3.15.0",
"liquidjs": "9.28.0",
"nyc": "^15.1.0"
},
"engines": {
"node": ">=14.16"
}
}
1 change: 1 addition & 0 deletions javascript-modules/integration-tests/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "integration-tests",
"packageManager": "yarn@3.0.0",
"private": true,
"main": "index.js",
"scripts": {
Expand Down
2 changes: 2 additions & 0 deletions javascript-modules/live/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@bookshop/live",
"packageManager": "yarn@3.0.0",
"version": "2.0.6",
"description": "Live component renderer for editing from a CMS",
"type": "module",
Expand All @@ -22,6 +23,7 @@
},
"dependencies": {
"@bookshop/builder": "2.0.6",
"@bookshop/helpers": "2.0.6",
"commander": "^8.1.0"
},
"engines": {
Expand Down
Loading

0 comments on commit 020d8c2

Please sign in to comment.