Compare commits
No commits in common. "main" and "1.0.0" have entirely different histories.
21 changed files with 280 additions and 725 deletions
|
@ -1,9 +1,9 @@
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = true
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
13
.github/workflows/bb.yml
vendored
13
.github/workflows/bb.yml
vendored
|
@ -1,13 +0,0 @@
|
||||||
jobs:
|
|
||||||
main:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: unifiedjs/beep-boop-beta@main
|
|
||||||
with:
|
|
||||||
repo-token: ${{secrets.GITHUB_TOKEN}}
|
|
||||||
name: bb
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [closed, edited, labeled, opened, reopened, unlabeled]
|
|
||||||
pull_request_target:
|
|
||||||
types: [closed, edited, labeled, opened, reopened, unlabeled]
|
|
21
.github/workflows/main.yml
vendored
21
.github/workflows/main.yml
vendored
|
@ -1,21 +0,0 @@
|
||||||
jobs:
|
|
||||||
main:
|
|
||||||
name: ${{matrix.node}}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{matrix.node}}
|
|
||||||
- run: npm install
|
|
||||||
- run: npm test
|
|
||||||
- uses: codecov/codecov-action@v5
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node:
|
|
||||||
- lts/hydrogen
|
|
||||||
- node
|
|
||||||
name: main
|
|
||||||
on:
|
|
||||||
- pull_request
|
|
||||||
- push
|
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,9 +1,6 @@
|
||||||
*.d.ts
|
|
||||||
*.log
|
|
||||||
*.map
|
|
||||||
*.tsbuildinfo
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
.nyc_output/
|
||||||
coverage/
|
coverage/
|
||||||
node_modules/
|
node_modules/
|
||||||
yarn.lock
|
yarn.lock
|
||||||
!/index.d.ts
|
|
||||||
|
|
1
.npmrc
1
.npmrc
|
@ -1,2 +1 @@
|
||||||
ignore-scripts=true
|
|
||||||
package-lock=false
|
package-lock=false
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
*.md
|
|
||||||
coverage/
|
coverage/
|
||||||
|
*.json
|
||||||
|
*.md
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
test/fixtures/
|
|
5
.travis.yml
Normal file
5
.travis.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- lts/dubnium
|
||||||
|
- node
|
||||||
|
after_script: bash <(curl -s https://codecov.io/bash)
|
15
index.d.ts
vendored
15
index.d.ts
vendored
|
@ -1,15 +0,0 @@
|
||||||
import type {ToMarkdownOptions} from 'mdast-util-directive'
|
|
||||||
|
|
||||||
export {default} from './lib/index.js'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration for `remark-directive`.
|
|
||||||
*
|
|
||||||
* Currently supports
|
|
||||||
* `collapseEmptyAttributes`,
|
|
||||||
* `preferShortcut`,
|
|
||||||
* `preferUnquoted`,
|
|
||||||
* `quoteSmart`,
|
|
||||||
* and `quote` as serialization options.
|
|
||||||
*/
|
|
||||||
export interface Options extends ToMarkdownOptions {}
|
|
41
index.js
41
index.js
|
@ -1,2 +1,39 @@
|
||||||
// Note: types exposed from `index.d.ts`.
|
'use strict'
|
||||||
export {default} from './lib/index.js'
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
lib/index.js
38
lib/index.js
|
@ -1,38 +0,0 @@
|
||||||
/**
|
|
||||||
* @import {} from 'mdast-util-directive'
|
|
||||||
* @import {Root} from 'mdast'
|
|
||||||
* @import {} from 'remark-arse'
|
|
||||||
* @import {} from 'remark-stringify'
|
|
||||||
* @import {Processor} from 'unified'
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {
|
|
||||||
directiveFromMarkdown,
|
|
||||||
directiveToMarkdown,
|
|
||||||
} from "mdast-util-directive";
|
|
||||||
import { directive } from "micromark-extension-directive";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add support for generic directives.
|
|
||||||
*
|
|
||||||
* ###### Notes
|
|
||||||
*
|
|
||||||
* Doesn’t handle the directives: create your own plugin to do that.
|
|
||||||
*
|
|
||||||
* @returns {undefined}
|
|
||||||
* Nothing.
|
|
||||||
*/
|
|
||||||
export default function remarkDirective() {
|
|
||||||
const data = this.data();
|
|
||||||
|
|
||||||
const micromarkExtensions =
|
|
||||||
data.micromarkExtensions || (data.micromarkExtensions = []);
|
|
||||||
const fromMarkdownExtensions =
|
|
||||||
data.fromMarkdownExtensions || (data.fromMarkdownExtensions = []);
|
|
||||||
const toMarkdownExtensions =
|
|
||||||
data.toMarkdownExtensions || (data.toMarkdownExtensions = []);
|
|
||||||
|
|
||||||
micromarkExtensions.push(directive());
|
|
||||||
fromMarkdownExtensions.push(directiveFromMarkdown());
|
|
||||||
toMarkdownExtensions.push(directiveToMarkdown());
|
|
||||||
}
|
|
2
license
2
license
|
@ -1,6 +1,6 @@
|
||||||
(The MIT License)
|
(The MIT License)
|
||||||
|
|
||||||
Copyright (c) Titus Wormer <tituswormer@gmail.com>
|
Copyright (c) 2020 Titus Wormer <tituswormer@gmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
186
package.json
186
package.json
|
@ -1,106 +1,84 @@
|
||||||
{
|
{
|
||||||
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
|
"name": "remark-directive",
|
||||||
"bugs": "https://github.com/remarkjs/remark-directive/issues",
|
"version": "1.0.0",
|
||||||
"contributors": ["Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"],
|
"description": "remark plugin to support directives",
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"@types/mdast": "^4.0.0",
|
"keywords": [
|
||||||
"mdast-util-directive": "^3.0.0",
|
"unified",
|
||||||
"micromark-extension-directive": "git+https://git.v-sli.me/HidemaruOwO/micromark-extension-directive.git#fix.1",
|
"remark",
|
||||||
"unified": "^11.0.0"
|
"remark-plugin",
|
||||||
},
|
"plugin",
|
||||||
"description": "remark plugin to support directives",
|
"mdast",
|
||||||
"devDependencies": {
|
"markdown",
|
||||||
"@types/node": "^22.0.0",
|
"generic",
|
||||||
"c8": "^10.0.0",
|
"directive",
|
||||||
"is-hidden": "^2.0.0",
|
"container"
|
||||||
"prettier": "^3.0.0",
|
],
|
||||||
"remark": "^15.0.0",
|
"repository": "remarkjs/remark-directive",
|
||||||
"remark-cli": "^12.0.0",
|
"bugs": "https://github.com/remarkjs/remark-directive/issues",
|
||||||
"remark-preset-wooorm": "^10.0.0",
|
"funding": {
|
||||||
"to-vfile": "^8.0.0",
|
"type": "opencollective",
|
||||||
"type-coverage": "^2.0.0",
|
"url": "https://opencollective.com/unified"
|
||||||
"typescript": "^5.0.0",
|
},
|
||||||
"xo": "^0.60.0"
|
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
|
||||||
},
|
"contributors": [
|
||||||
"exports": "./index.js",
|
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
|
||||||
"files": ["index.d.ts", "index.js", "lib/"],
|
],
|
||||||
"funding": {
|
"types": "types/index.d.ts",
|
||||||
"type": "opencollective",
|
"files": [
|
||||||
"url": "https://opencollective.com/unified"
|
"types/index.d.ts",
|
||||||
},
|
"index.js"
|
||||||
"keywords": [
|
],
|
||||||
"container",
|
"dependencies": {
|
||||||
"directive",
|
"mdast-util-directive": "^1.0.0",
|
||||||
"generic",
|
"micromark-extension-directive": "^1.0.0"
|
||||||
"markdown",
|
},
|
||||||
"mdast",
|
"devDependencies": {
|
||||||
"plugin",
|
"dtslint": "^4.0.0",
|
||||||
"remark-plugin",
|
"is-hidden": "^1.0.0",
|
||||||
"remark",
|
"not": "^0.1.0",
|
||||||
"unified"
|
"nyc": "^15.0.0",
|
||||||
],
|
"prettier": "^2.0.0",
|
||||||
"license": "MIT",
|
"remark": "^13.0.0",
|
||||||
"name": "remark-directive",
|
"remark-cli": "^9.0.0",
|
||||||
"prettier": {
|
"remark-preset-wooorm": "^8.0.0",
|
||||||
"bracketSpacing": false,
|
"tape": "^5.0.0",
|
||||||
"singleQuote": true,
|
"to-vfile": "^6.0.0",
|
||||||
"semi": false,
|
"unified": "^9.0.0",
|
||||||
"tabWidth": 2,
|
"xo": "^0.34.0"
|
||||||
"trailingComma": "none",
|
},
|
||||||
"useTabs": false
|
"scripts": {
|
||||||
},
|
"format": "remark . -qfo --ignore-pattern test/ && prettier . -w --loglevel warn && xo --fix",
|
||||||
"remarkConfig": {
|
"test-api": "node test",
|
||||||
"plugins": ["remark-preset-wooorm"]
|
"test-coverage": "nyc --reporter lcov tape test/index.js",
|
||||||
},
|
"test-types": "dtslint types",
|
||||||
"repository": "remarkjs/remark-directive",
|
"test": "npm run format && npm run test-coverage && npm run test-types"
|
||||||
"scripts": {
|
},
|
||||||
"build": "tsc --build --clean && tsc --build && type-coverage",
|
"nyc": {
|
||||||
"format": "remark --frail --output --quiet -- . && prettier --log-level warn --write -- . && xo --fix",
|
"check-coverage": true,
|
||||||
"prepack": "npm run build && npm run format",
|
"lines": 100,
|
||||||
"test-api": "node --conditions development test/index.js",
|
"functions": 100,
|
||||||
"test-coverage": "c8 --100 --reporter lcov -- npm run test-api",
|
"branches": 100
|
||||||
"test": "npm run build && npm run format && npm run test-coverage"
|
},
|
||||||
},
|
"prettier": {
|
||||||
"sideEffects": false,
|
"tabWidth": 2,
|
||||||
"typeCoverage": {
|
"useTabs": false,
|
||||||
"atLeast": 100,
|
"singleQuote": true,
|
||||||
"strict": true
|
"bracketSpacing": false,
|
||||||
},
|
"semi": false,
|
||||||
"type": "module",
|
"trailingComma": "none"
|
||||||
"version": "3.0.1",
|
},
|
||||||
"xo": {
|
"xo": {
|
||||||
"overrides": [
|
"prettier": true,
|
||||||
{
|
"esnext": false,
|
||||||
"files": ["**/*.d.ts"],
|
"rules": {
|
||||||
"rules": {
|
"unicorn/no-fn-reference-in-iterator": "off",
|
||||||
"@typescript-eslint/array-type": [
|
"unicorn/prefer-optional-catch-binding": "off"
|
||||||
"error",
|
}
|
||||||
{
|
},
|
||||||
"default": "generic"
|
"remarkConfig": {
|
||||||
}
|
"plugins": [
|
||||||
],
|
"preset-wooorm"
|
||||||
"@typescript-eslint/ban-types": [
|
]
|
||||||
"error",
|
}
|
||||||
{
|
|
||||||
"extendDefaults": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/consistent-type-definitions": [
|
|
||||||
"error",
|
|
||||||
"interface"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": ["test/**/*.js"],
|
|
||||||
"rules": {
|
|
||||||
"no-await-in-loop": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"prettier": true,
|
|
||||||
"rules": {
|
|
||||||
"logical-assignment-operators": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
502
readme.md
502
readme.md
|
@ -8,448 +8,86 @@
|
||||||
[![Backers][backers-badge]][collective]
|
[![Backers][backers-badge]][collective]
|
||||||
[![Chat][chat-badge]][chat]
|
[![Chat][chat-badge]][chat]
|
||||||
|
|
||||||
**[remark][]** plugin to support the [generic directives
|
[**remark**][remark] plugin to support the [generic directives proposal][prop]
|
||||||
proposal][commonmark-prop] (`:cite[smith04]`,
|
(`:cite[smith04]`, `::youtube[Video of a cat in a box]{v=01ab2cd3efg}`, and
|
||||||
`::youtube[Video of a cat in a box]{v=01ab2cd3efg}`, and such).
|
such).
|
||||||
|
|
||||||
## Contents
|
## Important!
|
||||||
|
|
||||||
* [What is this?](#what-is-this)
|
This plugin is made for the new parser in remark
|
||||||
* [When should I use this?](#when-should-i-use-this)
|
([`micromark`](https://github.com/micromark/micromark),
|
||||||
* [Install](#install)
|
see [`remarkjs/remark#536`](https://github.com/remarkjs/remark/pull/536)).
|
||||||
* [Use](#use)
|
Use this plugin for remark 13+.
|
||||||
* [API](#api)
|
|
||||||
* [`unified().use(remarkDirective[, options])`](#unifieduseremarkdirective-options)
|
|
||||||
* [`Options`](#options)
|
|
||||||
* [Examples](#examples)
|
|
||||||
* [Example: YouTube](#example-youtube)
|
|
||||||
* [Example: Styled blocks](#example-styled-blocks)
|
|
||||||
* [Authoring](#authoring)
|
|
||||||
* [HTML](#html)
|
|
||||||
* [CSS](#css)
|
|
||||||
* [Syntax](#syntax)
|
|
||||||
* [Syntax tree](#syntax-tree)
|
|
||||||
* [Types](#types)
|
|
||||||
* [Compatibility](#compatibility)
|
|
||||||
* [Security](#security)
|
|
||||||
* [Related](#related)
|
|
||||||
* [Contribute](#contribute)
|
|
||||||
* [License](#license)
|
|
||||||
|
|
||||||
## What is this?
|
|
||||||
|
|
||||||
This package is a [unified][] ([remark][]) plugin to add support for directives:
|
|
||||||
one syntax for arbitrary extensions in markdown.
|
|
||||||
|
|
||||||
## When should I use this?
|
|
||||||
|
|
||||||
Directives are one of the four ways to extend markdown: an arbitrary extension
|
|
||||||
syntax (see [Extending markdown][micromark-extending-markdown] in micromark’s
|
|
||||||
docs for the alternatives and more info).
|
|
||||||
This mechanism works well when you control the content: who authors it, what
|
|
||||||
tools handle it, and where it’s displayed.
|
|
||||||
When authors can read a guide on how to embed a tweet but are not expected to
|
|
||||||
know the ins and outs of HTML or JavaScript.
|
|
||||||
Directives don’t work well if you don’t know who authors content, what tools
|
|
||||||
handle it, and where it ends up.
|
|
||||||
Example use cases are a docs website for a project or product, or blogging
|
|
||||||
tools and static site generators.
|
|
||||||
|
|
||||||
If you *just* want to turn markdown into HTML (with maybe a few extensions such
|
|
||||||
as this one), we recommend [`micromark`][micromark] with
|
|
||||||
[`micromark-extension-directive`][micromark-extension-directive] instead.
|
|
||||||
If you don’t use plugins and want to access the syntax tree, you can use
|
|
||||||
[`mdast-util-from-markdown`][mdast-util-from-markdown] with
|
|
||||||
[`mdast-util-directive`][mdast-util-directive].
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
This package is [ESM only][esm].
|
[npm][]:
|
||||||
In Node.js (version 16+), install with [npm][]:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install remark-directive
|
npm install remark-directive
|
||||||
```
|
```
|
||||||
|
|
||||||
In Deno with [`esm.sh`][esmsh]:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import remarkDirective from 'https://esm.sh/remark-directive@3'
|
|
||||||
```
|
|
||||||
|
|
||||||
In browsers with [`esm.sh`][esmsh]:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script type="module">
|
|
||||||
import remarkDirective from 'https://esm.sh/remark-directive@3?bundle'
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
Say our document `example.md` contains:
|
Say we have the following file, `example.md`:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
:::main{#readme}
|
|
||||||
|
|
||||||
Lorem:br
|
|
||||||
ipsum.
|
|
||||||
|
|
||||||
::hr{.red}
|
|
||||||
|
|
||||||
A :i[lovely] language know as :abbr[HTML]{title="HyperText Markup Language"}.
|
|
||||||
|
|
||||||
:::
|
|
||||||
```
|
```
|
||||||
|
|
||||||
…and our module `example.js` contains:
|
And our script, `example.js`, looks as follows:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
var vfile = require('to-vfile')
|
||||||
* @import {} from 'mdast-util-directive'
|
var report = require('vfile-reporter')
|
||||||
* @import {} from 'mdast-util-to-hast'
|
var unified = require('unified')
|
||||||
* @import {Root} from 'mdast'
|
var parse = require('remark-parse')
|
||||||
*/
|
var directive = require('remark-directive')
|
||||||
|
var stringify = require('rehype-stringify')
|
||||||
|
|
||||||
import {h} from 'hastscript'
|
unified()
|
||||||
import rehypeFormat from 'rehype-format'
|
.use(parse)
|
||||||
import rehypeStringify from 'rehype-stringify'
|
.use(directive)
|
||||||
import remarkDirective from 'remark-directive'
|
.use(remark2rehype)
|
||||||
import remarkParse from 'remark-parse'
|
.use(stringify)
|
||||||
import remarkRehype from 'remark-rehype'
|
.process(vfile.readSync('example.md'), function (err, file) {
|
||||||
import {read} from 'to-vfile'
|
console.error(report(err || file))
|
||||||
import {unified} from 'unified'
|
console.log(String(file))
|
||||||
import {visit} from 'unist-util-visit'
|
})
|
||||||
|
|
||||||
const file = await unified()
|
|
||||||
.use(remarkParse)
|
|
||||||
.use(remarkDirective)
|
|
||||||
.use(myRemarkPlugin)
|
|
||||||
.use(remarkRehype)
|
|
||||||
.use(rehypeFormat)
|
|
||||||
.use(rehypeStringify)
|
|
||||||
.process(await read('example.md'))
|
|
||||||
|
|
||||||
console.log(String(file))
|
|
||||||
|
|
||||||
// This plugin is an example to let users write HTML with directives.
|
|
||||||
// It’s informative but rather useless.
|
|
||||||
// See below for others examples.
|
|
||||||
function myRemarkPlugin() {
|
|
||||||
/**
|
|
||||||
* @param {Root} tree
|
|
||||||
* Tree.
|
|
||||||
* @returns {undefined}
|
|
||||||
* Nothing.
|
|
||||||
*/
|
|
||||||
return function (tree) {
|
|
||||||
visit(tree, function (node) {
|
|
||||||
if (
|
|
||||||
node.type === 'containerDirective' ||
|
|
||||||
node.type === 'leafDirective' ||
|
|
||||||
node.type === 'textDirective'
|
|
||||||
) {
|
|
||||||
const data = node.data || (node.data = {})
|
|
||||||
const hast = h(node.name, node.attributes || {})
|
|
||||||
|
|
||||||
data.hName = hast.tagName
|
|
||||||
data.hProperties = hast.properties
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
…then running `node example.js` yields:
|
Now, running `node example` yields:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<main id="readme">
|
|
||||||
<p>Lorem<br>ipsum.</p>
|
|
||||||
<hr class="red">
|
|
||||||
<p>A <i>lovely</i> language know as <abbr title="HyperText Markup Language">HTML</abbr>.</p>
|
|
||||||
</main>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
This package exports no identifiers.
|
### `remark().use(directive)`
|
||||||
The default export is [`remarkDirective`][api-remark-directive].
|
|
||||||
|
|
||||||
### `unified().use(remarkDirective[, options])`
|
Configures remark so that it can parse and serialize directives.
|
||||||
|
Doesn’t handle the directives: [create your own plugin][create-plugin] to do
|
||||||
Add support for generic directives.
|
that.
|
||||||
|
See the [micromark extension for the syntax][syntax] and the
|
||||||
###### Parameters
|
[mdast utility for the syntax tree][syntax-tree].
|
||||||
|
|
||||||
* `options` ([`Options`][api-options], optional)
|
|
||||||
— configuration
|
|
||||||
|
|
||||||
###### Returns
|
|
||||||
|
|
||||||
Nothing (`undefined`).
|
|
||||||
|
|
||||||
###### Notes
|
|
||||||
|
|
||||||
Doesn’t handle the directives:
|
|
||||||
[create your own plugin][unified-create-plugin] to do that.
|
|
||||||
|
|
||||||
### `Options`
|
|
||||||
|
|
||||||
Configuration (TypeScript type).
|
|
||||||
|
|
||||||
###### Fields
|
|
||||||
|
|
||||||
* `collapseEmptyAttributes`
|
|
||||||
(`boolean`, default: `true`)
|
|
||||||
— collapse empty attributes: get `title` instead of `title=""`
|
|
||||||
* `preferShortcut`
|
|
||||||
(`boolean`, default: `true`)
|
|
||||||
— prefer `#` and `.` shortcuts for `id` and `class`
|
|
||||||
* `preferUnquoted`
|
|
||||||
(`boolean`, default: `false`)
|
|
||||||
— leave attributes unquoted if that results in less bytes
|
|
||||||
* `quoteSmart`
|
|
||||||
(`boolean`, default: `false`)
|
|
||||||
— use the other quote if that results in less bytes
|
|
||||||
* `quote`
|
|
||||||
(`'"'` or `"'"`,
|
|
||||||
default: the [`quote`][quote] used by `remark-stringify` for titles)
|
|
||||||
— preferred quote to use around attribute values
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Example: YouTube
|
|
||||||
|
|
||||||
This example shows how directives can be used for YouTube embeds.
|
|
||||||
It’s based on the example in Use above.
|
|
||||||
If `myRemarkPlugin` was replaced with this function:
|
|
||||||
|
|
||||||
```js
|
|
||||||
/**
|
|
||||||
* @import {} from 'mdast-util-directive'
|
|
||||||
* @import {} from 'mdast-util-to-hast'
|
|
||||||
* @import {Root} from 'mdast'
|
|
||||||
* @import {VFile} from 'vfile'
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {visit} from 'unist-util-visit'
|
|
||||||
|
|
||||||
// This plugin is an example to turn `::youtube` into iframes.
|
|
||||||
function myRemarkPlugin() {
|
|
||||||
/**
|
|
||||||
* @param {Root} tree
|
|
||||||
* Tree.
|
|
||||||
* @param {VFile} file
|
|
||||||
* File.
|
|
||||||
* @returns {undefined}
|
|
||||||
* Nothing.
|
|
||||||
*/
|
|
||||||
return (tree, file) => {
|
|
||||||
visit(tree, function (node) {
|
|
||||||
if (
|
|
||||||
node.type === 'containerDirective' ||
|
|
||||||
node.type === 'leafDirective' ||
|
|
||||||
node.type === 'textDirective'
|
|
||||||
) {
|
|
||||||
if (node.name !== 'youtube') return
|
|
||||||
|
|
||||||
const data = node.data || (node.data = {})
|
|
||||||
const attributes = node.attributes || {}
|
|
||||||
const id = attributes.id
|
|
||||||
|
|
||||||
if (node.type === 'textDirective') {
|
|
||||||
file.fail(
|
|
||||||
'Unexpected `:youtube` text directive, use two colons for a leaf directive',
|
|
||||||
node
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
file.fail('Unexpected missing `id` on `youtube` directive', node)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.hName = 'iframe'
|
|
||||||
data.hProperties = {
|
|
||||||
src: 'https://www.youtube.com/embed/' + id,
|
|
||||||
width: 200,
|
|
||||||
height: 200,
|
|
||||||
frameBorder: 0,
|
|
||||||
allow: 'picture-in-picture',
|
|
||||||
allowFullScreen: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
…and `example.md` contains:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Cat videos
|
|
||||||
|
|
||||||
::youtube[Video of a cat in a box]{#01ab2cd3efg}
|
|
||||||
```
|
|
||||||
|
|
||||||
…then running `node example.js` yields:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<h1>Cat videos</h1>
|
|
||||||
<iframe src="https://www.youtube.com/embed/01ab2cd3efg" width="200" height="200" frameborder="0" allow="picture-in-picture" allowfullscreen>Video of a cat in a box</iframe>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example: Styled blocks
|
|
||||||
|
|
||||||
> 👉 **Note**: This is sometimes called admonitions, callouts, etc.
|
|
||||||
|
|
||||||
This example shows how directives can be used to style blocks.
|
|
||||||
It’s based on the example in Use above.
|
|
||||||
If `myRemarkPlugin` was replaced with this function:
|
|
||||||
|
|
||||||
```js
|
|
||||||
/**
|
|
||||||
* @import {} from 'mdast-util-directive'
|
|
||||||
* @import {} from 'mdast-util-to-hast'
|
|
||||||
* @import {Root} from 'mdast'
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {h} from 'hastscript'
|
|
||||||
import {visit} from 'unist-util-visit'
|
|
||||||
|
|
||||||
// This plugin is an example to turn `::note` into divs, passing arbitrary
|
|
||||||
// attributes.
|
|
||||||
function myRemarkPlugin() {
|
|
||||||
/**
|
|
||||||
* @param {Root} tree
|
|
||||||
* Tree.
|
|
||||||
* @returns {undefined}
|
|
||||||
* Nothing.
|
|
||||||
*/
|
|
||||||
return (tree) => {
|
|
||||||
visit(tree, (node) => {
|
|
||||||
if (
|
|
||||||
node.type === 'containerDirective' ||
|
|
||||||
node.type === 'leafDirective' ||
|
|
||||||
node.type === 'textDirective'
|
|
||||||
) {
|
|
||||||
if (node.name !== 'note') return
|
|
||||||
|
|
||||||
const data = node.data || (node.data = {})
|
|
||||||
const tagName = node.type === 'textDirective' ? 'span' : 'div'
|
|
||||||
|
|
||||||
data.hName = tagName
|
|
||||||
data.hProperties = h(tagName, node.attributes || {}).properties
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
…and `example.md` contains:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# How to use xxx
|
|
||||||
|
|
||||||
You can use xxx.
|
|
||||||
|
|
||||||
:::note{.warning}
|
|
||||||
if you chose xxx, you should also use yyy somewhere…
|
|
||||||
:::
|
|
||||||
```
|
|
||||||
|
|
||||||
…then running `node example` yields:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<h1>How to use xxx</h1>
|
|
||||||
<p>You can use xxx.</p>
|
|
||||||
<div class="warning">
|
|
||||||
<p>if you chose xxx, you should also use yyy somewhere…</p>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Authoring
|
|
||||||
|
|
||||||
When authoring markdown with directives, keep in mind that they don’t work in
|
|
||||||
most places.
|
|
||||||
On your own site it can be great!
|
|
||||||
|
|
||||||
## HTML
|
|
||||||
|
|
||||||
You can define how directives are turned into HTML.
|
|
||||||
If directives are not handled, they do not emit anything.
|
|
||||||
|
|
||||||
## CSS
|
|
||||||
|
|
||||||
How to display directives is left as an exercise for the reader.
|
|
||||||
|
|
||||||
## Syntax
|
|
||||||
|
|
||||||
See [*Syntax* in
|
|
||||||
`micromark-extension-directive`](https://github.com/micromark/micromark-extension-directive#syntax).
|
|
||||||
|
|
||||||
## Syntax tree
|
|
||||||
|
|
||||||
See [*Syntax tree* in
|
|
||||||
`mdast-util-directive`](https://github.com/syntax-tree/mdast-util-directive#syntax-tree).
|
|
||||||
|
|
||||||
## Types
|
|
||||||
|
|
||||||
This package is fully typed with [TypeScript][].
|
|
||||||
It exports no additional options.
|
|
||||||
|
|
||||||
If you’re working with the syntax tree, you can register the new node types
|
|
||||||
with `@types/mdast` by adding a reference:
|
|
||||||
|
|
||||||
```js
|
|
||||||
/**
|
|
||||||
* @import {} from 'mdast-util-directive'
|
|
||||||
* @import {Root} from 'mdast'
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {visit} from 'unist-util-visit'
|
|
||||||
|
|
||||||
function myRemarkPlugin() {
|
|
||||||
/**
|
|
||||||
* @param {Root} tree
|
|
||||||
* Tree.
|
|
||||||
* @returns {undefined}
|
|
||||||
* Nothing.
|
|
||||||
*/
|
|
||||||
return (tree) => {
|
|
||||||
visit(tree, function (node) {
|
|
||||||
console.log(node) // `node` can now be one of the nodes for directives.
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compatibility
|
|
||||||
|
|
||||||
Projects maintained by the unified collective are compatible with maintained
|
|
||||||
versions of Node.js.
|
|
||||||
|
|
||||||
When we cut a new major release, we drop support for unmaintained versions of
|
|
||||||
Node.
|
|
||||||
This means we try to keep the current release line, `remark-directive@^3`,
|
|
||||||
compatible with Node.js 16.
|
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
Use of `remark-directive` does not involve **[rehype][]** ([hast][]) or user
|
Use of `remark-directive` does not involve [**rehype**][rehype]
|
||||||
content so there are no openings for [cross-site scripting (XSS)][wiki-xss]
|
([**hast**][hast]) or user content so there are no openings for [cross-site
|
||||||
attacks.
|
scripting (XSS)][xss] attacks.
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
* [`remark-gfm`](https://github.com/remarkjs/remark-gfm)
|
* [`remark-gfm`](https://github.com/remarkjs/remark-gfm)
|
||||||
— support GFM (autolink literals, footnotes, strikethrough, tables,
|
— GFM
|
||||||
tasklists)
|
* [`remark-github`](https://github.com/remarkjs/remark-github)
|
||||||
* [`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter)
|
— Autolink references like in GitHub issues, PRs, and comments
|
||||||
— support frontmatter (YAML, TOML, and more)
|
* [`remark-footnotes`](https://github.com/remarkjs/remark-footnotes)
|
||||||
* [`remark-math`](https://github.com/remarkjs/remark-math)
|
— Footnotes
|
||||||
— support math
|
* [`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter)
|
||||||
* [`remark-mdx`](https://github.com/mdx-js/mdx/tree/main/packages/remark-mdx)
|
— Frontmatter (YAML, TOML, and more)
|
||||||
— support MDX (ESM, JSX, expressions)
|
* [`remark-math`](https://github.com/remarkjs/remark-math)
|
||||||
|
— Math
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
|
@ -467,9 +105,9 @@ abide by its terms.
|
||||||
|
|
||||||
<!-- Definitions -->
|
<!-- Definitions -->
|
||||||
|
|
||||||
[build-badge]: https://github.com/remarkjs/remark-directive/workflows/main/badge.svg
|
[build-badge]: https://img.shields.io/travis/remarkjs/remark-directive/main.svg
|
||||||
|
|
||||||
[build]: https://github.com/remarkjs/remark-directive/actions
|
[build]: https://travis-ci.org/remarkjs/remark-directive
|
||||||
|
|
||||||
[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark-directive.svg
|
[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark-directive.svg
|
||||||
|
|
||||||
|
@ -479,9 +117,9 @@ abide by its terms.
|
||||||
|
|
||||||
[downloads]: https://www.npmjs.com/package/remark-directive
|
[downloads]: https://www.npmjs.com/package/remark-directive
|
||||||
|
|
||||||
[size-badge]: https://img.shields.io/bundlejs/size/remark-directive
|
[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-directive.svg
|
||||||
|
|
||||||
[size]: https://bundlejs.com/?q=remark-directive
|
[size]: https://bundlephobia.com/result?p=remark-directive
|
||||||
|
|
||||||
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
|
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
|
||||||
|
|
||||||
|
@ -495,50 +133,30 @@ abide by its terms.
|
||||||
|
|
||||||
[npm]: https://docs.npmjs.com/cli/install
|
[npm]: https://docs.npmjs.com/cli/install
|
||||||
|
|
||||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
|
||||||
|
|
||||||
[esmsh]: https://esm.sh
|
|
||||||
|
|
||||||
[health]: https://github.com/remarkjs/.github
|
[health]: https://github.com/remarkjs/.github
|
||||||
|
|
||||||
[contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md
|
[contributing]: https://github.com/remarkjs/.github/blob/HEAD/contributing.md
|
||||||
|
|
||||||
[support]: https://github.com/remarkjs/.github/blob/main/support.md
|
[support]: https://github.com/remarkjs/.github/blob/HEAD/support.md
|
||||||
|
|
||||||
[coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md
|
[coc]: https://github.com/remarkjs/.github/blob/HEAD/code-of-conduct.md
|
||||||
|
|
||||||
[license]: license
|
[license]: license
|
||||||
|
|
||||||
[author]: https://wooorm.com
|
[author]: https://wooorm.com
|
||||||
|
|
||||||
[commonmark-prop]: https://talk.commonmark.org/t/generic-directives-plugins-syntax/444
|
[remark]: https://github.com/remarkjs/remark
|
||||||
|
|
||||||
[hast]: https://github.com/syntax-tree/hast
|
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
|
||||||
|
|
||||||
[mdast-util-directive]: https://github.com/syntax-tree/mdast-util-directive
|
|
||||||
|
|
||||||
[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown
|
|
||||||
|
|
||||||
[micromark]: https://github.com/micromark/micromark
|
|
||||||
|
|
||||||
[micromark-extension-directive]: https://github.com/micromark/micromark-extension-directive
|
|
||||||
|
|
||||||
[micromark-extending-markdown]: https://github.com/micromark/micromark#extending-markdown
|
|
||||||
|
|
||||||
[quote]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify#options
|
|
||||||
|
|
||||||
[rehype]: https://github.com/rehypejs/rehype
|
[rehype]: https://github.com/rehypejs/rehype
|
||||||
|
|
||||||
[remark]: https://github.com/remarkjs/remark
|
[hast]: https://github.com/syntax-tree/hast
|
||||||
|
|
||||||
[typescript]: https://www.typescriptlang.org
|
[prop]: https://talk.commonmark.org/t/generic-directives-plugins-syntax/444
|
||||||
|
|
||||||
[unified]: https://github.com/unifiedjs/unified
|
[create-plugin]: https://unifiedjs.com/learn/guide/create-a-plugin/
|
||||||
|
|
||||||
[unified-create-plugin]: https://unifiedjs.com/learn/guide/create-a-plugin/
|
[syntax]: https://github.com/micromark/micromark-extension-directive#syntax
|
||||||
|
|
||||||
[wiki-xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
|
[syntax-tree]: https://github.com/syntax-tree/mdast-util-directive#syntax-tree
|
||||||
|
|
||||||
[api-remark-directive]: #unifieduseremarkdirective-options
|
|
||||||
|
|
||||||
[api-options]: #options
|
|
||||||
|
|
2
test/fixtures/container/output.md
vendored
2
test/fixtures/container/output.md
vendored
|
@ -30,7 +30,7 @@ b
|
||||||
d
|
d
|
||||||
|
|
||||||
:::e
|
:::e
|
||||||
* * f
|
* * f
|
||||||
:::
|
:::
|
||||||
|
|
||||||
> g h
|
> g h
|
||||||
|
|
109
test/index.js
109
test/index.js
|
@ -1,78 +1,67 @@
|
||||||
/**
|
'use strict'
|
||||||
* @typedef {import('mdast').Root} Root
|
|
||||||
*/
|
|
||||||
|
|
||||||
import assert from 'node:assert/strict'
|
var fs = require('fs')
|
||||||
import fs from 'node:fs/promises'
|
var path = require('path')
|
||||||
import process from 'node:process'
|
var test = require('tape')
|
||||||
import test from 'node:test'
|
var vfile = require('to-vfile')
|
||||||
import {isHidden} from 'is-hidden'
|
var unified = require('unified')
|
||||||
import {remark} from 'remark'
|
var remark = require('remark')
|
||||||
import remarkDirective from 'remark-directive'
|
var not = require('not')
|
||||||
|
var hidden = require('is-hidden')
|
||||||
|
var directive = require('..')
|
||||||
|
|
||||||
test('remarkDirective', async function (t) {
|
test('directive()', function (t) {
|
||||||
await t.test('should expose the public api', async function () {
|
t.doesNotThrow(function () {
|
||||||
assert.deepEqual(Object.keys(await import('remark-directive')).sort(), [
|
remark().use(directive).freeze()
|
||||||
'default'
|
}, 'should not throw if not passed options')
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
await t.test('should not throw if not passed options', async function () {
|
t.doesNotThrow(function () {
|
||||||
assert.doesNotThrow(function () {
|
unified().use(directive).freeze()
|
||||||
remark().use(remarkDirective).freeze()
|
}, 'should not throw if without parser or compiler')
|
||||||
})
|
|
||||||
})
|
t.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fixtures', async function (t) {
|
test('fixtures', function (t) {
|
||||||
const base = new URL('fixtures/', import.meta.url)
|
var base = path.join(__dirname, 'fixtures')
|
||||||
const folders = await fs.readdir(base)
|
var entries = fs.readdirSync(base).filter(not(hidden))
|
||||||
|
|
||||||
let index = -1
|
t.plan(entries.length)
|
||||||
|
|
||||||
while (++index < folders.length) {
|
entries.forEach(each)
|
||||||
const folder = folders[index]
|
|
||||||
|
|
||||||
if (isHidden(folder)) continue
|
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
|
||||||
|
|
||||||
await t.test(folder, async function () {
|
proc = remark().use(directive).freeze()
|
||||||
const folderUrl = new URL(folder + '/', base)
|
actual = proc.parse(file)
|
||||||
const inputUrl = new URL('input.md', folderUrl)
|
|
||||||
const outputUrl = new URL('output.md', folderUrl)
|
|
||||||
const treeUrl = new URL('tree.json', folderUrl)
|
|
||||||
|
|
||||||
const input = String(await fs.readFile(inputUrl))
|
|
||||||
|
|
||||||
/** @type {Root} */
|
|
||||||
let expected
|
|
||||||
/** @type {string} */
|
|
||||||
let output
|
|
||||||
|
|
||||||
const processor = remark().use(remarkDirective)
|
|
||||||
const actual = processor.parse(input)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
output = String(await fs.readFile(outputUrl))
|
expected = JSON.parse(fs.readFileSync(treePath))
|
||||||
} catch {
|
} catch (_) {
|
||||||
|
// New fixture.
|
||||||
|
fs.writeFileSync(treePath, JSON.stringify(actual, 0, 2) + '\n')
|
||||||
|
expected = actual
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
output = fs.readFileSync(outputPath, 'utf8')
|
||||||
|
} catch (_) {
|
||||||
output = input
|
output = input
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
st.deepEqual(actual, expected, 'tree')
|
||||||
if ('UPDATE' in process.env) {
|
st.equal(String(proc.processSync(file)), output, 'process')
|
||||||
throw new Error('Updating…')
|
|
||||||
}
|
|
||||||
|
|
||||||
expected = JSON.parse(String(await fs.readFile(treeUrl)))
|
st.end()
|
||||||
} catch {
|
|
||||||
expected = actual
|
|
||||||
|
|
||||||
// New fixture.
|
|
||||||
await fs.writeFile(treeUrl, JSON.stringify(actual, undefined, 2) + '\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.deepEqual(actual, expected)
|
|
||||||
|
|
||||||
assert.equal(String(await processor.process(input)), String(output))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"checkJs": true,
|
|
||||||
"customConditions": ["development"],
|
|
||||||
"declarationMap": true,
|
|
||||||
"declaration": true,
|
|
||||||
"emitDeclarationOnly": true,
|
|
||||||
"exactOptionalPropertyTypes": true,
|
|
||||||
"lib": ["es2022"],
|
|
||||||
"module": "node16",
|
|
||||||
"strict": true,
|
|
||||||
"target": "es2022"
|
|
||||||
},
|
|
||||||
"exclude": ["coverage/", "node_modules/"],
|
|
||||||
"include": ["**/*.js", "index.d.ts"]
|
|
||||||
}
|
|
11
types/index.d.ts
vendored
Normal file
11
types/index.d.ts
vendored
Normal file
|
@ -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
|
7
types/test.ts
Normal file
7
types/test.ts
Normal file
|
@ -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
|
10
types/tsconfig.json
Normal file
10
types/tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["es2015"],
|
||||||
|
"strict": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"remark-directive": ["index.d.ts"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
types/tslint.json
Normal file
7
types/tslint.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"extends": "dtslint/dtslint.json",
|
||||||
|
"rules": {
|
||||||
|
"semicolon": false,
|
||||||
|
"whitespace": false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue