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
*.log
.nyc_output/
coverage/
node_modules/
yarn.lock

View file

@ -1,4 +1,3 @@
coverage/
*.html
*.json
*.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
exports.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')
export const directiveContainer = {
tokenize: tokenizeDirectiveContainer,
concrete: true
}
var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true}
function tokenizeDirectiveContainer(effects, ok, nok) {
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 previous
@ -42,7 +46,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
}
effects.exit('directiveContainerSequence')
return createName.call(
return factoryName.call(
self,
effects,
afterName,
@ -64,7 +68,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
}
function afterAttributes(code) {
return createSpace(effects, openAfter, 'whitespace')(code)
return factorySpace(effects, openAfter, 'whitespace')(code)
}
function openAfter(code) {
@ -103,8 +107,8 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
return effects.attempt(
{tokenize: tokenizeClosingFence, partial: true},
after,
initialPrefix
? createSpace(effects, chunkStart, 'linePrefix', initialPrefix + 1)
initialSize
? factorySpace(effects, chunkStart, 'linePrefix', initialSize + 1)
: chunkStart
)(code)
}
@ -116,10 +120,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
return after(code)
}
token = effects.enter('chunkDocument', {
contentType: 'document',
previous: previous
})
token = effects.enter('chunkDocument', {contentType: 'document', previous})
if (previous) previous.next = token
previous = token
return contentContinue(code)
@ -150,7 +151,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
function tokenizeClosingFence(effects, ok, nok) {
var size = 0
return createSpace(effects, closingPrefixAfter, 'linePrefix', 4)
return factorySpace(effects, closingPrefixAfter, 'linePrefix', 4)
function closingPrefixAfter(code) {
effects.enter('directiveContainerFence')
@ -167,7 +168,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
if (size < sizeOpen) return nok(code)
effects.exit('directiveContainerSequence')
return createSpace(effects, closingSequenceEnd, 'whitespace')(code)
return factorySpace(effects, closingSequenceEnd, 'whitespace')(code)
}
function closingSequenceEnd(code) {
@ -183,7 +184,7 @@ function tokenizeDirectiveContainer(effects, ok, nok) {
function tokenizeLabel(effects, ok, nok) {
// Always a `[`
return createLabel(
return factoryLabel(
effects,
ok,
nok,
@ -196,7 +197,7 @@ function tokenizeLabel(effects, ok, nok) {
function tokenizeAttributes(effects, ok, nok) {
// Always a `{`
return createAttributes(
return factoryAttributes(
effects,
ok,
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
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')
export const directiveLeaf = {
tokenize: tokenizeDirectiveLeaf
}
var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true}
@ -30,7 +30,13 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
if (code === 58 /* `:` */) {
effects.consume(code)
effects.exit('directiveLeafSequence')
return createName.call(self, effects, afterName, nok, 'directiveLeafName')
return factoryName.call(
self,
effects,
afterName,
nok,
'directiveLeafName'
)
}
return nok(code)
@ -49,7 +55,7 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
}
function afterAttributes(code) {
return createSpace(effects, end, 'whitespace')(code)
return factorySpace(effects, end, 'whitespace')(code)
}
function end(code) {
@ -64,7 +70,7 @@ function tokenizeDirectiveLeaf(effects, ok, nok) {
function tokenizeLabel(effects, ok, nok) {
// Always a `[`
return createLabel(
return factoryLabel(
effects,
ok,
nok,
@ -77,7 +83,7 @@ function tokenizeLabel(effects, ok, nok) {
function tokenizeAttributes(effects, ok, nok) {
// Always a `{`
return createAttributes(
return factoryAttributes(
effects,
ok,
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
exports.previous = previous
var createAttributes = require('./factory-attributes.js')
var createLabel = require('./factory-label.js')
var createName = require('./factory-name.js')
export const directiveText = {
tokenize: tokenizeDirectiveText,
previous
}
var label = {tokenize: tokenizeLabel, partial: true}
var attributes = {tokenize: tokenizeAttributes, partial: true}
@ -36,7 +36,7 @@ function tokenizeDirectiveText(effects, ok, nok) {
effects.enter('directiveTextMarker')
effects.consume(code)
effects.exit('directiveTextMarker')
return createName.call(self, effects, afterName, nok, 'directiveTextName')
return factoryName.call(self, effects, afterName, nok, 'directiveTextName')
}
function afterName(code) {
@ -61,7 +61,7 @@ function tokenizeDirectiveText(effects, ok, nok) {
function tokenizeLabel(effects, ok, nok) {
// Always a `[`
return createLabel(
return factoryLabel(
effects,
ok,
nok,
@ -73,7 +73,7 @@ function tokenizeLabel(effects, ok, nok) {
function tokenizeAttributes(effects, ok, nok) {
// Always a `{`
return createAttributes(
return factoryAttributes(
effects,
ok,
nok,

View file

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

View file

@ -1,6 +1,4 @@
module.exports = createLabel
var markdownLineEnding = require('micromark/dist/character/markdown-line-ending')
import {markdownLineEnding} from 'micromark-util-character'
// This is a fork of:
// <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.
// eslint-disable-next-line max-params
function createLabel(
export function factoryLabel(
effects,
ok,
nok,

View file

@ -1,11 +1,6 @@
'use strict'
import {asciiAlpha, asciiAlphanumeric} from 'micromark-util-character'
module.exports = createName
var asciiAlpha = require('micromark/dist/character/ascii-alpha')
var asciiAlphanumeric = require('micromark/dist/character/ascii-alphanumeric')
function createName(effects, ok, nok, nameType) {
export function factoryName(effects, ok, nok, nameType) {
var self = this
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
function createDirectiveHtmlExtension(options) {
export function directiveHtml(options) {
var extensions = options || {}
return {
@ -70,7 +67,7 @@ function createDirectiveHtmlExtension(options) {
function enter(type) {
var stack = this.getData('directiveStack')
if (!stack) this.setData('directiveStack', (stack = []))
stack.push({type: type})
stack.push({type})
}
function exitName(token) {
@ -189,5 +186,5 @@ function decodeLight(value) {
}
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
var directiveText = require('./tokenize-directive-text.js')
var directiveLeaf = require('./tokenize-directive-leaf.js')
var directiveContainer = require('./tokenize-directive-container.js')
function directive() {
export function directive() {
return {
text: {58: directiveText},
flow: {58: [directiveContainer, directiveLeaf]}

View file

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

View file

@ -25,6 +25,9 @@ use [`mdast-util-directive`][mdast-util-directive] with **[mdast][]** or
## 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][]:
```sh
@ -79,12 +82,12 @@ Now, running `node example` yields (abbreviated):
## 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
> `micromark-extension-directive/html`.
### `directiveHtml(htmlOptions?)`
Support the [generic directives proposal][prop].
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')
var micromark = require('micromark/lib')
var voids = require('html-void-elements')
var syntax = require('.')
var html = require('./html.js')
import test from 'tape'
import {micromark} from 'micromark'
import {htmlVoidElements} from 'html-void-elements'
import {directive as syntax, directiveHtml as html} from '../index.js'
test('micromark-extension-directive (syntax)', function (t) {
t.test('text', function (t) {
@ -1113,7 +1112,7 @@ test('micromark-extension-directive (compile)', function (t) {
':abbr{title="HyperText Markup Language"}',
':abbr[HTML]{title="HyperText Markup Language"}'
].join('\n\n'),
options({abbr: abbr})
options({abbr})
),
[
'<p><abbr></abbr></p>',
@ -1143,7 +1142,7 @@ test('micromark-extension-directive (compile)', function (t) {
':::youtube{v=5}\ny\n:::',
':::youtube[Cat in a box f]{v=6}\nz\n:::'
].join('\n\n'),
options({youtube: youtube})
options({youtube})
),
[
'<p>Text:</p>',
@ -1166,10 +1165,7 @@ test('micromark-extension-directive (compile)', function (t) {
)
t.equal(
micromark(
':youtube[Cat in a box]\n:br',
options({youtube: youtube, '*': h})
),
micromark(':youtube[Cat in a box]\n:br', options({youtube, '*': h})),
'<p><youtube>Cat in a box</youtube>\n<br></p>',
'should support fall through directives (`*`)'
)
@ -1185,73 +1181,73 @@ test('micromark-extension-directive (compile)', function (t) {
test('content', function (t) {
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>',
'should support character escapes and character references in label'
)
t.equal(
micromark(':abbr[x\\[y\\]z]', options({abbr: abbr})),
micromark(':abbr[x\\[y\\]z]', options({abbr})),
'<p><abbr>x[y]z</abbr></p>',
'should support escaped brackets in a label'
)
t.equal(
micromark(':abbr[x[y]z]', options({abbr: abbr})),
micromark(':abbr[x[y]z]', options({abbr})),
'<p><abbr>x[y]z</abbr></p>',
'should support balanced brackets in a label'
)
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>',
'should support balanced brackets in a label, three levels deep'
)
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>',
'should *not* support balanced brackets in a label, four levels deep'
)
t.equal(
micromark(':abbr[a\nb\rc]', options({abbr: abbr})),
micromark(':abbr[a\nb\rc]', options({abbr})),
'<p><abbr>a\nb\rc</abbr></p>',
'should support EOLs in a label'
)
t.equal(
micromark(':abbr[\na\r]', options({abbr: abbr})),
micromark(':abbr[\na\r]', options({abbr})),
'<p><abbr>\na\r</abbr></p>',
'should support EOLs at the edges of a label'
)
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>',
'should support markdown in a label'
)
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>',
'should support character references in unquoted attribute values'
)
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>',
'should support character references in double attribute values'
)
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>',
'should support character references in single attribute values'
)
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>',
'should support unknown character references in attribute values'
)
@ -1429,7 +1425,7 @@ function h(d) {
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) {