From abf120a5fc5b8ff6c8a96989eb8f2da09e0e167c Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Thu, 22 Oct 2020 19:09:38 +0200 Subject: [PATCH] . --- .editorconfig | 9 + .gitignore | 6 + .npmrc | 1 + .prettierignore | 3 + .travis.yml | 5 + index.js | 39 ++ license | 22 + package.json | 84 ++++ readme.md | 162 ++++++++ test/fixtures/container/input.md | 32 ++ test/fixtures/container/output.md | 38 ++ test/fixtures/container/tree.json | 666 ++++++++++++++++++++++++++++++ test/fixtures/leaf/input.md | 11 + test/fixtures/leaf/output.md | 11 + test/fixtures/leaf/tree.json | 266 ++++++++++++ test/fixtures/text/input.md | 7 + test/fixtures/text/output.md | 7 + test/fixtures/text/tree.json | 429 +++++++++++++++++++ test/index.js | 67 +++ types/index.d.ts | 11 + types/test.ts | 7 + types/tsconfig.json | 10 + types/tslint.json | 7 + 23 files changed, 1900 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .travis.yml create mode 100644 index.js create mode 100644 license create mode 100644 package.json create mode 100644 readme.md create mode 100644 test/fixtures/container/input.md create mode 100644 test/fixtures/container/output.md create mode 100644 test/fixtures/container/tree.json create mode 100644 test/fixtures/leaf/input.md create mode 100644 test/fixtures/leaf/output.md create mode 100644 test/fixtures/leaf/tree.json create mode 100644 test/fixtures/text/input.md create mode 100644 test/fixtures/text/output.md create mode 100644 test/fixtures/text/tree.json create mode 100644 test/index.js create mode 100644 types/index.d.ts create mode 100644 types/test.ts create mode 100644 types/tsconfig.json create mode 100644 types/tslint.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c6c8b36 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fdefc8c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +*.log +.nyc_output/ +coverage/ +node_modules/ +yarn.lock diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..43c97e7 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..e7939c4 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +coverage/ +*.json +*.md diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e108609 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - lts/dubnium + - node +after_script: bash <(curl -s https://codecov.io/bash) diff --git a/index.js b/index.js new file mode 100644 index 0000000..0063bf5 --- /dev/null +++ b/index.js @@ -0,0 +1,39 @@ +'use strict' + +var syntax = require('micromark-extension-directive') +var fromMarkdown = require('mdast-util-directive/from-markdown') +var toMarkdown = require('mdast-util-directive/to-markdown') + +var warningIssued + +module.exports = directive + +function directive() { + var data = this.data() + + /* istanbul ignore next - old remark. */ + if ( + !warningIssued && + ((this.Parser && + this.Parser.prototype && + this.Parser.prototype.blockTokenizers) || + (this.Compiler && + this.Compiler.prototype && + this.Compiler.prototype.visitors)) + ) { + warningIssued = true + console.warn( + '[remark-directive] Warning: please upgrade to remark 13 to use this plugin' + ) + } + + add('micromarkExtensions', syntax()) + add('fromMarkdownExtensions', fromMarkdown) + add('toMarkdownExtensions', toMarkdown) + + function add(field, value) { + /* istanbul ignore if - other extensions. */ + if (data[field]) data[field].push(value) + else data[field] = [value] + } +} diff --git a/license b/license new file mode 100644 index 0000000..3937235 --- /dev/null +++ b/license @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2020 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/package.json b/package.json new file mode 100644 index 0000000..86504bf --- /dev/null +++ b/package.json @@ -0,0 +1,84 @@ +{ + "name": "remark-directive", + "version": "0.0.0", + "description": "remark plugin to support directives", + "license": "MIT", + "keywords": [ + "unified", + "remark", + "remark-plugin", + "plugin", + "mdast", + "markdown", + "generic", + "directive", + "container" + ], + "repository": "remarkjs/remark-directive", + "bugs": "https://github.com/remarkjs/remark-directive/issues", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "author": "Titus Wormer (https://wooorm.com)", + "contributors": [ + "Titus Wormer (https://wooorm.com)" + ], + "types": "types/index.d.ts", + "files": [ + "types/index.d.ts", + "index.js" + ], + "dependencies": { + "mdast-util-directive": "^1.0.0", + "micromark-extension-directive": "^1.0.0" + }, + "devDependencies": { + "dtslint": "^4.0.0", + "is-hidden": "^1.0.0", + "not": "^0.1.0", + "nyc": "^15.0.0", + "prettier": "^2.0.0", + "remark": "^13.0.0", + "remark-cli": "^9.0.0", + "remark-preset-wooorm": "^8.0.0", + "tape": "^5.0.0", + "to-vfile": "^6.0.0", + "unified": "^9.0.0", + "xo": "^0.34.0" + }, + "scripts": { + "format": "remark . -qfo --ignore-pattern test/ && prettier . -w --loglevel warn && xo --fix", + "test-api": "node test", + "test-coverage": "nyc --reporter lcov tape test/index.js", + "test-types": "dtslint types", + "test": "npm run format && npm run test-coverage && npm run test-types" + }, + "nyc": { + "check-coverage": true, + "lines": 100, + "functions": 100, + "branches": 100 + }, + "prettier": { + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "bracketSpacing": false, + "semi": false, + "trailingComma": "none" + }, + "xo": { + "prettier": true, + "esnext": false, + "rules": { + "unicorn/no-fn-reference-in-iterator": "off", + "unicorn/prefer-optional-catch-binding": "off" + } + }, + "remarkConfig": { + "plugins": [ + "preset-wooorm" + ] + } +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e2d75b3 --- /dev/null +++ b/readme.md @@ -0,0 +1,162 @@ +# remark-directive + +[![Build][build-badge]][build] +[![Coverage][coverage-badge]][coverage] +[![Downloads][downloads-badge]][downloads] +[![Size][size-badge]][size] +[![Sponsors][sponsors-badge]][collective] +[![Backers][backers-badge]][collective] +[![Chat][chat-badge]][chat] + +[**remark**][remark] plugin to support the [generic directives proposal][prop] +(`:cite[smith04]`, `::youtube[Video of a cat in a box]{v=01ab2cd3efg}`, and +such). + +## Important! + +This plugin is made for the new parser in remark +([`micromark`](https://github.com/micromark/micromark), +see [`remarkjs/remark#536`](https://github.com/remarkjs/remark/pull/536)). +Use this plugin for remark 13+. + +## Install + +[npm][]: + +```sh +npm install remark-directive +``` + +## Use + +Say we have the following file, `example.md`: + +```markdown +``` + +And our script, `example.js`, looks as follows: + +```js +var vfile = require('to-vfile') +var report = require('vfile-reporter') +var unified = require('unified') +var parse = require('remark-parse') +var directive = require('remark-directive') +var stringify = require('rehype-stringify') + +unified() + .use(parse) + .use(directive) + .use(remark2rehype) + .use(stringify) + .process(vfile.readSync('example.md'), function (err, file) { + console.error(report(err || file)) + console.log(String(file)) + }) +``` + +Now, running `node example` yields: + +```html +``` + +## API + +### `remark().use(directive)` + +Configures remark so that it can parse and serialize directives. +Doesn’t handle the directives: [create your own plugin][create-plugin] to do +that. +See the [micromark extension for the syntax][syntax] and the +[mdast utility for the syntax tree][syntax-tree]. + +## Security + +Use of `remark-directive` does not involve [**rehype**][rehype] +([**hast**][hast]) or user content so there are no openings for [cross-site +scripting (XSS)][xss] attacks. + +## Related + +* [`remark-gfm`](https://github.com/remarkjs/remark-gfm) + — GFM +* [`remark-github`](https://github.com/remarkjs/remark-github) + — Autolink references like in GitHub issues, PRs, and comments +* [`remark-footnotes`](https://github.com/remarkjs/remark-footnotes) + — Footnotes +* [`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter) + — Frontmatter (YAML, TOML, and more) +* [`remark-math`](https://github.com/remarkjs/remark-math) + — Math + +## Contribute + +See [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways +to get started. +See [`support.md`][support] for ways to get help. + +This project has a [code of conduct][coc]. +By interacting with this repository, organization, or community you agree to +abide by its terms. + +## License + +[MIT][license] © [Titus Wormer][author] + + + +[build-badge]: https://img.shields.io/travis/remarkjs/remark-directive/main.svg + +[build]: https://travis-ci.org/remarkjs/remark-directive + +[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark-directive.svg + +[coverage]: https://codecov.io/github/remarkjs/remark-directive + +[downloads-badge]: https://img.shields.io/npm/dm/remark-directive.svg + +[downloads]: https://www.npmjs.com/package/remark-directive + +[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-directive.svg + +[size]: https://bundlephobia.com/result?p=remark-directive + +[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg + +[backers-badge]: https://opencollective.com/unified/backers/badge.svg + +[collective]: https://opencollective.com/unified + +[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg + +[chat]: https://github.com/remarkjs/remark/discussions + +[npm]: https://docs.npmjs.com/cli/install + +[health]: https://github.com/remarkjs/.github + +[contributing]: https://github.com/remarkjs/.github/blob/HEAD/contributing.md + +[support]: https://github.com/remarkjs/.github/blob/HEAD/support.md + +[coc]: https://github.com/remarkjs/.github/blob/HEAD/code-of-conduct.md + +[license]: license + +[author]: https://wooorm.com + +[remark]: https://github.com/remarkjs/remark + +[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting + +[rehype]: https://github.com/rehypejs/rehype + +[hast]: https://github.com/syntax-tree/hast + +[prop]: https://talk.commonmark.org/t/generic-directives-plugins-syntax/444 + +[create-plugin]: https://unifiedjs.com/learn/guide/create-a-plugin/ + +[syntax]: https://github.com/micromark/micromark-extension-directive#syntax + +[syntax-tree]: https://github.com/syntax-tree/mdast-util-directive#syntax-tree diff --git a/test/fixtures/container/input.md b/test/fixtures/container/input.md new file mode 100644 index 0000000..c714fed --- /dev/null +++ b/test/fixtures/container/input.md @@ -0,0 +1,32 @@ +:::a +::: + +:::a[b] +::: + +:::a{b} +::: + +:::a[b]{c} +::: + +:::a[b *c* d **e**] +::: + +:::a{#b.c.d id=e class="f g" h="i & j k"} +::: + +:::::a +::::b +:::c +::::: + +:::::a +b +::::c +d +:::e +- - f +::: +> g h +::::: diff --git a/test/fixtures/container/output.md b/test/fixtures/container/output.md new file mode 100644 index 0000000..78291a5 --- /dev/null +++ b/test/fixtures/container/output.md @@ -0,0 +1,38 @@ +:::a +::: + +:::a[b] +::: + +:::a{b} +::: + +:::a[b]{c} +::: + +:::a[b *c* d **e**] +::: + +:::a{#e .c.d.f.g h="i & j k"} +::: + +:::::a +::::b +:::c +::: +:::: +::::: + +:::::a +b + +::::c +d + +:::e +* * f +::: + +> g h +:::: +::::: diff --git a/test/fixtures/container/tree.json b/test/fixtures/container/tree.json new file mode 100644 index 0000000..78970cd --- /dev/null +++ b/test/fixtures/container/tree.json @@ -0,0 +1,666 @@ +{ + "type": "root", + "children": [ + { + "type": "containerDirective", + "name": "a", + "attributes": {}, + "children": [], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 2, + "column": 4, + "offset": 8 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "paragraph", + "data": { + "directiveLabel": true + }, + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 4, + "column": 6, + "offset": 15 + }, + "end": { + "line": 4, + "column": 7, + "offset": 16 + } + } + } + ], + "position": { + "start": { + "line": 4, + "column": 5, + "offset": 14 + }, + "end": { + "line": 4, + "column": 8, + "offset": 17 + } + } + } + ], + "position": { + "start": { + "line": 4, + "column": 1, + "offset": 10 + }, + "end": { + "line": 5, + "column": 4, + "offset": 21 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": { + "b": "" + }, + "children": [], + "position": { + "start": { + "line": 7, + "column": 1, + "offset": 23 + }, + "end": { + "line": 8, + "column": 4, + "offset": 34 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": { + "c": "" + }, + "children": [ + { + "type": "paragraph", + "data": { + "directiveLabel": true + }, + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 10, + "column": 6, + "offset": 41 + }, + "end": { + "line": 10, + "column": 7, + "offset": 42 + } + } + } + ], + "position": { + "start": { + "line": 10, + "column": 5, + "offset": 40 + }, + "end": { + "line": 10, + "column": 8, + "offset": 43 + } + } + } + ], + "position": { + "start": { + "line": 10, + "column": 1, + "offset": 36 + }, + "end": { + "line": 11, + "column": 4, + "offset": 50 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "paragraph", + "data": { + "directiveLabel": true + }, + "children": [ + { + "type": "text", + "value": "b ", + "position": { + "start": { + "line": 13, + "column": 6, + "offset": 57 + }, + "end": { + "line": 13, + "column": 8, + "offset": 59 + } + } + }, + { + "type": "emphasis", + "children": [ + { + "type": "text", + "value": "c", + "position": { + "start": { + "line": 13, + "column": 9, + "offset": 60 + }, + "end": { + "line": 13, + "column": 10, + "offset": 61 + } + } + } + ], + "position": { + "start": { + "line": 13, + "column": 8, + "offset": 59 + }, + "end": { + "line": 13, + "column": 11, + "offset": 62 + } + } + }, + { + "type": "text", + "value": " d ", + "position": { + "start": { + "line": 13, + "column": 11, + "offset": 62 + }, + "end": { + "line": 13, + "column": 14, + "offset": 65 + } + } + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "e", + "position": { + "start": { + "line": 13, + "column": 16, + "offset": 67 + }, + "end": { + "line": 13, + "column": 17, + "offset": 68 + } + } + } + ], + "position": { + "start": { + "line": 13, + "column": 14, + "offset": 65 + }, + "end": { + "line": 13, + "column": 19, + "offset": 70 + } + } + } + ], + "position": { + "start": { + "line": 13, + "column": 5, + "offset": 56 + }, + "end": { + "line": 13, + "column": 20, + "offset": 71 + } + } + } + ], + "position": { + "start": { + "line": 13, + "column": 1, + "offset": 52 + }, + "end": { + "line": 14, + "column": 4, + "offset": 75 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": { + "id": "e", + "class": "c d f g", + "h": "i & j k" + }, + "children": [], + "position": { + "start": { + "line": 16, + "column": 1, + "offset": 77 + }, + "end": { + "line": 17, + "column": 4, + "offset": 126 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "containerDirective", + "name": "b", + "attributes": {}, + "children": [ + { + "type": "containerDirective", + "name": "c", + "attributes": {}, + "children": [], + "position": { + "start": { + "line": 21, + "column": 1, + "offset": 141 + }, + "end": { + "line": 22, + "column": 1, + "offset": 146 + } + } + } + ], + "position": { + "start": { + "line": 20, + "column": 1, + "offset": 135 + }, + "end": { + "line": 22, + "column": 1, + "offset": 146 + } + } + } + ], + "position": { + "start": { + "line": 19, + "column": 1, + "offset": 128 + }, + "end": { + "line": 22, + "column": 6, + "offset": 151 + } + } + }, + { + "type": "containerDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 25, + "column": 1, + "offset": 160 + }, + "end": { + "line": 25, + "column": 2, + "offset": 161 + } + } + } + ], + "position": { + "start": { + "line": 25, + "column": 1, + "offset": 160 + }, + "end": { + "line": 25, + "column": 2, + "offset": 161 + } + } + }, + { + "type": "containerDirective", + "name": "c", + "attributes": {}, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "d", + "position": { + "start": { + "line": 27, + "column": 1, + "offset": 168 + }, + "end": { + "line": 27, + "column": 2, + "offset": 169 + } + } + } + ], + "position": { + "start": { + "line": 27, + "column": 1, + "offset": 168 + }, + "end": { + "line": 27, + "column": 2, + "offset": 169 + } + } + }, + { + "type": "containerDirective", + "name": "e", + "attributes": {}, + "children": [ + { + "type": "list", + "ordered": false, + "start": null, + "spread": false, + "children": [ + { + "type": "listItem", + "spread": false, + "checked": null, + "children": [ + { + "type": "list", + "ordered": false, + "start": null, + "spread": false, + "children": [ + { + "type": "listItem", + "spread": false, + "checked": null, + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "f", + "position": { + "start": { + "line": 29, + "column": 5, + "offset": 179 + }, + "end": { + "line": 29, + "column": 6, + "offset": 180 + } + } + } + ], + "position": { + "start": { + "line": 29, + "column": 5, + "offset": 179 + }, + "end": { + "line": 29, + "column": 6, + "offset": 180 + } + } + } + ], + "position": { + "start": { + "line": 29, + "column": 3, + "offset": 177 + }, + "end": { + "line": 29, + "column": 6, + "offset": 180 + } + } + } + ], + "position": { + "start": { + "line": 29, + "column": 3, + "offset": 177 + }, + "end": { + "line": 29, + "column": 6, + "offset": 180 + } + } + } + ], + "position": { + "start": { + "line": 29, + "column": 1, + "offset": 175 + }, + "end": { + "line": 29, + "column": 6, + "offset": 180 + } + } + } + ], + "position": { + "start": { + "line": 29, + "column": 1, + "offset": 175 + }, + "end": { + "line": 29, + "column": 6, + "offset": 180 + } + } + } + ], + "position": { + "start": { + "line": 28, + "column": 1, + "offset": 170 + }, + "end": { + "line": 30, + "column": 4, + "offset": 184 + } + } + }, + { + "type": "blockquote", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "g h", + "position": { + "start": { + "line": 31, + "column": 3, + "offset": 187 + }, + "end": { + "line": 31, + "column": 6, + "offset": 190 + } + } + } + ], + "position": { + "start": { + "line": 31, + "column": 3, + "offset": 187 + }, + "end": { + "line": 31, + "column": 6, + "offset": 190 + } + } + } + ], + "position": { + "start": { + "line": 31, + "column": 1, + "offset": 185 + }, + "end": { + "line": 31, + "column": 6, + "offset": 190 + } + } + } + ], + "position": { + "start": { + "line": 26, + "column": 1, + "offset": 162 + }, + "end": { + "line": 32, + "column": 1, + "offset": 191 + } + } + } + ], + "position": { + "start": { + "line": 24, + "column": 1, + "offset": 153 + }, + "end": { + "line": 32, + "column": 6, + "offset": 196 + } + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 33, + "column": 1, + "offset": 197 + } + } +} diff --git a/test/fixtures/leaf/input.md b/test/fixtures/leaf/input.md new file mode 100644 index 0000000..e6c2236 --- /dev/null +++ b/test/fixtures/leaf/input.md @@ -0,0 +1,11 @@ +::a + +::a[b] + +::a{b} + +::a[b]{c} + +::a[b *c* d **e**] + +::a{#b.c.d id=e class="f g" h="i & j k"} diff --git a/test/fixtures/leaf/output.md b/test/fixtures/leaf/output.md new file mode 100644 index 0000000..f8652d9 --- /dev/null +++ b/test/fixtures/leaf/output.md @@ -0,0 +1,11 @@ +::a + +::a[b] + +::a{b} + +::a[b]{c} + +::a[b *c* d **e**] + +::a{#e .c.d.f.g h="i & j k"} diff --git a/test/fixtures/leaf/tree.json b/test/fixtures/leaf/tree.json new file mode 100644 index 0000000..f4cea19 --- /dev/null +++ b/test/fixtures/leaf/tree.json @@ -0,0 +1,266 @@ +{ + "type": "root", + "children": [ + { + "type": "leafDirective", + "name": "a", + "attributes": {}, + "children": [], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 4, + "offset": 3 + } + } + }, + { + "type": "leafDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 3, + "column": 5, + "offset": 9 + }, + "end": { + "line": 3, + "column": 6, + "offset": 10 + } + } + } + ], + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 5 + }, + "end": { + "line": 3, + "column": 7, + "offset": 11 + } + } + }, + { + "type": "leafDirective", + "name": "a", + "attributes": { + "b": "" + }, + "children": [], + "position": { + "start": { + "line": 5, + "column": 1, + "offset": 13 + }, + "end": { + "line": 5, + "column": 7, + "offset": 19 + } + } + }, + { + "type": "leafDirective", + "name": "a", + "attributes": { + "c": "" + }, + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 7, + "column": 5, + "offset": 25 + }, + "end": { + "line": 7, + "column": 6, + "offset": 26 + } + } + } + ], + "position": { + "start": { + "line": 7, + "column": 1, + "offset": 21 + }, + "end": { + "line": 7, + "column": 10, + "offset": 30 + } + } + }, + { + "type": "leafDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "text", + "value": "b ", + "position": { + "start": { + "line": 9, + "column": 5, + "offset": 36 + }, + "end": { + "line": 9, + "column": 7, + "offset": 38 + } + } + }, + { + "type": "emphasis", + "children": [ + { + "type": "text", + "value": "c", + "position": { + "start": { + "line": 9, + "column": 8, + "offset": 39 + }, + "end": { + "line": 9, + "column": 9, + "offset": 40 + } + } + } + ], + "position": { + "start": { + "line": 9, + "column": 7, + "offset": 38 + }, + "end": { + "line": 9, + "column": 10, + "offset": 41 + } + } + }, + { + "type": "text", + "value": " d ", + "position": { + "start": { + "line": 9, + "column": 10, + "offset": 41 + }, + "end": { + "line": 9, + "column": 13, + "offset": 44 + } + } + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "e", + "position": { + "start": { + "line": 9, + "column": 15, + "offset": 46 + }, + "end": { + "line": 9, + "column": 16, + "offset": 47 + } + } + } + ], + "position": { + "start": { + "line": 9, + "column": 13, + "offset": 44 + }, + "end": { + "line": 9, + "column": 18, + "offset": 49 + } + } + } + ], + "position": { + "start": { + "line": 9, + "column": 1, + "offset": 32 + }, + "end": { + "line": 9, + "column": 19, + "offset": 50 + } + } + }, + { + "type": "leafDirective", + "name": "a", + "attributes": { + "id": "e", + "class": "c d f g", + "h": "i & j k" + }, + "children": [], + "position": { + "start": { + "line": 11, + "column": 1, + "offset": 52 + }, + "end": { + "line": 11, + "column": 45, + "offset": 96 + } + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 12, + "column": 1, + "offset": 97 + } + } +} diff --git a/test/fixtures/text/input.md b/test/fixtures/text/input.md new file mode 100644 index 0000000..e0041ee --- /dev/null +++ b/test/fixtures/text/input.md @@ -0,0 +1,7 @@ +One :a, two :a[b], three :a{b}, four :a[b]{c}. + +:a[b *c* +d **e**]. + +:a{#b.c.d id=e class="f g" h="i & j +k"}. diff --git a/test/fixtures/text/output.md b/test/fixtures/text/output.md new file mode 100644 index 0000000..6766270 --- /dev/null +++ b/test/fixtures/text/output.md @@ -0,0 +1,7 @@ +One :a, two :a[b], three :a{b}, four :a[b]{c}. + +:a[b *c* +d **e**]. + +:a{#e .c.d.f.g h="i & j +k"}. diff --git a/test/fixtures/text/tree.json b/test/fixtures/text/tree.json new file mode 100644 index 0000000..a03367b --- /dev/null +++ b/test/fixtures/text/tree.json @@ -0,0 +1,429 @@ +{ + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "One ", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + } + } + }, + { + "type": "textDirective", + "name": "a", + "attributes": {}, + "children": [], + "position": { + "start": { + "line": 1, + "column": 5, + "offset": 4 + }, + "end": { + "line": 1, + "column": 7, + "offset": 6 + } + } + }, + { + "type": "text", + "value": ", two ", + "position": { + "start": { + "line": 1, + "column": 7, + "offset": 6 + }, + "end": { + "line": 1, + "column": 13, + "offset": 12 + } + } + }, + { + "type": "textDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 1, + "column": 16, + "offset": 15 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + } + } + } + ], + "position": { + "start": { + "line": 1, + "column": 13, + "offset": 12 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + } + } + }, + { + "type": "text", + "value": ", three ", + "position": { + "start": { + "line": 1, + "column": 18, + "offset": 17 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + }, + { + "type": "textDirective", + "name": "a", + "attributes": { + "b": "" + }, + "children": [], + "position": { + "start": { + "line": 1, + "column": 26, + "offset": 25 + }, + "end": { + "line": 1, + "column": 31, + "offset": 30 + } + } + }, + { + "type": "text", + "value": ", four ", + "position": { + "start": { + "line": 1, + "column": 31, + "offset": 30 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + } + } + }, + { + "type": "textDirective", + "name": "a", + "attributes": { + "c": "" + }, + "children": [ + { + "type": "text", + "value": "b", + "position": { + "start": { + "line": 1, + "column": 41, + "offset": 40 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + } + } + } + ], + "position": { + "start": { + "line": 1, + "column": 38, + "offset": 37 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 1, + "column": 46, + "offset": 45 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + } + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + } + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "textDirective", + "name": "a", + "attributes": {}, + "children": [ + { + "type": "text", + "value": "b ", + "position": { + "start": { + "line": 3, + "column": 4, + "offset": 51 + }, + "end": { + "line": 3, + "column": 6, + "offset": 53 + } + } + }, + { + "type": "emphasis", + "children": [ + { + "type": "text", + "value": "c", + "position": { + "start": { + "line": 3, + "column": 7, + "offset": 54 + }, + "end": { + "line": 3, + "column": 8, + "offset": 55 + } + } + } + ], + "position": { + "start": { + "line": 3, + "column": 6, + "offset": 53 + }, + "end": { + "line": 3, + "column": 9, + "offset": 56 + } + } + }, + { + "type": "text", + "value": "\nd ", + "position": { + "start": { + "line": 3, + "column": 9, + "offset": 56 + }, + "end": { + "line": 4, + "column": 3, + "offset": 59 + } + } + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "e", + "position": { + "start": { + "line": 4, + "column": 5, + "offset": 61 + }, + "end": { + "line": 4, + "column": 6, + "offset": 62 + } + } + } + ], + "position": { + "start": { + "line": 4, + "column": 3, + "offset": 59 + }, + "end": { + "line": 4, + "column": 8, + "offset": 64 + } + } + } + ], + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 48 + }, + "end": { + "line": 4, + "column": 9, + "offset": 65 + } + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 4, + "column": 9, + "offset": 65 + }, + "end": { + "line": 4, + "column": 10, + "offset": 66 + } + } + } + ], + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 48 + }, + "end": { + "line": 4, + "column": 10, + "offset": 66 + } + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "textDirective", + "name": "a", + "attributes": { + "id": "e", + "class": "c d f g", + "h": "i & j\nk" + }, + "children": [], + "position": { + "start": { + "line": 6, + "column": 1, + "offset": 68 + }, + "end": { + "line": 7, + "column": 4, + "offset": 111 + } + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 7, + "column": 4, + "offset": 111 + }, + "end": { + "line": 7, + "column": 5, + "offset": 112 + } + } + } + ], + "position": { + "start": { + "line": 6, + "column": 1, + "offset": 68 + }, + "end": { + "line": 7, + "column": 5, + "offset": 112 + } + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 8, + "column": 1, + "offset": 113 + } + } +} diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..e83826f --- /dev/null +++ b/test/index.js @@ -0,0 +1,67 @@ +'use strict' + +var fs = require('fs') +var path = require('path') +var test = require('tape') +var vfile = require('to-vfile') +var unified = require('unified') +var remark = require('remark') +var not = require('not') +var hidden = require('is-hidden') +var directive = require('..') + +test('directive()', function (t) { + t.doesNotThrow(function () { + remark().use(directive).freeze() + }, 'should not throw if not passed options') + + t.doesNotThrow(function () { + unified().use(directive).freeze() + }, 'should not throw if without parser or compiler') + + t.end() +}) + +test('fixtures', function (t) { + var base = path.join(__dirname, 'fixtures') + var entries = fs.readdirSync(base).filter(not(hidden)) + + t.plan(entries.length) + + entries.forEach(each) + + function each(fixture) { + t.test(fixture, function (st) { + var file = vfile.readSync(path.join(base, fixture, 'input.md')) + var input = String(file.contents) + var outputPath = path.join(base, fixture, 'output.md') + var treePath = path.join(base, fixture, 'tree.json') + var proc + var actual + var output + var expected + + proc = remark().use(directive).freeze() + actual = proc.parse(file) + + try { + expected = JSON.parse(fs.readFileSync(treePath)) + } catch (_) { + // New fixture. + fs.writeFileSync(treePath, JSON.stringify(actual, 0, 2) + '\n') + expected = actual + } + + try { + output = fs.readFileSync(outputPath, 'utf8') + } catch (_) { + output = input + } + + st.deepEqual(actual, expected, 'tree') + st.equal(String(proc.processSync(file)), output, 'process') + + st.end() + }) + } +}) diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..6de6595 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,11 @@ +// TypeScript Version: 3.4 + +import {Plugin} from 'unified' + +declare namespace remarkDirective { + type Directive = Plugin<[]> +} + +declare const remarkDirective: remarkDirective.Directive + +export = remarkDirective diff --git a/types/test.ts b/types/test.ts new file mode 100644 index 0000000..7edb336 --- /dev/null +++ b/types/test.ts @@ -0,0 +1,7 @@ +import unified = require('unified') +import directive = require('remark-directive') + +unified().use(directive) +unified().use(directive) + +unified().use(directive, {weird: true}) // $ExpectError diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 0000000..5e24fcf --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "lib": ["es2015"], + "strict": true, + "baseUrl": ".", + "paths": { + "remark-directive": ["index.d.ts"] + } + } +} diff --git a/types/tslint.json b/types/tslint.json new file mode 100644 index 0000000..70c4494 --- /dev/null +++ b/types/tslint.json @@ -0,0 +1,7 @@ +{ + "extends": "dtslint/dtslint.json", + "rules": { + "semicolon": false, + "whitespace": false + } +}