diff --git a/lib/index.js b/lib/index.js index e738500..6dac9f9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -60,6 +60,21 @@ export function createLowlight(grammars) { /** * Highlight `value` (code) as `language` (name). * + * @example + * ```js + * import {common, createLowlight} from 'lowlight' + * + * const lowlight = createLowlight(common) + * + * console.log(lowlight.highlight('css', 'em { color: red }')) + * ``` + * + * Yields: + * + * ```js + * {type: 'root', children: [Array], data: {language: 'css', relevance: 3}} + * ``` + * * @param {string} language * Programming language name. * @param {string} value @@ -67,12 +82,13 @@ export function createLowlight(grammars) { * @param {Readonly | null | undefined} [options={}] * Configuration (optional). * @returns {Root} - * A hast `Root` node. + * Tree; with the following `data` fields: `language` (`string`), detected + * programming language name; `relevance` (`number`), how sure lowlight is + * that the given code is in the language. */ function highlight(language, value, options) { assert(typeof language === 'string', 'expected `string` as `name`') assert(typeof value === 'string', 'expected `string` as `value`') - const settings = options || emptyOptions const prefix = typeof settings.prefix === 'string' ? settings.prefix : defaultPrefix @@ -112,23 +128,39 @@ export function createLowlight(grammars) { /** * Highlight `value` (code) and guess its programming language. * + * @example + * ```js + * import {common, createLowlight} from 'lowlight' + * + * const lowlight = createLowlight(common) + * + * console.log(lowlight.highlightAuto('"hello, " + name + "!"')) + * ``` + * + * Yields: + * + * ```js + * {type: 'root', children: [Array], data: {language: 'arduino', relevance: 2}} + * ``` + * * @param {string} value * Code to highlight. * @param {Readonly | null | undefined} [options={}] * Configuration (optional). * @returns {Root} - * A hast `Root` node. + * Tree; with the following `data` fields: `language` (`string`), detected + * programming language name; `relevance` (`number`), how sure lowlight is + * that the given code is in the language. */ function highlightAuto(value, options) { assert(typeof value === 'string', 'expected `string` as `value`') - const settings = options || emptyOptions const subset = settings.subset || listLanguages() let index = -1 let relevance = 0 - /** @type {Root} */ - let result = {type: 'root', children: []} + /** @type {Root | undefined} */ + let result while (++index < subset.length) { const name = subset[index] @@ -147,16 +179,32 @@ export function createLowlight(grammars) { } } - if (!result.data) { - result.data = {language: undefined, relevance} - } - - return result + return ( + result || { + type: 'root', + children: [], + data: {language: undefined, relevance} + } + ) } /** * List registered languages. * + * @example + * ```js + * import {createLowlight} from 'lowlight' + * import markdown from 'highlight.js/lib/languages/markdown' + * + * const lowlight = createLowlight() + * + * console.log(lowlight.listLanguages()) // => [] + * + * lowlight.register({markdown}) + * + * console.log(lowlight.listLanguages()) // => ['markdown'] + * ``` + * * @returns {Array} * Names of registered language. */ @@ -167,33 +215,52 @@ export function createLowlight(grammars) { /** * Register languages. * + * @example + * ```js + * import {createLowlight} from 'lowlight' + * import xml from 'highlight.js/lib/languages/xml' + * + * const lowlight = createLowlight() + * + * lowlight.register({xml}) + * + * // Note: `html` is an alias for `xml`. + * console.log(lowlight.highlight('html', 'Emphasis')) + * ``` + * + * Yields: + * + * ```js + * {type: 'root', children: [Array], data: {language: 'html', relevance: 2}} + * ``` + * * @overload - * @param {Readonly>} languageMap + * @param {Readonly>} grammars * @returns {undefined} * * @overload * @param {string} name - * @param {LanguageFn} language + * @param {LanguageFn} grammar * @returns {undefined} * - * @param {Readonly> | string} languageMapOrName - * Programming language name or a map of names to language functions. - * @param {LanguageFn | undefined} [languageFn] - * Language function, if with name. + * @param {Readonly> | string} grammarsOrName + * Grammars or programming language name. + * @param {LanguageFn | undefined} [grammar] + * Grammar, if with name. * @returns {undefined} * Nothing. */ - function register(languageMapOrName, languageFn) { - if (typeof languageMapOrName === 'string') { - assert(languageFn !== undefined, 'expected `languageFn`') - high.registerLanguage(languageMapOrName, languageFn) + function register(grammarsOrName, grammar) { + if (typeof grammarsOrName === 'string') { + assert(grammar !== undefined, 'expected `grammar`') + high.registerLanguage(grammarsOrName, grammar) } else { /** @type {string} */ let name - for (name in languageMapOrName) { - if (Object.hasOwn(languageMapOrName, name)) { - high.registerLanguage(name, languageMapOrName[name]) + for (name in grammarsOrName) { + if (Object.hasOwn(grammarsOrName, name)) { + high.registerLanguage(name, grammarsOrName[name]) } } } @@ -202,37 +269,55 @@ export function createLowlight(grammars) { /** * Register aliases. * + * @example + * ```js + * import {createLowlight} from 'lowlight' + * import markdown from 'highlight.js/lib/languages/markdown' + * + * const lowlight = createLowlight() + * + * lowlight.register({markdown}) + * + * // lowlight.highlight('mdown', 'Emphasis') + * // ^ would throw: Error: Unknown language: `mdown` is not registered + * + * lowlight.registerAlias({markdown: ['mdown', 'mkdn', 'mdwn', 'ron']}) + * lowlight.highlight('mdown', 'Emphasis') + * // ^ Works! + * ``` + * * @overload - * @param {Readonly | string>>} aliaseMap + * @param {Readonly | string>>} aliases * @returns {undefined} * * @overload * @param {string} language - * @param {ReadonlyArray | string} aliases + * @param {ReadonlyArray | string} alias * @returns {undefined} * - * @param {Readonly | string>> | string} language - * Programming language name or a map of `language`s to `alias`es or `list`s + * @param {Readonly | string>> | string} aliasesOrName + * Map of programming language names to one or more aliases, or programming + * language name. * @param {ReadonlyArray | string | undefined} [alias] - * New aliases for the programming language. + * One or more aliases for the programming language, if with `name`. * @returns {undefined} * Nothing. */ - function registerAlias(language, alias) { - if (typeof language === 'string') { + function registerAlias(aliasesOrName, alias) { + if (typeof aliasesOrName === 'string') { assert(alias !== undefined) high.registerAliases( // Note: copy needed because hljs doesn’t accept readonly arrays yet. typeof alias === 'string' ? alias : [...alias], - {languageName: language} + {languageName: aliasesOrName} ) } else { /** @type {string} */ let key - for (key in language) { - if (Object.hasOwn(language, key)) { - const aliases = language[key] + for (key in aliasesOrName) { + if (Object.hasOwn(aliasesOrName, key)) { + const aliases = aliasesOrName[key] high.registerAliases( // Note: copy needed because hljs doesn’t accept readonly arrays yet. typeof aliases === 'string' ? aliases : [...aliases], @@ -244,15 +329,28 @@ export function createLowlight(grammars) { } /** - * Check whether an `alias` or `language` is registered. + * Check whether an alias or name is registered. + * + * @example + * ```js + * import {createLowlight} from 'lowlight' + * import javascript from 'highlight.js/lib/languages/javascript' + * + * const lowlight = createLowlight({javascript}) + * + * console.log(lowlight.registered('funkyscript')) // => `false` + * + * lowlight.registerAlias({javascript: 'funkyscript'}) + * console.log(lowlight.registered('funkyscript')) // => `true` + * ``` * - * @param {string} aliasOrLanguage - * Name of a registered language or alias. + * @param {string} aliasOrName + * Name of a language or alias for one. * @returns {boolean} - * Whether `aliasOrlanguage` is registered. + * Whether `aliasOrName` is registered. */ - function registered(aliasOrLanguage) { - return Boolean(high.getLanguage(aliasOrLanguage)) + function registered(aliasOrName) { + return Boolean(high.getLanguage(aliasOrName)) } } diff --git a/package.json b/package.json index 77c1e54..b3a72b2 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,6 @@ "remarkConfig": { "plugins": [ "remark-preset-wooorm", - "./script/count.js", "./script/support.js" ] }, diff --git a/readme.md b/readme.md index e91f78e..26d5f1d 100644 --- a/readme.md +++ b/readme.md @@ -7,7 +7,8 @@ [![Downloads][downloads-badge]][downloads] [![Size][size-badge]][size] -Virtual syntax highlighting for virtual DOMs and non-HTML things. +Virtual syntax highlighting for virtual DOMs and non-HTML things based on +[`highlight.js`][highlight-js]. ## Contents @@ -16,15 +17,21 @@ Virtual syntax highlighting for virtual DOMs and non-HTML things. * [Install](#install) * [Use](#use) * [API](#api) + * [`all`](#all) + * [`common`](#common) + * [`createLowlight([grammars])`](#createlowlightgrammars) * [`lowlight.highlight(language, value[, options])`](#lowlighthighlightlanguage-value-options) * [`lowlight.highlightAuto(value[, options])`](#lowlighthighlightautovalue-options) - * [`lowlight.registerLanguage(language, syntax)`](#lowlightregisterlanguagelanguage-syntax) + * [`lowlight.listLanguages()`](#lowlightlistlanguages) + * [`lowlight.register(grammars)`](#lowlightregistergrammars) * [`lowlight.registerAlias(language, alias)`](#lowlightregisteraliaslanguage-alias) * [`lowlight.registered(aliasOrlanguage)`](#lowlightregisteredaliasorlanguage) - * [`lowlight.listLanguages()`](#lowlightlistlanguages) + * [`AutoOptions`](#autooptions) + * [`LanguageFn`](#languagefn) + * [`Options`](#options) * [Examples](#examples) * [Example: serializing hast as html](#example-serializing-hast-as-html) - * [Example: turning hast into react nodes](#example-turning-hast-into-react-nodes) + * [Example: turning hast into preact, react, etc](#example-turning-hast-into-preact-react-etc) * [Types](#types) * [Data](#data) * [CSS](#css) @@ -37,22 +44,9 @@ Virtual syntax highlighting for virtual DOMs and non-HTML things. ## What is this? -This package wraps [highlight.js][] to output objects (ASTs) instead of a string -of HTML. - -`highlight.js`, through lowlight, supports 190+ programming languages. -Supporting all of them requires a lot of code. -That’s why there are three entry points for lowlight: - - - -* `lib/core.js` — 0 languages -* `lib/common.js` (default) — 37 languages -* `lib/all.js` — 192 languages - - - -Bundled, minified, and gzipped, those are roughly 9.7 kB, 47 kB, and 290 kB. +This package uses [`highlight.js`][highlight-js] for syntax highlighting and +outputs objects (ASTs) instead of a string of HTML. +It optionally supports about 190+ programming languages. ## When should I use this? @@ -63,15 +57,15 @@ rendering to ANSI sequences, when you’re using virtual DOM frameworks (such as React or Preact) so that diffing can be performant, or when you’re working with ASTs (rehype). -A different package, [`refractor`][refractor], does the same as lowlight but -uses [Prism][] instead. -If you’re looking for a *really good* (but rather heavy) highlighter, try +You can use the similar [`refractor`][refractor] if you want to use [Prism][] +grammars instead. +If you’re looking for a *really good* (but rather heavy) alternative, use [`starry-night`][starry-night]. ## Install This package is [ESM only][esm]. -In Node.js (version 14.14+, 16.0+), install with [npm][]: +In Node.js (version 16+), install with [npm][]: ```sh npm install lowlight @@ -80,25 +74,27 @@ npm install lowlight In Deno with [`esm.sh`][esmsh]: ```js -import {lowlight} from 'https://esm.sh/lowlight@2' +import {all, common, createLowlight} from 'https://esm.sh/lowlight@2' ``` In browsers with [`esm.sh`][esmsh]: ```html ``` ## Use ```js -import {lowlight} from 'lowlight' +import {common, createLowlight} from 'lowlight' + +const lowlight = createLowlight(common) const tree = lowlight.highlight('js', '"use strict";') -console.dir(tree, {depth: null}) +console.dir(tree, {depth: undefined}) ``` Yields: @@ -121,9 +117,32 @@ Yields: ## API -This package exports the identifier `lowlight`. +This package exports the identifiers [`all`][api-all], +[`common`][api-common], and +[`createLowlight`][api-create-lowlight]. There is no default export. +### `all` + +Map of all (±190) grammars ([`Record`][api-language-fn]). + +### `common` + +Map of common (37) grammars ([`Record`][api-language-fn]). + +### `createLowlight([grammars])` + +Create a `lowlight` instance. + +###### Parameters + +* `grammars` ([`Record`][api-language-fn], optional) + — grammars to add + +###### Returns + +Lowlight (`Lowlight`). + ### `lowlight.highlight(language, value[, options])` Highlight `value` (code) as `language` (name). @@ -134,22 +153,21 @@ Highlight `value` (code) as `language` (name). — programming language [name][names] * `value` (`string`) — code to highlight -* `options.prefix` (`string?`, default: `'hljs-'`) - — class prefix +* `options` ([`Options`][api-options], optional) + — configuration ###### Returns -A hast [`Root`][root] node with the following `data` fields: - -* `relevance` (`number`) - — how sure lowlight is that the given code is in the language -* `language` (`string`) - — detected programming language name +Tree ([`Root`][hast-root]); with the following `data` fields: `language` +(`string`), detected programming language name; `relevance` (`number`), how +sure lowlight is that the given code is in the language. ###### Example ```js -import {lowlight} from 'lowlight' +import {common, createLowlight} from 'lowlight' + +const lowlight = createLowlight(common) console.log(lowlight.highlight('css', 'em { color: red }')) ``` @@ -168,19 +186,21 @@ Highlight `value` (code) and guess its programming language. * `value` (`string`) — code to highlight -* `options.prefix` (`string?`, default: `'hljs-'`) - — class prefix -* `options.subset` (`Array`, default: all registered language names) - — list of allowed languages +* `options` ([`AutoOptions`][api-auto-options], optional) + — configuration ###### Returns -The same result as `lowlight.highlight` is returned. +Tree ([`Root`][hast-root]); with the following `data` fields: `language` +(`string`), detected programming language name; `relevance` (`number`), how +sure lowlight is that the given code is in the language. ###### Example ```js -import {lowlight} from 'lowlight' +import {common, createLowlight} from 'lowlight' + +const lowlight = createLowlight(common) console.log(lowlight.highlightAuto('"hello, " + name + "!"')) ``` @@ -188,34 +208,65 @@ console.log(lowlight.highlightAuto('"hello, " + name + "!"')) Yields: ```js -{type: 'root', children: [Array], data: {language: 'applescript', relevance: 3}} +{type: 'root', children: [Array], data: {language: 'arduino', relevance: 2}} +``` + +### `lowlight.listLanguages()` + +List registered languages. + +###### Returns + +[Names][] of registered language (`Array`). + +###### Example + +```js +import {createLowlight} from 'lowlight' +import markdown from 'highlight.js/lib/languages/markdown' +const lowlight = createLowlight() + +console.log(lowlight.listLanguages()) // => [] + +lowlight.register({markdown}) + +console.log(lowlight.listLanguages()) // => ['markdown'] ``` -### `lowlight.registerLanguage(language, syntax)` +### `lowlight.register(grammars)` -Register a language. +Register languages. + +###### Signatures + +* `register(name, grammar)` +* `register(grammars)` ###### Parameters -* `language` (`string`) - — programming language name -* `syntax` ([`HighlightSyntax`][syntax]) - — `highlight.js` syntax +* `name` (`string`) + — programming language [name][names] +* `grammar` ([`LanguageFn`][api-language-fn]) + — grammar +* `grammars` ([`Record`][api-language-fn], optional) + — grammars -###### Note +###### Returns -`highlight.js` operates as a singleton: once you register a language in one -place, it’ll be available everywhere. +Nothing (`undefined`). ###### Example ```js -import {lowlight} from 'lowlight/lib/core.js' -import xml from 'highlight.js/lib/languages/xml.js' +import {createLowlight} from 'lowlight' +import xml from 'highlight.js/lib/languages/xml' -lowlight.registerLanguage('xml', xml) +const lowlight = createLowlight() +lowlight.register({xml}) + +// Note: `html` is an alias for `xml`. console.log(lowlight.highlight('html', 'Emphasis')) ``` @@ -227,31 +278,35 @@ Yields: ### `lowlight.registerAlias(language, alias)` -Register aliases for already registered languages. +Register aliases. ###### Signatures -* `registerAlias(language, alias | list)` * `registerAlias(aliases)` +* `registerAlias(name, alias)` ###### Parameters -* `language` (`string`) +* `aliases` (`Record | string>`) + — map of programming language [names][] to one or more aliases +* `name` (`string`) — programming language [name][names] -* `alias` (`string`) - — new aliases for the programming language -* `list` (`Array`) - — list of aliases -* `aliases` (`Record`) - — map of `language`s to `alias`es or `list`s +* `alias` (`Array | string`) + — one or more aliases for the programming language + +###### Returns + +Nothing (`undefined`). ###### Example ```js -import {lowlight} from 'lowlight/lib/core.js' -import md from 'highlight.js/lib/languages/markdown.js' +import {createLowlight} from 'lowlight' +import markdown from 'highlight.js/lib/languages/markdown' -lowlight.registerLanguage('markdown', md) +const lowlight = createLowlight() + +lowlight.register({markdown}) // lowlight.highlight('mdown', 'Emphasis') // ^ would throw: Error: Unknown language: `mdown` is not registered @@ -263,52 +318,61 @@ lowlight.highlight('mdown', 'Emphasis') ### `lowlight.registered(aliasOrlanguage)` -Check whether an `alias` or `language` is registered. +Check whether an alias or name is registered. ###### Parameters * `aliasOrlanguage` (`string`) - — [name][names] of a registered language or alias + — [name][names] of a language or alias for one ###### Returns -Whether `aliasOrlanguage` is registered (`boolean`). +Whether `aliasOrName` is registered (`boolean`). ###### Example ```js -import {lowlight} from 'lowlight/lib/core.js' -import javascript from 'highlight.js/lib/languages/javascript.js' +import {createLowlight} from 'lowlight' +import javascript from 'highlight.js/lib/languages/javascript' -lowlight.registerLanguage('javascript', javascript) +const lowlight = createLowlight({javascript}) -lowlight.registered('js') // return false +console.log(lowlight.registered('funkyscript')) // => `false` -lowlight.registerAlias('javascript', 'js') -lowlight.registered('js') // return true +lowlight.registerAlias({javascript: 'funkyscript'}) +console.log(lowlight.registered('funkyscript')) // => `true` ``` -### `lowlight.listLanguages()` - -List registered languages. +### `AutoOptions` -###### Returns +Configuration for `highlightAuto` (TypeScript type). -Names of registered language (`Array`). +###### Fields -###### Example +* `prefix` (`string`, default: `'hljs-'`) + — class prefix +* `subset` (`Array`, default: all registered languages) + — list of allowed languages -```js -import {lowlight} from 'lowlight/lib/core.js' -import md from 'highlight.js/lib/languages/markdown.js' +### `LanguageFn` -console.log(lowlight.listLanguages()) // => [] +Highlight.js grammar (TypeScript type). -lowlight.registerLanguage('markdown', md) +###### Type -console.log(lowlight.listLanguages()) // => ['markdown'] +```ts +export type {LanguageFn} from 'highlight.js' ``` +### `Options` + +Configuration for `highlight` (TypeScript type). + +###### Fields + +* `prefix` (`string`, default: `'hljs-'`) + — class prefix + ## Examples ### Example: serializing hast as html @@ -317,9 +381,11 @@ hast trees as returned by lowlight can be serialized with [`hast-util-to-html`][hast-util-to-html]: ```js -import {lowlight} from 'lowlight' +import {common, createLowlight} from 'lowlight' import {toHtml} from 'hast-util-to-html' +const lowlight = createLowlight(common) + const tree = lowlight.highlight('js', '"use strict";') console.log(toHtml(tree)) @@ -331,31 +397,34 @@ Yields: "use strict"; ``` -### Example: turning hast into react nodes +### Example: turning hast into preact, react, etc -hast trees as returned by lowlight can be turned into React (or Preact) with -[`hast-to-hyperscript`][hast-to-hyperscript]: +hast trees as returned by lowlight can be turned into nodes of any framework +that supports JSX, such as preact, react, solid, svelte, vue, and more, with +[`hast-util-to-jsx-runtime`][hast-util-to-jsx-runtime]: ```js -import {lowlight} from 'lowlight' -import {toH} from 'hast-to-hyperscript' -import React from 'react' +import {toJsxRuntime} from 'hast-util-to-jsx-runtime' +// @ts-expect-error: react types don’t type these. +import {Fragment, jsx, jsxs} from 'react/jsx-runtime' +import {common, createLowlight} from 'lowlight' + +const lowlight = createLowlight(common) const tree = lowlight.highlight('js', '"use strict";') -const react = toH(React.createElement, tree) -console.log(react) +console.log(toJsxRuntime(tree, {Fragment, jsx, jsxs})) ``` Yields: ```js { - '$$typeof': Symbol(react.element), - type: 'div', - key: 'h-1', + $$typeof: Symbol(react.element), + type: Symbol(react.fragment), + key: null, ref: null, - props: { children: [ [Object], ';' ] }, + props: {children: [[Object], ';']}, _owner: null, _store: {} } @@ -364,7 +433,29 @@ Yields: ## Types This package is fully typed with [TypeScript][]. -It exports the additional types `Root`, `Options`, and `AutoOptions`. +It exports the additional types +[`AutoOptions`][api-auto-options], +[`LanguageFn`][api-language-fn], and +[`Options`][api-options]. + +It also registers `root.data` with `@types/hast`. +If you’re working with the data fields, make sure to import this package +somewhere in your types, as that registers the new fields on the file. + +```js +/** + * @typedef {import('hast').Root} Root + * + * @typedef {import('lowlight')} + */ + +import {VFile} from 'vfile' + +/** @type {Root} */ +const root = {type: 'root', children: []} + +console.log(root.data?.language) //=> TS now knows that this is a `string?`. +``` @@ -372,14 +463,14 @@ It exports the additional types `Root`, `Options`, and `AutoOptions`. ## Data -If you’re using `lowlight/lib/core.js`, no syntaxes are included. -Checked syntaxes are included if you import `lowlight` (or explicitly -`lowlight/lib/common.js`). -Unchecked syntaxes are available through `lowlight/lib/all.js`. -You can import `core` or `common` and manually add more languages as you please. +If you’re using `createLowlight()`, no syntaxes are included yet. +You can import `all` or `common` and pass them, such as with +`createLowlight(all)`. +Checked syntaxes are included in `common`. +All syntaxes are included in `all`. -`highlight.js` operates as a singleton: once you register a language in one -place, it’ll be available everywhere. +You can also manually import syntaxes from `highlight.js/lib/languages/xxx`, +where `xxx` is the name, such as `'highlight.js/lib/languages/wasm'`. @@ -586,14 +677,17 @@ If you are in a browser, you can use any `highlight.js` theme. For example, to get GitHub Dark from cdnjs: ```html - + ``` ## Compatibility -This package is at least compatible with all maintained versions of Node.js. -As of now, that is Node.js 14.14+ and 16.0+. -It also works in Deno and modern browsers. +This package is 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, +`lowlight@^2`, compatible with Node.js 12. ## Security @@ -662,11 +756,9 @@ See [How to Contribute to Open Source][contribute]. [contribute]: https://opensource.guide/how-to-contribute/ -[root]: https://github.com/syntax-tree/hast#root - -[highlight.js]: https://github.com/highlightjs/highlight.js +[hast-root]: https://github.com/syntax-tree/hast#root -[syntax]: https://github.com/highlightjs/highlight.js/blob/main/docs/language-guide.rst +[highlight-js]: https://github.com/highlightjs/highlight.js [names]: https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md @@ -680,4 +772,16 @@ See [How to Contribute to Open Source][contribute]. [hast-util-to-html]: https://github.com/syntax-tree/hast-util-to-html -[hast-to-hyperscript]: https://github.com/syntax-tree/hast-to-hyperscript +[hast-util-to-jsx-runtime]: https://github.com/syntax-tree/hast-util-to-jsx-runtime + +[api-all]: #all + +[api-auto-options]: #autooptions + +[api-common]: #common + +[api-create-lowlight]: #createlowlightgrammars + +[api-language-fn]: #languagefn + +[api-options]: #options diff --git a/script/count.js b/script/count.js deleted file mode 100644 index af69bb4..0000000 --- a/script/count.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @typedef {import('mdast').List} List - * @typedef {import('mdast').Root} Root - */ - -import fs from 'node:fs/promises' -import {zone} from 'mdast-zone' - -/** @type {{common: Array, uncommon: Array}} */ -const data = JSON.parse( - String(await fs.readFile(new URL('data.json', import.meta.url))) -) - -/** - * Generate count. - * - * @returns - * Transform. - */ -export default function count() { - /** - * Transform. - * - * @param {Root} tree - * Tree. - * @returns {undefined} - * Nothing. - */ - return function (tree) { - zone(tree, 'index', function (start, _, end) { - const {common, uncommon} = data - /** @type {List} */ - const list = { - type: 'list', - spread: false, - children: [ - { - type: 'listItem', - children: [ - { - type: 'paragraph', - children: [ - {type: 'inlineCode', value: 'lib/core.js'}, - {type: 'text', value: ' — 0 languages'} - ] - } - ] - }, - { - type: 'listItem', - children: [ - { - type: 'paragraph', - children: [ - {type: 'inlineCode', value: 'lib/common.js'}, - { - type: 'text', - value: ' (default) — ' + common.length + ' languages' - } - ] - } - ] - }, - { - type: 'listItem', - children: [ - { - type: 'paragraph', - children: [ - {type: 'inlineCode', value: 'lib/all.js'}, - { - type: 'text', - value: - ' — ' + (common.length + uncommon.length) + ' languages' - } - ] - } - ] - } - ] - } - - return [start, list, end] - }) - } -}