This commit is contained in:
Titus Wormer 2021-06-08 15:36:32 +02:00
parent fa035cfcb7
commit 76b54c3924
No known key found for this signature in database
GPG key ID: E6E581152ED04E2E
16 changed files with 126 additions and 139 deletions

1
.gitignore vendored
View file

@ -1,6 +1,5 @@
.DS_Store .DS_Store
*.log *.log
.nyc_output/
coverage/ coverage/
node_modules/ node_modules/
yarn.lock yarn.lock

View file

@ -1,4 +1,3 @@
coverage/ coverage/
*.html *.html
*.json
*.md *.md

View file

@ -1 +0,0 @@
module.exports = require('./lib/html.js')

View file

@ -1 +1,2 @@
module.exports = require('./lib/syntax.js') export {directive} from './lib/syntax.js'
export {directiveHtml} from './lib/html.js'

View file

@ -1,21 +1,25 @@
'use strict' import {factorySpace} from 'micromark-factory-space'
import {markdownLineEnding} from 'micromark-util-character'
// . import prefixSize from 'micromark/dist/util/prefix-size'
import {factoryAttributes} from './factory-attributes.js'
import {factoryLabel} from './factory-label.js'
import {factoryName} from './factory-name.js'
exports.tokenize = tokenizeDirectiveContainer export const directiveContainer = {
exports.concrete = true tokenize: tokenizeDirectiveContainer,
concrete: true
var markdownLineEnding = require('micromark/dist/character/markdown-line-ending') }
var createSpace = require('micromark/dist/tokenize/factory-space')
var prefixSize = require('micromark/dist/util/prefix-size')
var createAttributes = require('./factory-attributes.js')
var createLabel = require('./factory-label.js')
var createName = require('./factory-name.js')
var label = {tokenize: tokenizeLabel, partial: true} var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true} var attributes = {tokenize: tokenizeAttributes, partial: true}
function tokenizeDirectiveContainer(effects, ok, nok) { function tokenizeDirectiveContainer(effects, ok, nok) {
var self = this var self = this
var initialPrefix = prefixSize(this.events, 'linePrefix') const tail = self.events[self.events.length - 1]
const initialSize =
tail && tail[1].type === 'linePrefix'
? tail[2].sliceSerialize(tail[1], true).length
: 0
var sizeOpen = 0 var sizeOpen = 0
var previous var previous
@ -42,7 +46,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
} }
effects.exit('directiveContainerSequence') effects.exit('directiveContainerSequence')
return createName.call( return factoryName.call(
self, self,
effects, effects,
afterName, afterName,
@ -64,7 +68,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
} }
function afterAttributes(code) { function afterAttributes(code) {
return createSpace(effects, openAfter, 'whitespace')(code) return factorySpace(effects, openAfter, 'whitespace')(code)
} }
function openAfter(code) { function openAfter(code) {
@ -103,8 +107,8 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
return effects.attempt( return effects.attempt(
{tokenize: tokenizeClosingFence, partial: true}, {tokenize: tokenizeClosingFence, partial: true},
after, after,
initialPrefix initialSize
? createSpace(effects, chunkStart, 'linePrefix', initialPrefix + 1) ? factorySpace(effects, chunkStart, 'linePrefix', initialSize + 1)
: chunkStart : chunkStart
)(code) )(code)
} }
@ -116,10 +120,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
return after(code) return after(code)
} }
token = effects.enter('chunkDocument', { token = effects.enter('chunkDocument', {contentType: 'document', previous})
contentType: 'document',
previous: previous
})
if (previous) previous.next = token if (previous) previous.next = token
previous = token previous = token
return contentContinue(code) return contentContinue(code)
@ -150,7 +151,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
function tokenizeClosingFence(effects, ok, nok) { function tokenizeClosingFence(effects, ok, nok) {
var size = 0 var size = 0
return createSpace(effects, closingPrefixAfter, 'linePrefix', 4) return factorySpace(effects, closingPrefixAfter, 'linePrefix', 4)
function closingPrefixAfter(code) { function closingPrefixAfter(code) {
effects.enter('directiveContainerFence') effects.enter('directiveContainerFence')
@ -167,7 +168,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
if (size < sizeOpen) return nok(code) if (size < sizeOpen) return nok(code)
effects.exit('directiveContainerSequence') effects.exit('directiveContainerSequence')
return createSpace(effects, closingSequenceEnd, 'whitespace')(code) return factorySpace(effects, closingSequenceEnd, 'whitespace')(code)
} }
function closingSequenceEnd(code) { function closingSequenceEnd(code) {
@ -183,7 +184,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
function tokenizeLabel(effects, ok, nok) { function tokenizeLabel(effects, ok, nok) {
// Always a `[` // Always a `[`
return createLabel( return factoryLabel(
effects, effects,
ok, ok,
nok, nok,
@ -196,7 +197,7 @@ function tokenizeLabel(effects, ok, nok) {
function tokenizeAttributes(effects, ok, nok) { function tokenizeAttributes(effects, ok, nok) {
// Always a `{` // Always a `{`
return createAttributes( return factoryAttributes(
effects, effects,
ok, ok,
nok, nok,

View file

@ -1,12 +1,12 @@
'use strict' import {factorySpace} from 'micromark-factory-space'
import {markdownLineEnding} from 'micromark-util-character'
import {factoryAttributes} from './factory-attributes.js'
import {factoryLabel} from './factory-label.js'
import {factoryName} from './factory-name.js'
exports.tokenize = tokenizeDirectiveLeaf export const directiveLeaf = {
tokenize: tokenizeDirectiveLeaf
var markdownLineEnding = require('micromark/dist/character/markdown-line-ending') }
var createSpace = require('micromark/dist/tokenize/factory-space')
var createAttributes = require('./factory-attributes.js')
var createLabel = require('./factory-label.js')
var createName = require('./factory-name.js')
var label = {tokenize: tokenizeLabel, partial: true} var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true} var attributes = {tokenize: tokenizeAttributes, partial: true}
@ -30,7 +30,13 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
if (code === 58 /* `:` */) { if (code === 58 /* `:` */) {
effects.consume(code) effects.consume(code)
effects.exit('directiveLeafSequence') effects.exit('directiveLeafSequence')
return createName.call(self, effects, afterName, nok, 'directiveLeafName') return factoryName.call(
self,
effects,
afterName,
nok,
'directiveLeafName'
)
} }
return nok(code) return nok(code)
@ -49,7 +55,7 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
} }
function afterAttributes(code) { function afterAttributes(code) {
return createSpace(effects, end, 'whitespace')(code) return factorySpace(effects, end, 'whitespace')(code)
} }
function end(code) { function end(code) {
@ -64,7 +70,7 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
function tokenizeLabel(effects, ok, nok) { function tokenizeLabel(effects, ok, nok) {
// Always a `[` // Always a `[`
return createLabel( return factoryLabel(
effects, effects,
ok, ok,
nok, nok,
@ -77,7 +83,7 @@ function tokenizeLabel(effects, ok, nok) {
function tokenizeAttributes(effects, ok, nok) { function tokenizeAttributes(effects, ok, nok) {
// Always a `{` // Always a `{`
return createAttributes( return factoryAttributes(
effects, effects,
ok, ok,
nok, nok,

View file

@ -1,11 +1,11 @@
'use strict' import {factoryAttributes} from './factory-attributes.js'
import {factoryLabel} from './factory-label.js'
import {factoryName} from './factory-name.js'
exports.tokenize = tokenizeDirectiveText export const directiveText = {
exports.previous = previous tokenize: tokenizeDirectiveText,
previous
var createAttributes = require('./factory-attributes.js') }
var createLabel = require('./factory-label.js')
var createName = require('./factory-name.js')
var label = {tokenize: tokenizeLabel, partial: true} var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true} var attributes = {tokenize: tokenizeAttributes, partial: true}
@ -36,7 +36,7 @@ function tokenizeDirectiveText(effects, ok, nok) {
effects.enter('directiveTextMarker') effects.enter('directiveTextMarker')
effects.consume(code) effects.consume(code)
effects.exit('directiveTextMarker') effects.exit('directiveTextMarker')
return createName.call(self, effects, afterName, nok, 'directiveTextName') return factoryName.call(self, effects, afterName, nok, 'directiveTextName')
} }
function afterName(code) { function afterName(code) {
@ -61,7 +61,7 @@ function tokenizeDirectiveText(effects, ok, nok) {
function tokenizeLabel(effects, ok, nok) { function tokenizeLabel(effects, ok, nok) {
// Always a `[` // Always a `[`
return createLabel( return factoryLabel(
effects, effects,
ok, ok,
nok, nok,
@ -73,7 +73,7 @@ function tokenizeLabel(effects, ok, nok) {
function tokenizeAttributes(effects, ok, nok) { function tokenizeAttributes(effects, ok, nok) {
// Always a `{` // Always a `{`
return createAttributes( return factoryAttributes(
effects, effects,
ok, ok,
nok, nok,

View file

@ -1,17 +1,15 @@
'use strict' import {factorySpace} from 'micromark-factory-space'
import {factoryWhitespace} from 'micromark-factory-whitespace'
module.exports = createAttributes import {
asciiAlpha,
var asciiAlpha = require('micromark/dist/character/ascii-alpha') asciiAlphanumeric,
var asciiAlphanumeric = require('micromark/dist/character/ascii-alphanumeric') markdownLineEnding,
var markdownLineEnding = require('micromark/dist/character/markdown-line-ending') markdownLineEndingOrSpace,
var markdownLineEndingOrSpace = require('micromark/dist/character/markdown-line-ending-or-space') markdownSpace
var markdownSpace = require('micromark/dist/character/markdown-space') } from 'micromark-util-character'
var createWhitespace = require('micromark/dist/tokenize/factory-whitespace')
var createSpace = require('micromark/dist/tokenize/factory-space')
/* eslint-disable-next-line max-params */ /* eslint-disable-next-line max-params */
function createAttributes( export function factoryAttributes(
effects, effects,
ok, ok,
nok, nok,
@ -61,11 +59,11 @@ function createAttributes(
} }
if (disallowEol && markdownSpace(code)) { if (disallowEol && markdownSpace(code)) {
return createSpace(effects, between, 'whitespace')(code) return factorySpace(effects, between, 'whitespace')(code)
} }
if (!disallowEol && markdownLineEndingOrSpace(code)) { if (!disallowEol && markdownLineEndingOrSpace(code)) {
return createWhitespace(effects, between)(code) return factoryWhitespace(effects, between)(code)
} }
return end(code) return end(code)
@ -146,11 +144,11 @@ function createAttributes(
effects.exit(attributeNameType) effects.exit(attributeNameType)
if (disallowEol && markdownSpace(code)) { if (disallowEol && markdownSpace(code)) {
return createSpace(effects, nameAfter, 'whitespace')(code) return factorySpace(effects, nameAfter, 'whitespace')(code)
} }
if (!disallowEol && markdownLineEndingOrSpace(code)) { if (!disallowEol && markdownLineEndingOrSpace(code)) {
return createWhitespace(effects, nameAfter)(code) return factoryWhitespace(effects, nameAfter)(code)
} }
return nameAfter(code) return nameAfter(code)
@ -192,11 +190,11 @@ function createAttributes(
} }
if (disallowEol && markdownSpace(code)) { if (disallowEol && markdownSpace(code)) {
return createSpace(effects, valueBefore, 'whitespace')(code) return factorySpace(effects, valueBefore, 'whitespace')(code)
} }
if (!disallowEol && markdownLineEndingOrSpace(code)) { if (!disallowEol && markdownLineEndingOrSpace(code)) {
return createWhitespace(effects, valueBefore)(code) return factoryWhitespace(effects, valueBefore)(code)
} }
effects.enter(attributeValueType) effects.enter(attributeValueType)
@ -258,7 +256,7 @@ function createAttributes(
if (markdownLineEnding(code)) { if (markdownLineEnding(code)) {
return disallowEol return disallowEol
? nok(code) ? nok(code)
: createWhitespace(effects, valueQuotedBetween)(code) : factoryWhitespace(effects, valueQuotedBetween)(code)
} }
effects.enter(attributeValueData) effects.enter(attributeValueData)

View file

@ -1,6 +1,4 @@
module.exports = createLabel import {markdownLineEnding} from 'micromark-util-character'
var markdownLineEnding = require('micromark/dist/character/markdown-line-ending')
// This is a fork of: // This is a fork of:
// <https://github.com/micromark/micromark/blob/bf53bf9/lib/tokenize/factory-label.js> // <https://github.com/micromark/micromark/blob/bf53bf9/lib/tokenize/factory-label.js>
@ -8,7 +6,7 @@ var markdownLineEnding = require('micromark/dist/character/markdown-line-ending'
// text instead of strings, and optionally disallows EOLs. // text instead of strings, and optionally disallows EOLs.
// eslint-disable-next-line max-params // eslint-disable-next-line max-params
function createLabel( export function factoryLabel(
effects, effects,
ok, ok,
nok, nok,

View file

@ -1,11 +1,6 @@
'use strict' import {asciiAlpha, asciiAlphanumeric} from 'micromark-util-character'
module.exports = createName export function factoryName(effects, ok, nok, nameType) {
var asciiAlpha = require('micromark/dist/character/ascii-alpha')
var asciiAlphanumeric = require('micromark/dist/character/ascii-alphanumeric')
function createName(effects, ok, nok, nameType) {
var self = this var self = this
return start return start

View file

@ -1,11 +1,8 @@
'use strict' import {decodeEntity} from 'parse-entities/decode-entity.js'
module.exports = createDirectiveHtmlExtension
var decode = require('parse-entities/decode-entity')
var own = {}.hasOwnProperty var own = {}.hasOwnProperty
function createDirectiveHtmlExtension(options) { export function directiveHtml(options) {
var extensions = options || {} var extensions = options || {}
return { return {
@ -70,7 +67,7 @@ function createDirectiveHtmlExtension(options) {
function enter(type) { function enter(type) {
var stack = this.getData('directiveStack') var stack = this.getData('directiveStack')
if (!stack) this.setData('directiveStack', (stack = [])) if (!stack) this.setData('directiveStack', (stack = []))
stack.push({type: type}) stack.push({type})
} }
function exitName(token) { function exitName(token) {
@ -189,5 +186,5 @@ function decodeLight(value) {
} }
function decodeIfPossible($0, $1) { function decodeIfPossible($0, $1) {
return decode($1) || $0 return decodeEntity($1) || $0
} }

View file

@ -1 +0,0 @@
module.exports = require('./syntax.js')

View file

@ -1,12 +1,8 @@
'use strict' import {directiveContainer} from './directive-container.js'
import {directiveLeaf} from './directive-leaf.js'
import {directiveText} from './directive-text.js'
module.exports = directive export function directive() {
var directiveText = require('./tokenize-directive-text.js')
var directiveLeaf = require('./tokenize-directive-leaf.js')
var directiveContainer = require('./tokenize-directive-container.js')
function directive() {
return { return {
text: {58: directiveText}, text: {58: directiveText},
flow: {58: [directiveContainer, directiveLeaf]} flow: {58: [directiveContainer, directiveLeaf]}

View file

@ -23,36 +23,35 @@
"contributors": [ "contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)" "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
], ],
"sideEffects": false,
"type": "module",
"main": "index.js",
"files": [ "files": [
"lib/", "lib/",
"index.js", "index.js"
"html.js"
], ],
"dependencies": { "dependencies": {
"micromark": "~2.11.0", "micromark": "^3.0.0-alpha.2",
"parse-entities": "^2.0.0" "micromark-factory-space": "^1.0.0-alpha.2",
"micromark-factory-whitespace": "^1.0.0-alpha.2",
"micromark-util-character": "^1.0.0-alpha.2",
"parse-entities": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"html-void-elements": "^1.0.0", "c8": "^7.0.0",
"nyc": "^15.0.0", "html-void-elements": "^2.0.0",
"prettier": "^2.0.0", "prettier": "^2.0.0",
"remark-cli": "^9.0.0", "remark-cli": "^9.0.0",
"remark-preset-wooorm": "^8.0.0", "remark-preset-wooorm": "^8.0.0",
"tape": "^5.0.0", "tape": "^5.0.0",
"xo": "^0.38.0" "xo": "^0.39.0"
}, },
"scripts": { "scripts": {
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node test", "test-api": "node --conditions development test/index.js",
"test-coverage": "nyc --reporter lcov tape test.js", "test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --conditions development test/index.js",
"test": "npm run format && npm run test-coverage" "test": "npm run format && npm run test-coverage"
}, },
"nyc": {
"check-coverage": true,
"lines": 100,
"functions": 100,
"branches": 100
},
"prettier": { "prettier": {
"tabWidth": 2, "tabWidth": 2,
"useTabs": false, "useTabs": false,
@ -63,8 +62,9 @@
}, },
"xo": { "xo": {
"prettier": true, "prettier": true,
"esnext": false,
"rules": { "rules": {
"no-var": "off",
"prefer-arrow-callback": "off",
"guard-for-in": "off", "guard-for-in": "off",
"unicorn/explicit-length-check": "off", "unicorn/explicit-length-check": "off",
"unicorn/no-this-assignment": "off" "unicorn/no-this-assignment": "off"

View file

@ -25,6 +25,9 @@ use [`mdast-util-directive`][mdast-util-directive] with **[mdast][]** or
## Install ## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
[npm][]: [npm][]:
```sh ```sh
@ -79,12 +82,12 @@ Now, running `node example` yields (abbreviated):
## API ## API
### `html(htmlOptions?)` This package exports the following identifiers: `directive`, `directiveHtml`.
There is no default export.
### `syntax(syntaxOptions?)` ### `directive(syntaxOptions?)`
> Note: `syntax` is the default export of this module, `html` is available at ### `directiveHtml(htmlOptions?)`
> `micromark-extension-directive/html`.
Support the [generic directives proposal][prop]. Support the [generic directives proposal][prop].
The export of `syntax` is a function that can be called with options and returns The export of `syntax` is a function that can be called with options and returns

View file

@ -1,8 +1,7 @@
var test = require('tape') import test from 'tape'
var micromark = require('micromark/lib') import {micromark} from 'micromark'
var voids = require('html-void-elements') import {htmlVoidElements} from 'html-void-elements'
var syntax = require('.') import {directive as syntax, directiveHtml as html} from '../index.js'
var html = require('./html.js')
test('micromark-extension-directive (syntax)', function (t) { test('micromark-extension-directive (syntax)', function (t) {
t.test('text', function (t) { t.test('text', function (t) {
@ -1113,7 +1112,7 @@ test('micromark-extension-directive (compile)', function (t) {
':abbr{title="HyperText Markup Language"}', ':abbr{title="HyperText Markup Language"}',
':abbr[HTML]{title="HyperText Markup Language"}' ':abbr[HTML]{title="HyperText Markup Language"}'
].join('\n\n'), ].join('\n\n'),
options({abbr: abbr}) options({abbr})
), ),
[ [
'<p><abbr></abbr></p>', '<p><abbr></abbr></p>',
@ -1143,7 +1142,7 @@ test('micromark-extension-directive (compile)', function (t) {
':::youtube{v=5}\ny\n:::', ':::youtube{v=5}\ny\n:::',
':::youtube[Cat in a box f]{v=6}\nz\n:::' ':::youtube[Cat in a box f]{v=6}\nz\n:::'
].join('\n\n'), ].join('\n\n'),
options({youtube: youtube}) options({youtube})
), ),
[ [
'<p>Text:</p>', '<p>Text:</p>',
@ -1166,10 +1165,7 @@ test('micromark-extension-directive (compile)', function (t) {
) )
t.equal( t.equal(
micromark( micromark(':youtube[Cat in a box]\n:br', options({youtube, '*': h})),
':youtube[Cat in a box]\n:br',
options({youtube: youtube, '*': h})
),
'<p><youtube>Cat in a box</youtube>\n<br></p>', '<p><youtube>Cat in a box</youtube>\n<br></p>',
'should support fall through directives (`*`)' 'should support fall through directives (`*`)'
) )
@ -1185,73 +1181,73 @@ test('micromark-extension-directive (compile)', function (t) {
test('content', function (t) { test('content', function (t) {
t.equal( t.equal(
micromark(':abbr[x\\&y&amp;z]', options({abbr: abbr})), micromark(':abbr[x\\&y&amp;z]', options({abbr})),
'<p><abbr>x&amp;y&amp;z</abbr></p>', '<p><abbr>x&amp;y&amp;z</abbr></p>',
'should support character escapes and character references in label' 'should support character escapes and character references in label'
) )
t.equal( t.equal(
micromark(':abbr[x\\[y\\]z]', options({abbr: abbr})), micromark(':abbr[x\\[y\\]z]', options({abbr})),
'<p><abbr>x[y]z</abbr></p>', '<p><abbr>x[y]z</abbr></p>',
'should support escaped brackets in a label' 'should support escaped brackets in a label'
) )
t.equal( t.equal(
micromark(':abbr[x[y]z]', options({abbr: abbr})), micromark(':abbr[x[y]z]', options({abbr})),
'<p><abbr>x[y]z</abbr></p>', '<p><abbr>x[y]z</abbr></p>',
'should support balanced brackets in a label' 'should support balanced brackets in a label'
) )
t.equal( t.equal(
micromark(':abbr[a[b[c[d]e]f]g]h', options({abbr: abbr})), micromark(':abbr[a[b[c[d]e]f]g]h', options({abbr})),
'<p><abbr>a[b[c[d]e]f]g</abbr>h</p>', '<p><abbr>a[b[c[d]e]f]g</abbr>h</p>',
'should support balanced brackets in a label, three levels deep' 'should support balanced brackets in a label, three levels deep'
) )
t.equal( t.equal(
micromark(':abbr[a[b[c[d[e]f]g]h]i]j', options({abbr: abbr})), micromark(':abbr[a[b[c[d[e]f]g]h]i]j', options({abbr})),
'<p><abbr></abbr>[a[b[c[d[e]f]g]h]i]j</p>', '<p><abbr></abbr>[a[b[c[d[e]f]g]h]i]j</p>',
'should *not* support balanced brackets in a label, four levels deep' 'should *not* support balanced brackets in a label, four levels deep'
) )
t.equal( t.equal(
micromark(':abbr[a\nb\rc]', options({abbr: abbr})), micromark(':abbr[a\nb\rc]', options({abbr})),
'<p><abbr>a\nb\rc</abbr></p>', '<p><abbr>a\nb\rc</abbr></p>',
'should support EOLs in a label' 'should support EOLs in a label'
) )
t.equal( t.equal(
micromark(':abbr[\na\r]', options({abbr: abbr})), micromark(':abbr[\na\r]', options({abbr})),
'<p><abbr>\na\r</abbr></p>', '<p><abbr>\na\r</abbr></p>',
'should support EOLs at the edges of a label' 'should support EOLs at the edges of a label'
) )
t.equal( t.equal(
micromark(':abbr[a *b* **c** d]', options({abbr: abbr})), micromark(':abbr[a *b* **c** d]', options({abbr})),
'<p><abbr>a <em>b</em> <strong>c</strong> d</abbr></p>', '<p><abbr>a <em>b</em> <strong>c</strong> d</abbr></p>',
'should support markdown in a label' 'should support markdown in a label'
) )
t.equal( t.equal(
micromark(':abbr{title=a&apos;b}', options({abbr: abbr})), micromark(':abbr{title=a&apos;b}', options({abbr})),
'<p><abbr title="a\'b"></abbr></p>', '<p><abbr title="a\'b"></abbr></p>',
'should support character references in unquoted attribute values' 'should support character references in unquoted attribute values'
) )
t.equal( t.equal(
micromark(':abbr{title="a&apos;b"}', options({abbr: abbr})), micromark(':abbr{title="a&apos;b"}', options({abbr})),
'<p><abbr title="a\'b"></abbr></p>', '<p><abbr title="a\'b"></abbr></p>',
'should support character references in double attribute values' 'should support character references in double attribute values'
) )
t.equal( t.equal(
micromark(":abbr{title='a&apos;b'}", options({abbr: abbr})), micromark(":abbr{title='a&apos;b'}", options({abbr})),
'<p><abbr title="a\'b"></abbr></p>', '<p><abbr title="a\'b"></abbr></p>',
'should support character references in single attribute values' 'should support character references in single attribute values'
) )
t.equal( t.equal(
micromark(':abbr{title="a&somethingelse;b"}', options({abbr: abbr})), micromark(':abbr{title="a&somethingelse;b"}', options({abbr})),
'<p><abbr title="a&amp;somethingelse;b"></abbr></p>', '<p><abbr title="a&amp;somethingelse;b"></abbr></p>',
'should support unknown character references in attribute values' 'should support unknown character references in attribute values'
) )
@ -1429,7 +1425,7 @@ function h(d) {
if (d.type === 'containerDirective') this.lineEndingIfNeeded() if (d.type === 'containerDirective') this.lineEndingIfNeeded()
} }
if (!voids.includes(d.name)) this.tag('</' + d.name + '>') if (!htmlVoidElements.includes(d.name)) this.tag('</' + d.name + '>')
} }
function options(options) { function options(options) {