Skip to content

Commit 0b1cd0a

Browse files
committedOct 3, 2020
Change to comply to CommonMark
* Change to comply to CommonMark — prefer the first when duplicate definitions are found * Replace `xtend` w/ `Object.assign` * Refactor old stuff in tests
1 parent 5fec432 commit 0b1cd0a

File tree

21 files changed

+141
-443
lines changed

21 files changed

+141
-443
lines changed
 

‎index.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use strict'
22

3-
var xtend = require('xtend')
43
var toHast = require('mdast-util-to-hast')
54
var toHtml = require('hast-util-to-html')
65
var sanitize = require('hast-util-sanitize')
@@ -17,7 +16,11 @@ function plugin(options) {
1716

1817
function compiler(node, file) {
1918
var root = node && node.type && node.type === 'root'
20-
var hast = toHast(node, {allowDangerousHtml: !clean, handlers: handlers})
19+
var hast = toHast(node, {
20+
allowDangerousHtml: !clean,
21+
handlers: handlers,
22+
commonmark: true
23+
})
2124
var result
2225

2326
if (file.extname) {
@@ -28,10 +31,13 @@ function plugin(options) {
2831
hast = sanitize(hast, schema)
2932
}
3033

31-
result = toHtml(hast, xtend(settings, {allowDangerousHtml: !clean}))
34+
result = toHtml(
35+
hast,
36+
Object.assign({}, settings, {allowDangerousHtml: !clean})
37+
)
3238

3339
// Add an eof eol.
34-
if (root && result.charAt(result.length - 1) !== '\n') {
40+
if (root && result && /[^\r\n]/.test(result.charAt(result.length - 1))) {
3541
result += '\n'
3642
}
3743

‎package.json

+8-4
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,23 @@
3636
"dependencies": {
3737
"hast-util-sanitize": "^3.0.0",
3838
"hast-util-to-html": "^7.0.0",
39-
"mdast-util-to-hast": "^9.0.0",
40-
"xtend": "^4.0.1"
39+
"mdast-util-to-hast": "^9.0.0"
4140
},
4241
"devDependencies": {
4342
"browserify": "^16.0.0",
4443
"commonmark.json": "^0.29.0",
4544
"dtslint": "^4.0.0",
4645
"is-hidden": "^1.0.0",
46+
"not": "^0.1.0",
4747
"nyc": "^15.0.0",
4848
"prettier": "^2.0.0",
49-
"remark": "^12.0.0",
49+
"rehype-parse": "^7.0.0",
50+
"rehype-stringify": "^8.0.0",
51+
"remark": "^13.0.0-alpha.0",
5052
"remark-cli": "^8.0.0",
5153
"remark-github": "^9.0.0",
5254
"remark-preset-wooorm": "^7.0.0",
55+
"remark-slug": "^6.0.0",
5356
"remark-toc": "^7.0.0",
5457
"tape": "^5.0.0",
5558
"tinyify": "^3.0.0",
@@ -86,7 +89,8 @@
8689
"esnext": false,
8790
"rules": {
8891
"unicorn/no-fn-reference-in-iterator": "off",
89-
"unicorn/prefer-includes": "off"
92+
"unicorn/prefer-includes": "off",
93+
"unicorn/prefer-optional-catch-binding": "off"
9094
},
9195
"ignores": [
9296
"remark-html.js"

‎readme.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
> It’s probably smarter to use `remark-rehype` directly and benefit from the
1717
> [**rehype**][rehype] ecosystem.
1818
19+
## Note!
20+
21+
This plugin is ready for the new parser in remark
22+
([`remarkjs/remark#536`](https://github.com/remarkjs/remark/pull/536)).
23+
The current and previous version of the plugin works with the current and
24+
previous version of remark.
25+
1926
## Install
2027

2128
[npm][]:
@@ -79,7 +86,7 @@ All options except for `sanitize` and `handlers` are passed to
7986
###### `options.handlers`
8087

8188
Object mapping [mdast][] [nodes][mdast-node] to functions handling them.
82-
This option is passed to [`mdast-util-to-html`][to-mdast-handlers].
89+
This option is passed to [`mdast-util-to-hast`][to-hast-handlers].
8390

8491
###### `options.sanitize`
8592

@@ -264,7 +271,7 @@ abide by its terms.
264271

265272
[to-html]: https://github.com/syntax-tree/hast-util-to-html
266273

267-
[to-mdast-handlers]: https://github.com/syntax-tree/mdast-util-to-hast#optionshandlers
274+
[to-hast-handlers]: https://github.com/syntax-tree/mdast-util-to-hast#optionshandlers
268275

269276
[sanitize]: https://github.com/syntax-tree/hast-util-sanitize
270277

‎test/fixtures/blockquote/output.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ <h1>Block Quote</h1>
1010
</li>
1111
<li>
1212
<p>Normal list</p>
13-
<p>Paragraph.</p>
1413
</li>
1514
</ul>
15+
<p>Paragraph.</p>
1616
</blockquote>

‎test/fixtures/code/output.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ <h1>Code</h1>
77
</code></pre>
88
<pre><code class="language-empty"></code></pre>
99
<pre><code class="language-tabs"> two spaces
10-
one
11-
two
12-
one
13-
mixed.
10+
one
11+
two
12+
one
13+
mixed.
1414
</code></pre>

‎test/fixtures/entities-named/output.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ <h1>Entities</h1>
99
<pre><code class="language-AT&amp;T">Something in the AT&amp;T language
1010
</code></pre>
1111
<p>Automatic links:</p>
12-
<p><a href="http://at&amp;t.com">http://at&amp;t.com</a>, <a href="http://at&amp;t.com">http://at&amp;t.com</a>, and <a href="http://at&amp;t.com">http://at&amp;t.com</a>.</p>
12+
<p><a href="http://at&amp;amp;t.com">http://at&amp;amp;t.com</a>, <a href="http://at&amp;#x26;t.com">http://at&amp;#x26;t.com</a>, and <a href="http://at&amp;t.com">http://at&amp;t.com</a>.</p>
1313
<p>Link <code>href</code>:</p>
1414
<p><a href="http://at&amp;t.com">With entity</a>, <a href="http://at&amp;t.com">numeric entity</a>, <a href="http://at&amp;t.com">without entity</a>.</p>
1515
<p>Link <code>title</code>:</p>

‎test/fixtures/entities-numerical/output.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ <h1>Entities</h1>
99
<pre><code class="language-AT&#x26;T">Something in the AT&#x26;T language
1010
</code></pre>
1111
<p>Automatic links:</p>
12-
<p><a href="http://at&#x26;t.com">http://at&#x26;t.com</a>, <a href="http://at&#x26;t.com">http://at&#x26;t.com</a>, and <a href="http://at&#x26;t.com">http://at&#x26;t.com</a>.</p>
12+
<p><a href="http://at&#x26;amp;t.com">http://at&#x26;amp;t.com</a>, <a href="http://at&#x26;#x26;t.com">http://at&#x26;#x26;t.com</a>, and <a href="http://at&#x26;t.com">http://at&#x26;t.com</a>.</p>
1313
<p>Link <code>href</code>:</p>
1414
<p><a href="http://at&#x26;t.com">With entity</a>, <a href="http://at&#x26;t.com">numeric entity</a>, <a href="http://at&#x26;t.com">without entity</a>.</p>
1515
<p>Link <code>title</code>:</p>

‎test/fixtures/escape/output.html

+15-15
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,21 @@
1919
<p>Pipe: |</p>
2020
<p>Tilde: ~</p>
2121
<p><strong>Commonmark:</strong></p>
22-
<p>Quote: \"</p>
23-
<p>Dollar: \$</p>
24-
<p>Percentage: \%</p>
25-
<p>Ampersand: \&#x26;</p>
26-
<p>Single quote: \'</p>
27-
<p>Comma: \,</p>
28-
<p>Forward slash: \/</p>
29-
<p>Colon: \:</p>
30-
<p>Semicolon: \;</p>
31-
<p>Less-than: \&#x3C;</p>
32-
<p>Equals: \=</p>
33-
<p>Question mark: \?</p>
34-
<p>At-sign: \@</p>
35-
<p>Caret: \^</p>
36-
<p>New line: \
22+
<p>Quote: "</p>
23+
<p>Dollar: $</p>
24+
<p>Percentage: %</p>
25+
<p>Ampersand: &#x26;</p>
26+
<p>Single quote: '</p>
27+
<p>Comma: ,</p>
28+
<p>Forward slash: /</p>
29+
<p>Colon: :</p>
30+
<p>Semicolon: ;</p>
31+
<p>Less-than: &#x3C;</p>
32+
<p>Equals: =</p>
33+
<p>Question mark: ?</p>
34+
<p>At-sign: @</p>
35+
<p>Caret: ^</p>
36+
<p>New line: <br>
3737
only works in paragraphs.</p>
3838
<p>Two spaces:<br>
3939
only works in paragraphs.</p>

‎test/fixtures/footnotes/config.json

-3
This file was deleted.

‎test/fixtures/footnotes/input.md

-83
This file was deleted.

‎test/fixtures/footnotes/output.html

-84
This file was deleted.

‎test/fixtures/images/output.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<p><img src="http://example.com/favicon.ico" alt="Example" title="Example Image"></p>
22
<p><img src="http://example.com/favicon.ico" alt="Example"></p>
3-
<p><img src="http://example.com/favicon.ico"></p>
4-
<p><img src="" title="Example Image"></p>
5-
<p><img src=""></p>
6-
<p><img src=""></p>
3+
<p><img src="http://example.com/favicon.ico" alt=""></p>
4+
<p><img src="" alt="" title="Example Image"></p>
5+
<p><img src="" alt=""></p>
6+
<p><img src="" alt=""></p>

‎test/fixtures/list/output.html

+12-22
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
11
<h1>List</h1>
22
<ul>
3-
<li>
4-
<p><strong>One</strong>;</p>
5-
</li>
6-
<li>
7-
<p><em>Two</em>;</p>
8-
</li>
9-
<li>
10-
<p><del>Three</del>.</p>
11-
</li>
12-
<li>
13-
<p>One;</p>
14-
</li>
15-
<li>
16-
<p>Two;</p>
17-
</li>
3+
<li><strong>One</strong>;</li>
4+
<li><em>Two</em>;</li>
5+
<li>~~Three~~.</li>
186
</ul>
7+
<ol>
8+
<li>One;</li>
9+
<li>Two;</li>
10+
</ol>
1911
<!-- -->
2012
<ol start="4">
21-
<li>
22-
<p>Four.</p>
23-
</li>
24-
<li>
25-
<p>Five.</p>
26-
</li>
13+
<li>Four.</li>
14+
<li>Five.</li>
15+
</ol>
16+
<ul>
2717
<li>
2818
<p>Loose:</p>
2919
<ul>
@@ -40,7 +30,7 @@ <h1>List</h1>
4030
<li>Foxtrot.</li>
4131
</ul>
4232
</li>
43-
</ol>
33+
</ul>
4434
<hr>
4535
<pre><code>And a rule.
4636
</code></pre>

‎test/fixtures/references/output.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<h1>References</h1>
22
<p>Entities contains some serious entity tests relating to titles and links
33
in definitions.</p>
4-
<p>However, the [missing], <a href="">missing</a>, and <a href="">missing</a> are omitted.</p>
5-
<p>However, the ![missing], <img src="" alt="missing">, and <img src="" alt="missing"> are omitted.</p>
6-
<p>Same goes for <a href=""></a> and <img src="">.</p>
4+
<p>However, the [missing], [missing][], and [missing][missing] are omitted.</p>
5+
<p>However, the ![missing], ![missing][], and ![missing][missing] are omitted.</p>
6+
<p>Same goes for [][empty] and ![][empty].</p>

‎test/fixtures/tables/config.json

-3
This file was deleted.

‎test/fixtures/tables/input.md

-7
This file was deleted.

‎test/fixtures/tables/output.html

-42
This file was deleted.

‎test/fixtures/yaml/config.json

-3
This file was deleted.

‎test/fixtures/yaml/input.md

-5
This file was deleted.

‎test/fixtures/yaml/output.html

-1
This file was deleted.

‎test/index.js

+73-151
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,29 @@
22

33
var path = require('path')
44
var fs = require('fs')
5-
var assert = require('assert')
65
var test = require('tape')
76
var remark = require('remark')
7+
var slug = require('remark-slug')
88
var toc = require('remark-toc')
99
var github = require('remark-github')
1010
var commonmark = require('commonmark.json')
1111
var vfile = require('to-vfile')
1212
var hidden = require('is-hidden')
13+
var not = require('not')
14+
var unified = require('unified')
15+
var parse = require('remark-parse')
16+
var rehypeParse = require('rehype-parse')
17+
var rehypeStringify = require('rehype-stringify')
1318
var all = require('mdast-util-to-hast/lib/all')
1419
var html = require('..')
1520

16-
var read = fs.readFileSync
17-
var exists = fs.existsSync
18-
var join = path.join
19-
20-
// By default, CommonMark failures are accepted.
21-
// To fail on CommonMark exceptions, set the `CMARK` environment variable.
22-
var ignoreCommonMarkException = !('CMARK' in global.process.env)
23-
24-
var integrationMap = {github: github, toc: toc}
25-
var integrationRoot = join(__dirname, 'integrations')
26-
var fixtureRoot = join(__dirname, 'fixtures')
27-
28-
var commonmarkOptions = {
29-
entities: {escapeOnly: true, useNamedReferences: true},
30-
commonmark: true,
31-
yaml: false,
32-
closeSelfClosing: true,
33-
sanitize: false
34-
}
35-
36-
// List of CommonMark tests I dissagree with.
37-
// For reasoning, see `doc/commonmark.md`.
38-
// Note that these differences have to do with not puting more time into
39-
// features which IMHO produce less quality HTML.
40-
// So if you’d like to write the features, I’ll gladly merge!
41-
var commonmarkIgnore = [
42-
// Exception 1.
43-
247,
44-
248,
45-
46-
// Exception 2.
47-
3,
48-
50,
49-
76,
50-
77,
51-
80,
52-
86,
53-
89,
54-
98,
55-
118,
56-
176,
57-
230,
58-
231,
59-
233,
60-
236,
61-
257,
62-
258,
63-
261,
64-
262,
65-
263,
66-
264,
67-
265,
68-
266,
69-
267,
70-
268,
71-
269,
72-
270,
73-
395,
74-
396,
75-
433,
76-
445,
77-
520,
78-
522,
79-
551,
80-
81-
// Exception 3.
82-
428,
83-
477,
84-
478,
85-
479,
86-
480,
87-
481,
88-
489,
89-
493
90-
]
91-
92-
var fixtures = fs.readdirSync(fixtureRoot)
93-
var integrations = fs.readdirSync(integrationRoot)
94-
95-
fixtures = fixtures.filter(hidden)
96-
integrations = integrations.filter(hidden)
97-
98-
var section
99-
var start
100-
101-
commonmark.forEach(function (test, position) {
102-
if (section !== test.section) {
103-
section = test.section
104-
start = position
105-
}
106-
107-
test.relative = position - start + 1
108-
})
109-
11021
test('remark-html()', function (t) {
11122
var processor
11223

11324
t.equal(typeof html, 'function', 'should be a function')
11425

11526
t.doesNotThrow(function () {
116-
html.call(remark())
27+
remark().use(html).freeze()
11728
}, 'should not throw if not passed options')
11829

11930
t.throws(
@@ -315,93 +226,104 @@ test('remark-html()', function (t) {
315226

316227
// Assert fixtures.
317228
test('Fixtures', function (t) {
318-
fixtures.forEach(function (fixture) {
319-
var filepath = join(fixtureRoot, fixture)
320-
var output = read(join(filepath, 'output.html'), 'utf-8')
321-
var input = read(join(filepath, 'input.md'), 'utf-8')
322-
var config = join(filepath, 'config.json')
323-
var file = vfile(fixture + '.md')
229+
var base = path.join(__dirname, 'fixtures')
230+
231+
fs.readdirSync(base).filter(not(hidden)).forEach(each)
232+
233+
t.end()
234+
235+
function each(name) {
236+
var output = String(fs.readFileSync(path.join(base, name, 'output.html')))
237+
var input = String(fs.readFileSync(path.join(base, name, 'input.md')))
238+
var config = {}
239+
var file = vfile(name + '.md')
324240
var result
325241

326242
file.contents = input
327243

328-
config = exists(config) ? JSON.parse(read(config, 'utf-8')) : {}
329-
result = processSync(file, config)
244+
try {
245+
config = JSON.parse(fs.readFileSync(path.join(base, name, 'config.json')))
246+
} catch (_) {}
330247

331-
t.equal(result, output, 'should work on `' + fixture + '`')
332-
})
248+
result = processSync(file, config)
333249

334-
t.end()
250+
t.equal(result, output, 'should work on `' + name + '`')
251+
}
335252
})
336253

337-
// Assert CommonMark.
338254
test('CommonMark', function (t) {
339-
commonmark.forEach(function (test, n) {
340-
var name = test.section + ' ' + test.relative
341-
var file = vfile(name + '.md')
342-
var result
343-
var message
344-
var exception
255+
var start = 0
256+
var section
345257

346-
file.contents = test.markdown
347-
result = processSync(file, commonmarkOptions)
258+
commonmark.forEach(each)
348259

349-
n += 1
260+
t.end()
350261

351-
try {
352-
assert.strictEqual(result, test.html)
353-
} catch (error) {
354-
exception = error
262+
function each(example, index) {
263+
if (section !== example.section) {
264+
section = example.section
265+
start = index
355266
}
356267

357-
message = '(' + n + ') should work on ' + name
358-
359-
if (
360-
commonmarkIgnore.indexOf(n) !== -1 ||
361-
(ignoreCommonMarkException && exception)
362-
) {
363-
t.skip(message)
364-
} else {
365-
t.equal(result, test.html, message)
366-
}
367-
})
268+
var actual = unified()
269+
.use(parse)
270+
.use(html)
271+
.processSync(example.markdown)
272+
.toString()
368273

369-
t.end()
274+
var reformat = unified()
275+
.use(rehypeParse, {fragment: true})
276+
.use(rehypeStringify)
277+
278+
// Normalize meaningless stuff, like character references, `<hr />` is `<hr>`,
279+
// etc.
280+
t.equal(
281+
String(reformat.processSync(actual)),
282+
String(reformat.processSync(example.html)),
283+
index + ': ' + example.section + ' (' + (index - start + 1) + ')'
284+
)
285+
}
370286
})
371287

372-
// Assert integrations.
373288
test('Integrations', function (t) {
374-
integrations.forEach(function (integration) {
375-
var filepath = join(integrationRoot, integration)
376-
var output = read(join(filepath, 'output.html'), 'utf-8')
377-
var input = read(join(filepath, 'input.md'), 'utf-8')
378-
var config = join(filepath, 'config.json')
379-
var file = vfile(integration + '.md')
289+
var integrationMap = {github: github, toc: [slug, toc]}
290+
var base = path.join(__dirname, 'integrations')
291+
292+
fs.readdirSync(base)
293+
.filter(not(hidden))
294+
// Ignore `github` for now, which needs to be updated for remark@next.
295+
// To do: add gfm, footnotes, frontmatter integrations.
296+
.filter((d) => d !== 'github')
297+
.forEach(each)
298+
299+
t.end()
300+
301+
function each(name) {
302+
var output = String(fs.readFileSync(path.join(base, name, 'output.html')))
303+
var input = String(fs.readFileSync(path.join(base, name, 'input.md')))
304+
var file = vfile(name + '.md')
305+
var config = {}
380306
var result
381307

382308
file.contents = input
383309

384-
config = exists(config) ? JSON.parse(read(config, 'utf-8')) : {}
310+
try {
311+
config = JSON.parse(fs.readFileSync(path.join(base, name, 'config.json')))
312+
} catch (_) {}
385313

386314
config.sanitize = false
387315

388316
result = remark()
389317
.data('settings', config)
390318
.use(html, config)
391-
.use(integrationMap[integration], config)
319+
.use(integrationMap[name], config)
392320
.processSync(file)
393321
.toString()
394322

395-
t.equal(result, output, 'should work on `' + integration + '`')
396-
})
397-
398-
t.end()
323+
t.equal(result, output, 'should work on `' + name + '`')
324+
}
399325
})
400326

401327
function processSync(file, config) {
402-
return remark()
403-
.data('settings', config)
404-
.use(html, config)
405-
.processSync(file)
406-
.toString()
328+
return remark().use(html, config).processSync(file).toString()
407329
}

0 commit comments

Comments
 (0)
Please sign in to comment.