mdast-util-gfm-task-list-item
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -1,15 +0,4 @@ | ||
/** @type {FromMarkdownExtension} */ | ||
export const gfmTaskListItemFromMarkdown: FromMarkdownExtension | ||
/** @type {ToMarkdownExtension} */ | ||
export const gfmTaskListItemToMarkdown: ToMarkdownExtension | ||
export type Parent = Extract< | ||
import('mdast').Root | import('mdast').Content, | ||
import('unist').Parent | ||
> | ||
export type ListItem = import('mdast').ListItem | ||
export type Paragraph = import('mdast').Paragraph | ||
export type BlockContent = import('mdast').BlockContent | ||
export type FromMarkdownExtension = import('mdast-util-from-markdown').Extension | ||
export type FromMarkdownHandle = import('mdast-util-from-markdown').Handle | ||
export type ToMarkdownExtension = import('mdast-util-to-markdown').Options | ||
export type ToMarkdownHandle = import('mdast-util-to-markdown').Handle | ||
export { | ||
gfmTaskListItemFromMarkdown, | ||
gfmTaskListItemToMarkdown | ||
} from './lib/index.js' |
120
index.js
@@ -1,116 +0,4 @@ | ||
/** | ||
* @typedef {Extract<import('mdast').Root|import('mdast').Content, import('unist').Parent>} Parent | ||
* @typedef {import('mdast').ListItem} ListItem | ||
* @typedef {import('mdast').Paragraph} Paragraph | ||
* @typedef {import('mdast').BlockContent} BlockContent | ||
* @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension | ||
* @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle | ||
* @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension | ||
* @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle | ||
*/ | ||
import {listItem} from 'mdast-util-to-markdown/lib/handle/list-item.js' | ||
import {track} from 'mdast-util-to-markdown/lib/util/track.js' | ||
/** @type {FromMarkdownExtension} */ | ||
export const gfmTaskListItemFromMarkdown = { | ||
exit: { | ||
taskListCheckValueChecked: exitCheck, | ||
taskListCheckValueUnchecked: exitCheck, | ||
paragraph: exitParagraphWithTaskListItem | ||
} | ||
} | ||
/** @type {ToMarkdownExtension} */ | ||
export const gfmTaskListItemToMarkdown = { | ||
unsafe: [{atBreak: true, character: '-', after: '[:|-]'}], | ||
handlers: {listItem: listItemWithTaskListItem} | ||
} | ||
/** @type {FromMarkdownHandle} */ | ||
function exitCheck(token) { | ||
const node = /** @type {ListItem} */ (this.stack[this.stack.length - 2]) | ||
// We’re always in a paragraph, in a list item. | ||
node.checked = token.type === 'taskListCheckValueChecked' | ||
} | ||
/** @type {FromMarkdownHandle} */ | ||
function exitParagraphWithTaskListItem(token) { | ||
const parent = /** @type {Parent} */ (this.stack[this.stack.length - 2]) | ||
const node = /** @type {Paragraph} */ (this.stack[this.stack.length - 1]) | ||
const siblings = parent.children | ||
const head = node.children[0] | ||
let index = -1 | ||
/** @type {Paragraph|undefined} */ | ||
let firstParaghraph | ||
if ( | ||
parent && | ||
parent.type === 'listItem' && | ||
typeof parent.checked === 'boolean' && | ||
head && | ||
head.type === 'text' | ||
) { | ||
while (++index < siblings.length) { | ||
const sibling = siblings[index] | ||
if (sibling.type === 'paragraph') { | ||
firstParaghraph = sibling | ||
break | ||
} | ||
} | ||
if (firstParaghraph === node) { | ||
// Must start with a space or a tab. | ||
head.value = head.value.slice(1) | ||
if (head.value.length === 0) { | ||
node.children.shift() | ||
} else if ( | ||
node.position && | ||
head.position && | ||
typeof head.position.start.offset === 'number' | ||
) { | ||
head.position.start.column++ | ||
head.position.start.offset++ | ||
node.position.start = Object.assign({}, head.position.start) | ||
} | ||
} | ||
} | ||
this.exit(token) | ||
} | ||
/** | ||
* @type {ToMarkdownHandle} | ||
* @param {ListItem} node | ||
*/ | ||
function listItemWithTaskListItem(node, parent, context, safeOptions) { | ||
const head = node.children[0] | ||
const checkable = | ||
typeof node.checked === 'boolean' && head && head.type === 'paragraph' | ||
const checkbox = '[' + (node.checked ? 'x' : ' ') + '] ' | ||
const tracker = track(safeOptions) | ||
if (checkable) { | ||
tracker.move(checkbox) | ||
} | ||
let value = listItem(node, parent, context, { | ||
...safeOptions, | ||
...tracker.current() | ||
}) | ||
if (checkable) { | ||
value = value.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/, check) | ||
} | ||
return value | ||
/** | ||
* @param {string} $0 | ||
* @returns {string} | ||
*/ | ||
function check($0) { | ||
return $0 + checkbox | ||
} | ||
} | ||
export { | ||
gfmTaskListItemFromMarkdown, | ||
gfmTaskListItemToMarkdown | ||
} from './lib/index.js' |
{ | ||
"name": "mdast-util-gfm-task-list-item", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "mdast extension to parse and serialize GFM task list items", | ||
@@ -37,2 +37,3 @@ "license": "MIT", | ||
"files": [ | ||
"lib/", | ||
"index.d.ts", | ||
@@ -46,3 +47,3 @@ "index.js" | ||
"devDependencies": { | ||
"@types/tape": "^4.0.0", | ||
"@types/node": "^18.0.0", | ||
"c8": "^7.0.0", | ||
@@ -52,16 +53,15 @@ "mdast-util-from-markdown": "^1.0.0", | ||
"prettier": "^2.0.0", | ||
"remark-cli": "^10.0.0", | ||
"remark-cli": "^11.0.0", | ||
"remark-preset-wooorm": "^9.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"unist-util-remove-position": "^4.0.0", | ||
"xo": "^0.47.0" | ||
"xo": "^0.53.0" | ||
}, | ||
"scripts": { | ||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage", | ||
"prepack": "npm run build && npm run format", | ||
"build": "tsc --build --clean && tsc --build && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"test-api": "node --conditions development test.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --conditions development test.js", | ||
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
@@ -68,0 +68,0 @@ }, |
201
readme.md
@@ -11,22 +11,61 @@ # mdast-util-gfm-task-list-item | ||
Extension for [`mdast-util-from-markdown`][from-markdown] and/or | ||
[`mdast-util-to-markdown`][to-markdown] to support GitHub flavored markdown | ||
task list items in **[mdast][]**. | ||
When parsing (`from-markdown`), must be combined with | ||
[`micromark-extension-gfm-task-list-item`][extension]. | ||
[mdast][] extensions to parse and serialize [GFM][] task list items. | ||
## Contents | ||
* [What is this?](#what-is-this) | ||
* [When to use this](#when-to-use-this) | ||
* [Install](#install) | ||
* [Use](#use) | ||
* [API](#api) | ||
* [`gfmTaskListItemFromMarkdown`](#gfmtasklistitemfrommarkdown) | ||
* [`gfmTaskListItemToMarkdown`](#gfmtasklistitemtomarkdown) | ||
* [HTML](#html) | ||
* [Syntax](#syntax) | ||
* [Syntax tree](#syntax-tree) | ||
* [Nodes](#nodes) | ||
* [Content model](#content-model) | ||
* [Types](#types) | ||
* [Compatibility](#compatibility) | ||
* [Related](#related) | ||
* [Contribute](#contribute) | ||
* [License](#license) | ||
## What is this? | ||
This package contains two extensions that add support for GFM task list item | ||
syntax in markdown to [mdast][]. | ||
These extensions plug into | ||
[`mdast-util-from-markdown`][mdast-util-from-markdown] (to support parsing | ||
task lists in markdown into a syntax tree) and | ||
[`mdast-util-to-markdown`][mdast-util-to-markdown] (to support serializing | ||
task lists in syntax trees to markdown). | ||
## When to use this | ||
Use this if you’re dealing with the AST manually. | ||
It’s might be better to use [`remark-gfm`][remark-gfm] with **[remark][]**, | ||
which includes this but provides a nicer interface and makes it easier to | ||
combine with hundreds of plugins. | ||
You can use these extensions when you are working with | ||
`mdast-util-from-markdown` and `mdast-util-to-markdown` already. | ||
When working with `mdast-util-from-markdown`, you must combine this package | ||
with | ||
[`micromark-extension-gfm-task-list-item`][extension]. | ||
When you don’t need a syntax tree, you can use [`micromark`][micromark] | ||
directly with `micromark-extension-gfm-task-list-item`. | ||
When you are working with syntax trees and want all of GFM, use | ||
[`mdast-util-gfm`][mdast-util-gfm] instead. | ||
All these packages are used [`remark-gfm`][remark-gfm], which | ||
focusses on making it easier to transform content by abstracting these | ||
internals away. | ||
This utility does not handle how markdown is turned to HTML. | ||
That’s done by [`mdast-util-to-hast`][mdast-util-to-hast]. | ||
## 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. | ||
This package is [ESM only][esm]. | ||
In Node.js (version 14.14+ and 16.0+), install with [npm][]: | ||
[npm][]: | ||
```sh | ||
@@ -36,5 +75,19 @@ npm install mdast-util-gfm-task-list-item | ||
In Deno with [`esm.sh`][esmsh]: | ||
```js | ||
import {gfmTaskListItemFromMarkdown, gfmTaskListItemToMarkdown} from 'https://esm.sh/mdast-util-gfm-task-list-item@1' | ||
``` | ||
In browsers with [`esm.sh`][esmsh]: | ||
```html | ||
<script type="module"> | ||
import {gfmTaskListItemFromMarkdown, gfmTaskListItemToMarkdown} from 'https://esm.sh/mdast-util-gfm-task-list-item@1?bundle' | ||
</script> | ||
``` | ||
## Use | ||
Say we have the following file, `example.md`: | ||
Say our document `example.md` contains: | ||
@@ -49,6 +102,6 @@ ```markdown | ||
And our module, `example.js`, looks as follows: | ||
…and our module `example.js` looks as follows: | ||
```js | ||
import fs from 'node:fs' | ||
import fs from 'node:fs/promises' | ||
import {fromMarkdown} from 'mdast-util-from-markdown' | ||
@@ -59,3 +112,3 @@ import {toMarkdown} from 'mdast-util-to-markdown' | ||
const doc = fs.readFileSync('example.md') | ||
const doc = await fs.readFile('example.md') | ||
@@ -74,4 +127,3 @@ const tree = fromMarkdown(doc, { | ||
Now, running `node example` yields (positional info removed for the sake of | ||
brevity): | ||
…now running `node example.js` yields (positional info removed for brevity): | ||
@@ -144,4 +196,5 @@ ```js | ||
This package exports the following identifier: `gfmTaskListItemFromMarkdown`, | ||
`gfmTaskListItemToMarkdown`. | ||
This package exports the identifiers | ||
[`gfmTaskListItemFromMarkdown`][api-gfmtasklistitemfrommarkdown] and | ||
[`gfmTaskListItemToMarkdown`][api-gfmtasklistitemtomarkdown]. | ||
There is no default export. | ||
@@ -151,28 +204,76 @@ | ||
Extension for [`mdast-util-from-markdown`][mdast-util-from-markdown] | ||
to enable GFM task lists ([`FromMarkdownExtension`][frommarkdownextension]). | ||
### `gfmTaskListItemToMarkdown` | ||
Support task list items. | ||
The exports are extensions, respectively | ||
for [`mdast-util-from-markdown`][from-markdown] and | ||
[`mdast-util-to-markdown`][to-markdown]. | ||
Extension for [`mdast-util-to-markdown`][mdast-util-to-markdown] | ||
to enable GFM task lists ([`ToMarkdownExtension`][tomarkdownextension]). | ||
## HTML | ||
This utility does not handle how markdown is turned to HTML. | ||
That’s done by [`mdast-util-to-hast`][mdast-util-to-hast]. | ||
## Syntax | ||
See [Syntax in `micromark-extension-gfm-task-list-item`][syntax]. | ||
## Syntax tree | ||
The following interfaces are added to **[mdast][]** by this utility. | ||
### Nodes | ||
#### `ListItem` (GFM) | ||
```idl | ||
interface ListItemGfm <: ListItem { | ||
checked: boolean? | ||
} | ||
``` | ||
In GFM, a `checked` field can be present. | ||
It represents whether the item is done (when `true`), not done (when `false`), | ||
or indeterminate or not applicable (when `null` or not present). | ||
### Content model | ||
#### `ListContent` (GFM) | ||
```idl | ||
type ListContentGfm = ListItemGfm | ||
``` | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
It does not export additional types. | ||
The `ListItem` type of the mdast nodes are exposed from `@types/mdast`. | ||
## Compatibility | ||
Projects maintained by the unified collective are compatible with all maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 14.14+ and 16.0+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
This plugin works with `mdast-util-from-markdown` version 1+ and | ||
`mdast-util-to-markdown` version 1+. | ||
## Related | ||
* [`remarkjs/remark`][remark] | ||
— markdown processor powered by plugins | ||
* [`remarkjs/remark-gfm`][remark-gfm] | ||
— remark plugin to support GFM | ||
* [`micromark/micromark`][micromark] | ||
— the smallest commonmark-compliant markdown parser that exists | ||
* [`syntax-tree/mdast-util-gfm`][mdast-util-gfm] | ||
— same but all of GFM (autolink literals, footnotes, strikethrough, tables, | ||
tasklists) | ||
* [`micromark/micromark-extension-gfm-task-list-item`][extension] | ||
— micromark extension to parse GFM task list items | ||
* [`syntax-tree/mdast-util-from-markdown`][from-markdown] | ||
— mdast parser using `micromark` to create mdast from markdown | ||
* [`syntax-tree/mdast-util-to-markdown`][to-markdown] | ||
— mdast serializer to create markdown from mdast | ||
## Contribute | ||
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get | ||
started. | ||
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for | ||
ways to get started. | ||
See [`support.md`][support] for ways to get help. | ||
@@ -218,2 +319,8 @@ | ||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c | ||
[esmsh]: https://esm.sh | ||
[typescript]: https://www.typescriptlang.org | ||
[license]: license | ||
@@ -223,2 +330,4 @@ | ||
[health]: https://github.com/syntax-tree/.github | ||
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md | ||
@@ -232,12 +341,26 @@ | ||
[remark]: https://github.com/remarkjs/remark | ||
[remark-gfm]: https://github.com/remarkjs/remark-gfm | ||
[from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown | ||
[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown | ||
[to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown | ||
[mdast-util-to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown | ||
[mdast-util-gfm]: https://github.com/syntax-tree/mdast-util-gfm | ||
[mdast-util-to-hast]: https://github.com/syntax-tree/mdast-util-to-hast | ||
[micromark]: https://github.com/micromark/micromark | ||
[extension]: https://github.com/micromark/micromark-extension-gfm-task-list-item | ||
[syntax]: https://github.com/micromark/micromark-extension-gfm-task-list-item#syntax | ||
[frommarkdownextension]: https://github.com/syntax-tree/mdast-util-from-markdown#extension | ||
[tomarkdownextension]: https://github.com/syntax-tree/mdast-util-to-markdown#options | ||
[gfm]: https://github.github.com/gfm/ | ||
[api-gfmtasklistitemfrommarkdown]: #gfmtasklistitemfrommarkdown | ||
[api-gfmtasklistitemtomarkdown]: #gfmtasklistitemtomarkdown |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18090
11
7
155
357
1