micromark-extension-gfm-strikethrough
Advanced tools
Comparing version 1.0.4 to 1.0.5
/** | ||
* @typedef {import('./lib/syntax.js').Options} Options | ||
*/ | ||
export {gfmStrikethroughHtml} from './lib/html.js' | ||
export {gfmStrikethrough} from './lib/syntax.js' |
/** | ||
* @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension | ||
*/ | ||
/** @type {HtmlExtension} */ | ||
/** | ||
* Extension for `micromark` that can be passed in `htmlExtensions`, to | ||
* support GFM strikethrough when serializing to HTML. | ||
* | ||
* @type {HtmlExtension} | ||
*/ | ||
export const gfmStrikethroughHtml: HtmlExtension | ||
export type HtmlExtension = import('micromark-util-types').HtmlExtension |
@@ -5,3 +5,10 @@ /** | ||
/** @type {HtmlExtension} */ | ||
// To do: next major: expose function instead of object. | ||
/** | ||
* Extension for `micromark` that can be passed in `htmlExtensions`, to | ||
* support GFM strikethrough when serializing to HTML. | ||
* | ||
* @type {HtmlExtension} | ||
*/ | ||
export const gfmStrikethroughHtml = { | ||
@@ -8,0 +15,0 @@ enter: { |
/** | ||
* @param {Options} [options] | ||
* Create an extension for `micromark` to enable GFM strikethrough syntax. | ||
* | ||
* @param {Options | null | undefined} [options] | ||
* Configuration. | ||
* @returns {Extension} | ||
* Extension for `micromark` that can be passed in `extensions`, to | ||
* enable GFM strikethrough syntax. | ||
*/ | ||
export function gfmStrikethrough(options?: Options | undefined): Extension | ||
export function gfmStrikethrough( | ||
options?: Options | null | undefined | ||
): Extension | ||
export type Extension = import('micromark-util-types').Extension | ||
export type Resolver = import('micromark-util-types').Resolver | ||
export type State = import('micromark-util-types').State | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext | ||
export type Tokenizer = import('micromark-util-types').Tokenizer | ||
export type State = import('micromark-util-types').State | ||
export type Token = import('micromark-util-types').Token | ||
export type Event = import('micromark-util-types').Event | ||
/** | ||
@@ -17,8 +23,8 @@ * Configuration (optional). | ||
/** | ||
* Whether to support strikethrough with a single tilde (`boolean`, default: | ||
* `true`). | ||
* Whether to support strikethrough with a single tilde. | ||
* | ||
* Single tildes work on github.com, but are technically prohibited by the | ||
* GFM spec. | ||
*/ | ||
singleTilde?: boolean | undefined | ||
singleTilde?: boolean | ||
} |
/** | ||
* @typedef {import('micromark-util-types').Extension} Extension | ||
* @typedef {import('micromark-util-types').Resolver} Resolver | ||
* @typedef {import('micromark-util-types').State} State | ||
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext | ||
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer | ||
* @typedef {import('micromark-util-types').State} State | ||
* @typedef {import('micromark-util-types').Token} Token | ||
* @typedef {import('micromark-util-types').Event} Event | ||
*/ | ||
/** | ||
* | ||
* @typedef Options | ||
* Configuration (optional). | ||
* @property {boolean} [singleTilde=true] | ||
* Whether to support strikethrough with a single tilde (`boolean`, default: | ||
* `true`). | ||
* Whether to support strikethrough with a single tilde. | ||
* | ||
* Single tildes work on github.com, but are technically prohibited by the | ||
@@ -29,7 +26,13 @@ * GFM spec. | ||
/** | ||
* @param {Options} [options] | ||
* Create an extension for `micromark` to enable GFM strikethrough syntax. | ||
* | ||
* @param {Options | null | undefined} [options] | ||
* Configuration. | ||
* @returns {Extension} | ||
* Extension for `micromark` that can be passed in `extensions`, to | ||
* enable GFM strikethrough syntax. | ||
*/ | ||
export function gfmStrikethrough(options = {}) { | ||
let single = options.singleTilde | ||
export function gfmStrikethrough(options) { | ||
const options_ = options || {} | ||
let single = options_.singleTilde | ||
const tokenizer = { | ||
@@ -102,13 +105,14 @@ tokenize: tokenizeStrikethrough, | ||
// Between. | ||
splice( | ||
nextEvents, | ||
nextEvents.length, | ||
0, | ||
resolveAll( | ||
context.parser.constructs.insideSpan.null, | ||
events.slice(open + 1, index), | ||
context | ||
const insideSpan = context.parser.constructs.insideSpan.null | ||
if (insideSpan) { | ||
// Between. | ||
splice( | ||
nextEvents, | ||
nextEvents.length, | ||
0, | ||
// @ts-expect-error: to do: update `mdast-util-types` to allow explicit `undefined`s. | ||
resolveAll(insideSpan, events.slice(open + 1, index), context) | ||
) | ||
) | ||
} | ||
@@ -143,3 +147,6 @@ // Closing. | ||
/** @type {Tokenizer} */ | ||
/** | ||
* @this {TokenizeContext} | ||
* @type {Tokenizer} | ||
*/ | ||
function tokenizeStrikethrough(effects, ok, nok) { | ||
@@ -146,0 +153,0 @@ const previous = this.previous |
/** | ||
* @typedef {import('./lib/syntax.js').Options} Options | ||
*/ | ||
export {gfmStrikethroughHtml} from './lib/html.js' | ||
export {gfmStrikethrough} from './lib/syntax.js' |
/** | ||
* @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension | ||
*/ | ||
/** @type {HtmlExtension} */ | ||
/** | ||
* Extension for `micromark` that can be passed in `htmlExtensions`, to | ||
* support GFM strikethrough when serializing to HTML. | ||
* | ||
* @type {HtmlExtension} | ||
*/ | ||
export const gfmStrikethroughHtml: HtmlExtension | ||
export type HtmlExtension = import('micromark-util-types').HtmlExtension |
@@ -5,3 +5,10 @@ /** | ||
/** @type {HtmlExtension} */ | ||
// To do: next major: expose function instead of object. | ||
/** | ||
* Extension for `micromark` that can be passed in `htmlExtensions`, to | ||
* support GFM strikethrough when serializing to HTML. | ||
* | ||
* @type {HtmlExtension} | ||
*/ | ||
export const gfmStrikethroughHtml = { | ||
@@ -8,0 +15,0 @@ enter: { |
/** | ||
* @param {Options} [options] | ||
* Create an extension for `micromark` to enable GFM strikethrough syntax. | ||
* | ||
* @param {Options | null | undefined} [options] | ||
* Configuration. | ||
* @returns {Extension} | ||
* Extension for `micromark` that can be passed in `extensions`, to | ||
* enable GFM strikethrough syntax. | ||
*/ | ||
export function gfmStrikethrough(options?: Options | undefined): Extension | ||
export function gfmStrikethrough( | ||
options?: Options | null | undefined | ||
): Extension | ||
export type Extension = import('micromark-util-types').Extension | ||
export type Resolver = import('micromark-util-types').Resolver | ||
export type State = import('micromark-util-types').State | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext | ||
export type Tokenizer = import('micromark-util-types').Tokenizer | ||
export type State = import('micromark-util-types').State | ||
export type Token = import('micromark-util-types').Token | ||
export type Event = import('micromark-util-types').Event | ||
/** | ||
@@ -17,8 +23,8 @@ * Configuration (optional). | ||
/** | ||
* Whether to support strikethrough with a single tilde (`boolean`, default: | ||
* `true`). | ||
* Whether to support strikethrough with a single tilde. | ||
* | ||
* Single tildes work on github.com, but are technically prohibited by the | ||
* GFM spec. | ||
*/ | ||
singleTilde?: boolean | undefined | ||
singleTilde?: boolean | ||
} |
/** | ||
* @typedef {import('micromark-util-types').Extension} Extension | ||
* @typedef {import('micromark-util-types').Resolver} Resolver | ||
* @typedef {import('micromark-util-types').State} State | ||
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext | ||
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer | ||
* @typedef {import('micromark-util-types').State} State | ||
* @typedef {import('micromark-util-types').Token} Token | ||
* @typedef {import('micromark-util-types').Event} Event | ||
*/ | ||
/** | ||
* | ||
* @typedef Options | ||
* Configuration (optional). | ||
* @property {boolean} [singleTilde=true] | ||
* Whether to support strikethrough with a single tilde (`boolean`, default: | ||
* `true`). | ||
* Whether to support strikethrough with a single tilde. | ||
* | ||
* Single tildes work on github.com, but are technically prohibited by the | ||
* GFM spec. | ||
*/ | ||
import {splice} from 'micromark-util-chunked' | ||
import {classifyCharacter} from 'micromark-util-classify-character' | ||
import {resolveAll} from 'micromark-util-resolve-all' | ||
/** | ||
* @param {Options} [options] | ||
* Create an extension for `micromark` to enable GFM strikethrough syntax. | ||
* | ||
* @param {Options | null | undefined} [options] | ||
* Configuration. | ||
* @returns {Extension} | ||
* Extension for `micromark` that can be passed in `extensions`, to | ||
* enable GFM strikethrough syntax. | ||
*/ | ||
export function gfmStrikethrough(options = {}) { | ||
let single = options.singleTilde | ||
export function gfmStrikethrough(options) { | ||
const options_ = options || {} | ||
let single = options_.singleTilde | ||
const tokenizer = { | ||
@@ -33,7 +36,5 @@ tokenize: tokenizeStrikethrough, | ||
} | ||
if (single === null || single === undefined) { | ||
single = true | ||
} | ||
return { | ||
@@ -50,2 +51,3 @@ text: { | ||
} | ||
/** | ||
@@ -56,6 +58,6 @@ * Take events and resolve strikethrough. | ||
*/ | ||
function resolveAllStrikethrough(events, context) { | ||
let index = -1 // Walk through all events. | ||
let index = -1 | ||
// Walk through all events. | ||
while (++index < events.length) { | ||
@@ -68,4 +70,5 @@ // Find a token that can close. | ||
) { | ||
let open = index // Now walk back to find an opener. | ||
let open = index | ||
// Now walk back to find an opener. | ||
while (open--) { | ||
@@ -76,3 +79,4 @@ // Find a token that can open the closer. | ||
events[open][1].type === 'strikethroughSequenceTemporary' && | ||
events[open][1]._open && // If the sizes are the same: | ||
events[open][1]._open && | ||
// If the sizes are the same: | ||
events[index][1].end.offset - events[index][1].start.offset === | ||
@@ -92,4 +96,5 @@ events[open][1].end.offset - events[open][1].start.offset | ||
end: Object.assign({}, events[index][1].start) | ||
} // Opening. | ||
} | ||
// Opening. | ||
const nextEvents = [ | ||
@@ -100,15 +105,16 @@ ['enter', strikethrough, context], | ||
['enter', text, context] | ||
] // Between. | ||
splice( | ||
nextEvents, | ||
nextEvents.length, | ||
0, | ||
resolveAll( | ||
context.parser.constructs.insideSpan.null, | ||
events.slice(open + 1, index), | ||
context | ||
] | ||
const insideSpan = context.parser.constructs.insideSpan.null | ||
if (insideSpan) { | ||
// Between. | ||
splice( | ||
nextEvents, | ||
nextEvents.length, | ||
0, | ||
// @ts-expect-error: to do: update `mdast-util-types` to allow explicit `undefined`s. | ||
resolveAll(insideSpan, events.slice(open + 1, index), context) | ||
) | ||
) // Closing. | ||
} | ||
// Closing. | ||
splice(nextEvents, nextEvents.length, 0, [ | ||
@@ -127,5 +133,3 @@ ['exit', text, context], | ||
} | ||
index = -1 | ||
while (++index < events.length) { | ||
@@ -136,7 +140,9 @@ if (events[index][1].type === 'strikethroughSequenceTemporary') { | ||
} | ||
return events | ||
} | ||
/** @type {Tokenizer} */ | ||
/** | ||
* @this {TokenizeContext} | ||
* @type {Tokenizer} | ||
*/ | ||
function tokenizeStrikethrough(effects, ok, nok) { | ||
@@ -147,4 +153,4 @@ const previous = this.previous | ||
return start | ||
/** @type {State} */ | ||
function start(code) { | ||
@@ -157,11 +163,9 @@ if ( | ||
} | ||
effects.enter('strikethroughSequenceTemporary') | ||
return more(code) | ||
} | ||
/** @type {State} */ | ||
function more(code) { | ||
const before = classifyCharacter(previous) | ||
if (code === 126) { | ||
@@ -174,3 +178,2 @@ // If this is the third marker, exit. | ||
} | ||
if (size < 2 && !single) return nok(code) | ||
@@ -177,0 +180,0 @@ const token = effects.exit('strikethroughSequenceTemporary') |
{ | ||
"name": "micromark-extension-gfm-strikethrough", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "micromark extension to support GFM strikethrough", | ||
@@ -52,3 +52,3 @@ "license": "MIT", | ||
"devDependencies": { | ||
"@types/tape": "^4.0.0", | ||
"@types/node": "^18.0.0", | ||
"c8": "^7.0.0", | ||
@@ -59,15 +59,17 @@ "create-gfm-fixtures": "^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", | ||
"xo": "^0.47.0" | ||
"typescript": "^5.0.0", | ||
"xo": "^0.53.0" | ||
}, | ||
"scripts": { | ||
"build": "rimraf \"dev/**/*.d.ts\" \"test/**/*.d.ts\" && tsc && type-coverage && micromark-build", | ||
"prepack": "npm run build && npm run format", | ||
"build": "tsc --build --clean && tsc --build && type-coverage && micromark-build", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"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-api-prod": "node --conditions production test/index.js", | ||
"test-api-dev": "node --conditions development test/index.js", | ||
"test-api": "npm run test-api-dev && npm run test-api-prod", | ||
"test-coverage": "c8 --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
@@ -86,9 +88,18 @@ }, | ||
"rules": { | ||
"node/file-extension-in-import": "off", | ||
"n/file-extension-in-import": "off", | ||
"max-depth": "off", | ||
"unicorn/prefer-node-protocol": "off" | ||
} | ||
}, | ||
"overrides": [ | ||
{ | ||
"files": "test/**/*.js", | ||
"rules": { | ||
"no-await-in-loop": 0 | ||
} | ||
} | ||
] | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-wooorm" | ||
"remark-preset-wooorm" | ||
] | ||
@@ -95,0 +106,0 @@ }, |
164
readme.md
@@ -11,4 +11,3 @@ # micromark-extension-gfm-strikethrough | ||
**[micromark][]** extension to support GitHub flavored markdown (GFM) | ||
[strikethrough][]. | ||
[micromark][] extensions to support GFM [strikethrough][]. | ||
@@ -24,2 +23,7 @@ ## Contents | ||
* [`gfmStrikethroughHtml`](#gfmstrikethroughhtml) | ||
* [`Options`](#options) | ||
* [Authoring](#authoring) | ||
* [HTML](#html) | ||
* [CSS](#css) | ||
* [Syntax](#syntax) | ||
* [Types](#types) | ||
@@ -34,26 +38,23 @@ * [Compatibility](#compatibility) | ||
This package is a micromark extension to add support for GFM strikethrough. | ||
Strikethrough on `github.com`, which this extension matches, can use one | ||
(`~one~`) or two (`~~two~~`) tildes. | ||
You can also strictly match the GFM spec instead of their implementation by | ||
passing `singleTilde: false`. | ||
This package contains extensions that add support for strikethrough as enabled | ||
by GFM to [`micromark`][micromark]. | ||
## When to use this | ||
In many cases, when working with micromark, you’d want to use | ||
[`micromark-extension-gfm`][micromark-extension-gfm] instead, which combines | ||
this package with other GFM features. | ||
This project is useful when you want to support strikethrough in markdown. | ||
When working with syntax trees, you’d want to combine this package with | ||
[`mdast-util-gfm-strikethrough`][mdast-util-gfm-strikethrough] (or | ||
[`mdast-util-gfm`][mdast-util-gfm] when using `micromark-extension-gfm`). | ||
You can use these extensions when you are working with [`micromark`][micromark]. | ||
To support all GFM features, use | ||
[`micromark-extension-gfm`][micromark-extension-gfm]. | ||
These tools are all rather low-level. | ||
In most cases, you’d instead want to use [`remark-gfm`][remark-gfm] with | ||
[remark][]. | ||
When you need a syntax tree, you can combine this package with | ||
[`mdast-util-gfm-strikethrough`][mdast-util-gfm-strikethrough]. | ||
All these packages are used [`remark-gfm`][remark-gfm], which focusses on making | ||
it easier to transform content by abstracting these internals away. | ||
## Install | ||
This package is [ESM only][esm]. | ||
In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: | ||
In Node.js (version 14.14+), install with [npm][]: | ||
@@ -64,13 +65,13 @@ ```sh | ||
In Deno with [Skypack][]: | ||
In Deno with [`esm.sh`][esmsh]: | ||
```js | ||
import {gfmStrikethrough, gfmStrikethroughHtml} from 'https://cdn.skypack.dev/micromark-extension-gfm-strikethrough@1?dts' | ||
import {gfmStrikethrough, gfmStrikethroughHtml} from 'https://esm.sh/micromark-extension-gfm-strikethrough@1' | ||
``` | ||
In browsers with [Skypack][]: | ||
In browsers with [`esm.sh`][esmsh]: | ||
```html | ||
<script type="module"> | ||
import {gfmStrikethrough, gfmStrikethroughHtml} from 'https://cdn.skypack.dev/micromark-extension-gfm-strikethrough@1?min' | ||
import {gfmStrikethrough, gfmStrikethroughHtml} from 'https://esm.sh/micromark-extension-gfm-strikethrough@1?bundle' | ||
</script> | ||
@@ -104,8 +105,8 @@ ``` | ||
This package exports the following identifiers: `gfmStrikethrough`, | ||
`gfmStrikethroughHtml`. | ||
This package exports the identifiers | ||
[`gfmStrikethrough`][api-gfm-strikethrough] and | ||
[`gfmStrikethroughHtml`][api-gfm-strikethrough-html]. | ||
There is no default export. | ||
The export map supports the endorsed | ||
[`development` condition](https://nodejs.org/api/packages.html#packages_resolving_user_conditions). | ||
The export map supports the [`development` condition][development]. | ||
Run `node --conditions development module.js` to get instrumented dev code. | ||
@@ -116,30 +117,85 @@ Without this condition, production code is loaded. | ||
A function that can be called to get an extension for micromark to parse | ||
GFM strikethrough (can be passed in `extensions`). | ||
Create an extension for `micromark` to enable GFM strikethrough syntax. | ||
##### `options` | ||
###### Parameters | ||
Configuration (optional). | ||
* `options` ([`Options`][api-options], optional) | ||
— configuration | ||
###### `options.singleTilde` | ||
###### Returns | ||
Whether to support strikethrough with a single tilde (`boolean`, default: | ||
`true`). | ||
Single tildes work on github.com, but are technically prohibited by GFM. | ||
Extension for `micromark` that can be passed in `extensions`, to | ||
enable GFM strikethrough syntax ([`Extension`][micromark-extension]). | ||
### `gfmStrikethroughHtml` | ||
An extension to compile them to HTML (can be passed in `htmlExtensions`). | ||
Extension for `micromark` that can be passed in `htmlExtensions`, to support | ||
GFM strikethrough when serializing to HTML | ||
([`HtmlExtension`][micromark-html-extension]). | ||
### `Options` | ||
Configuration (TypeScript type). | ||
###### Fields | ||
* `singleTilde` (`boolean`, default: `true`) | ||
— whether to support strikethrough with a single tilde. | ||
Single tildes work on github.com, but are technically prohibited by the GFM | ||
spec | ||
## Authoring | ||
When authoring markdown with strikethrough, it is recommended to use two | ||
markers. | ||
While `github.com` allows single tildes too, it technically prohibits it in | ||
their spec. | ||
## HTML | ||
When tilde sequences match, they together relate to the `<del>` element in | ||
HTML. | ||
See [*§ 4.7.2 The `del` element*][html-del] in the HTML spec for more info. | ||
## CSS | ||
GitHub itself does not apply interesting CSS to `del` elements. | ||
It currently (July 2022) does change `code` in `del`. | ||
```css | ||
del code { | ||
text-decoration: inherit; | ||
} | ||
``` | ||
For the complete actual CSS see | ||
[`sindresorhus/github-markdown-css`][github-markdown-css]. | ||
## Syntax | ||
Strikethrough sequences form with the following BNF: | ||
```bnf | ||
gfm_attention_sequence ::= 1*'~' | ||
``` | ||
Sequences are matched together to form strikethrough based on which character | ||
they contain, how long they are, and what character occurs before and after | ||
each sequence. | ||
Otherwise they are turned into data. | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
It exports additional `Options` type that models its respective interface. | ||
It exports the additional type [`Options`][api-options]. | ||
## Compatibility | ||
This package is at least compatible with all maintained versions of Node.js. | ||
As of now, that is Node.js 12.20+, 14.14+, and 16.0+. | ||
It also works in Deno and modern browsers. | ||
Projects maintained by the unified collective are compatible with all maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 14.14+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
These extensions work with `micromark` version 3+. | ||
## Security | ||
@@ -151,8 +207,10 @@ | ||
* [`syntax-tree/mdast-util-gfm-strikethrough`][mdast-util-gfm-strikethrough] | ||
— support GFM strikethrough in mdast | ||
* [`syntax-tree/mdast-util-gfm`][mdast-util-gfm] | ||
— support GFM in mdast | ||
* [`remarkjs/remark-gfm`][remark-gfm] | ||
— support GFM in remark | ||
* [`micromark-extension-gfm`][micromark-extension-gfm] | ||
— support all of GFM | ||
* [`mdast-util-gfm-strikethrough`][mdast-util-gfm-strikethrough] | ||
— support all of GFM in mdast | ||
* [`mdast-util-gfm`][mdast-util-gfm] | ||
— support all of GFM in mdast | ||
* [`remark-gfm`][remark-gfm] | ||
— support all of GFM in remark | ||
@@ -203,3 +261,3 @@ ## Contribute | ||
[skypack]: https://www.skypack.dev | ||
[esmsh]: https://esm.sh | ||
@@ -220,6 +278,10 @@ [license]: license | ||
[development]: https://nodejs.org/api/packages.html#packages_resolving_user_conditions | ||
[micromark]: https://github.com/micromark/micromark | ||
[remark]: https://github.com/remarkjs/remark | ||
[micromark-html-extension]: https://github.com/micromark/micromark#htmlextension | ||
[micromark-extension]: https://github.com/micromark/micromark#syntaxextension | ||
[micromark-extension-gfm]: https://github.com/micromark/micromark-extension-gfm | ||
@@ -234,1 +296,11 @@ | ||
[strikethrough]: https://github.github.com/gfm/#strikethrough-extension- | ||
[github-markdown-css]: https://github.com/sindresorhus/github-markdown-css | ||
[html-del]: https://html.spec.whatwg.org/multipage/edits.html#the-del-element | ||
[api-gfm-strikethrough]: #gfmstrikethroughoptions | ||
[api-gfm-strikethrough-html]: #gfmstrikethroughhtml | ||
[api-options]: #options |
27642
12
473
297