Skip to content

Commit 98efdbd

Browse files
committed
Clean up compile-markdown utility
1 parent 6b9ac66 commit 98efdbd

File tree

1 file changed

+45
-24
lines changed

1 file changed

+45
-24
lines changed

lib/utils/compile-markdown.js

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
const marked = require('marked');
44
const highlightjs = require('highlightjs');
55

6-
module.exports = function compileMarkdown(source, options) {
7-
let tokens;
8-
let config = { highlight };
6+
module.exports = function compileMarkdown(source, config) {
7+
let tokens = marked.lexer(source);
8+
let markedOptions = {
9+
highlight,
10+
renderer: new HBSRenderer(config)
11+
};
912

10-
if (options && options.targetHandlebars) {
11-
config.renderer = new HBSRenderer();
12-
tokens = compactParagraphs(source);
13-
} else {
14-
tokens = marked.lexer(source);
13+
if (config && config.targetHandlebars) {
14+
tokens = compactParagraphs(tokens);
1515
}
1616

17-
return `<div class="docs-md">${marked.parser(tokens, config).trim()}</div>`;
17+
return `<div class="docs-md">${marked.parser(tokens, markedOptions).trim()}</div>`;
1818
};
1919

2020
function highlight(code, lang) {
@@ -25,25 +25,29 @@ function highlight(code, lang) {
2525
}
2626
}
2727

28-
function compactParagraphs(source) {
29-
let tokens = marked.lexer(source);
28+
// Whitespace can imply paragraphs in Markdown, which can result
29+
// in interleaving between <p> tags and block component invocations,
30+
// so this scans the Marked tokens to turn things like this:
31+
// <p>{{#my-component}}<p>
32+
// <p>{{/my-component}}</p>
33+
// Into this:
34+
// <p>{{#my-component}} {{/my-component}}</p>
35+
function compactParagraphs(tokens) {
3036
let compacted = [];
3137

3238
compacted.links = tokens.links;
3339

34-
let diff = 0;
40+
let balance = 0;
3541
for (let token of tokens) {
36-
let wasBalanced = diff === 0;
37-
38-
diff += count(/\{\{#/g, token.text);
39-
diff -= count(/\{\{\//g, token.text);
40-
41-
if (wasBalanced) {
42+
if (balance === 0) {
4243
compacted.push(token);
4344
} else {
4445
let last = compacted[compacted.length - 1];
4546
last.text = `${last.text} ${token.text}`;
4647
}
48+
49+
balance += count(/\{\{#/g, token.text);
50+
balance -= count(/\{\{\//g, token.text);
4751
}
4852

4953
return compacted;
@@ -56,21 +60,38 @@ function count(regex, string) {
5660
}
5761

5862
class HBSRenderer extends marked.Renderer {
59-
// Escape curlies in code spans/blocks to avoid treating them as Handlebars
63+
constructor(config) {
64+
super();
65+
this.config = config || {};
66+
}
67+
6068
codespan() {
61-
return this._escapeCurlies(super.codespan.apply(this, arguments));
69+
return this._processCode(super.codespan.apply(this, arguments));
6270
}
6371

6472
code() {
65-
let code = this._escapeCurlies(super.code.apply(this, arguments));
73+
let code = this._processCode(super.code.apply(this, arguments));
6674
return code.replace(/^<pre>/, '<pre class="docs-md__code">');
6775
}
6876

6977
// Unescape quotes in text, as they may be part of a Handlebars statement
7078
text() {
71-
return super.text.apply(this, arguments)
72-
.replace(/&quot;|&#34;/g, `"`)
73-
.replace(/&apos;|&#39;/g, `'`);
79+
let text = super.text.apply(this, arguments);
80+
if (this.config.targetHandlebars) {
81+
text = text
82+
.replace(/&quot;|&#34;/g, `"`)
83+
.replace(/&apos;|&#39;/g, `'`);
84+
}
85+
return text;
86+
}
87+
88+
// Escape curlies in code spans/blocks to avoid treating them as Handlebars
89+
_processCode(string) {
90+
if (this.config.targetHandlebars) {
91+
string = this._escapeCurlies(string);
92+
}
93+
94+
return string;
7495
}
7596

7697
_escapeCurlies(string) {

0 commit comments

Comments
 (0)