New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mdast-util-directive

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mdast-util-directive - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

lib/index.d.ts.map

51

index.d.ts
import type {
BlockContent,
Data,
DefinitionContent,
Parent,
BlockContent,
DefinitionContent,
PhrasingContent

@@ -12,2 +12,33 @@ } from 'mdast'

/**
* Configuration.
*/
export interface ToMarkdownOptions {
/**
* Collapse empty attributes: get `title` instead of `title=""`
* (default: `true`).
*/
collapseEmptyAttributes?: boolean | null | undefined
/**
* Prefer `#` and `.` shortcuts for `id` and `class`
* (default: `true`).
*/
preferShortcut?: boolean | null | undefined
/**
* Leave attributes unquoted if that results in less bytes
* (default: `false`).
*/
preferUnquoted?: boolean | null | undefined
/**
* Use the other quote if that results in less bytes
* (default: `false`).
*/
quoteSmart?: boolean | null | undefined
/**
* Preferred quote to use around attribute values
* (default: the `quote` used by `mdast-util-to-markdown` for titles).
*/
quote?: '"' | "'" | null | undefined
}
/**
* Fields shared by directives.

@@ -17,10 +48,10 @@ */

/**
* Directive name.
* Directive attributes.
*/
name: string
attributes?: Record<string, string | null | undefined> | null | undefined
/**
* Directive attributes.
* Directive name.
*/
attributes?: Record<string, string | null | undefined> | null | undefined
name: string
}

@@ -31,3 +62,3 @@

*/
export interface ContainerDirective extends Parent, DirectiveFields {
export interface ContainerDirective extends DirectiveFields, Parent {
/**

@@ -66,3 +97,3 @@ * Node type of container directive.

*/
children: PhrasingContent[]
children: Array<PhrasingContent>

@@ -83,3 +114,3 @@ /**

*/
export interface TextDirective extends Parent, DirectiveFields {
export interface TextDirective extends DirectiveFields, Parent {
/**

@@ -93,3 +124,3 @@ * Node type of text directive.

*/
children: PhrasingContent[]
children: Array<PhrasingContent>

@@ -96,0 +127,0 @@ /**

23

lib/index.d.ts

@@ -8,3 +8,3 @@ /**

*/
export function directiveFromMarkdown(): FromMarkdownExtension
export function directiveFromMarkdown(): FromMarkdownExtension;
/**

@@ -14,18 +14,11 @@ * Create an extension for `mdast-util-to-markdown` to enable directives in

*
* @param {Readonly<ToMarkdownOptions> | null | undefined} [options]
* Configuration (optional).
* @returns {ToMarkdownExtension}
* Extension for `mdast-util-to-markdown` to enable directives.
*/
export function directiveToMarkdown(): ToMarkdownExtension
export type Nodes = import('mdast').Nodes
export type Paragraph = import('mdast').Paragraph
export type CompileContext = import('mdast-util-from-markdown').CompileContext
export type FromMarkdownExtension = import('mdast-util-from-markdown').Extension
export type FromMarkdownHandle = import('mdast-util-from-markdown').Handle
export type Token = import('mdast-util-from-markdown').Token
export type ConstructName = import('mdast-util-to-markdown').ConstructName
export type ToMarkdownHandle = import('mdast-util-to-markdown').Handle
export type ToMarkdownExtension = import('mdast-util-to-markdown').Options
export type State = import('mdast-util-to-markdown').State
export type Directives = import('../index.js').Directives
export type LeafDirective = import('../index.js').LeafDirective
export type TextDirective = import('../index.js').TextDirective
export function directiveToMarkdown(options?: Readonly<ToMarkdownOptions> | null | undefined): ToMarkdownExtension;
import type { Extension as FromMarkdownExtension } from 'mdast-util-from-markdown';
import type { ToMarkdownOptions } from 'mdast-util-directive';
import type { Options as ToMarkdownExtension } from 'mdast-util-to-markdown';
//# sourceMappingURL=index.d.ts.map
/**
* @typedef {import('mdast').Nodes} Nodes
* @typedef {import('mdast').Paragraph} Paragraph
*
* @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext
* @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension
* @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle
* @typedef {import('mdast-util-from-markdown').Token} Token
*
* @typedef {import('mdast-util-to-markdown').ConstructName} ConstructName
* @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle
* @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension
* @typedef {import('mdast-util-to-markdown').State} State
*
* @typedef {import('../index.js').Directives} Directives
* @typedef {import('../index.js').LeafDirective} LeafDirective
* @typedef {import('../index.js').TextDirective} TextDirective
* @import {Directives, LeafDirective, TextDirective, ToMarkdownOptions} from 'mdast-util-directive'
* @import {
* CompileContext,
* Extension as FromMarkdownExtension,
* Handle as FromMarkdownHandle,
* Token
* } from 'mdast-util-from-markdown'
* @import {
* ConstructName,
* Handle as ToMarkdownHandle,
* Options as ToMarkdownExtension,
* State
* } from 'mdast-util-to-markdown'
* @import {Nodes, Paragraph} from 'mdast'
*/
import {ccount} from 'ccount'
import {ok as assert} from 'devlop'

@@ -27,6 +26,8 @@ import {parseEntities} from 'parse-entities'

/** @type {Readonly<ToMarkdownOptions>} */
const emptyOptions = {}
const shortcut = /^[^\t\n\r "#'.<=>`}]+$/
const unquoted = /^[^\t\n\r "'<=>`}]+$/
handleDirective.peek = peekDirective
/**

@@ -86,7 +87,29 @@ * Create an extension for `mdast-util-from-markdown` to enable directives in

*
* @param {Readonly<ToMarkdownOptions> | null | undefined} [options]
* Configuration (optional).
* @returns {ToMarkdownExtension}
* Extension for `mdast-util-to-markdown` to enable directives.
*/
export function directiveToMarkdown() {
export function directiveToMarkdown(options) {
const settings = options || emptyOptions
if (
settings.quote !== '"' &&
settings.quote !== "'" &&
settings.quote !== null &&
settings.quote !== undefined
) {
throw new Error(
'Invalid quote `' + settings.quote + '`, expected `\'` or `"`'
)
}
handleDirective.peek = peekDirective
return {
handlers: {
containerDirective: handleDirective,
leafDirective: handleDirective,
textDirective: handleDirective
},
unsafe: [

@@ -108,9 +131,176 @@ {

{atBreak: true, character: ':', after: ':'}
],
handlers: {
containerDirective: handleDirective,
leafDirective: handleDirective,
textDirective: handleDirective
]
}
/**
* @type {ToMarkdownHandle}
* @param {Directives} node
*/
function handleDirective(node, _, state, info) {
const tracker = state.createTracker(info)
const sequence = fence(node)
const exit = state.enter(node.type)
let value = tracker.move(sequence + (node.name || ''))
/** @type {LeafDirective | Paragraph | TextDirective | undefined} */
let label
if (node.type === 'containerDirective') {
const head = (node.children || [])[0]
label = inlineDirectiveLabel(head) ? head : undefined
} else {
label = node
}
if (label && label.children && label.children.length > 0) {
const exit = state.enter('label')
/** @type {ConstructName} */
const labelType = `${node.type}Label`
const subexit = state.enter(labelType)
value += tracker.move('[')
value += tracker.move(
state.containerPhrasing(label, {
...tracker.current(),
before: value,
after: ']'
})
)
value += tracker.move(']')
subexit()
exit()
}
value += tracker.move(attributes(node, state))
if (node.type === 'containerDirective') {
const head = (node.children || [])[0]
let shallow = node
if (inlineDirectiveLabel(head)) {
shallow = Object.assign({}, node, {children: node.children.slice(1)})
}
if (shallow && shallow.children && shallow.children.length > 0) {
value += tracker.move('\n')
value += tracker.move(state.containerFlow(shallow, tracker.current()))
}
value += tracker.move('\n' + sequence)
}
exit()
return value
}
/**
* @param {Directives} node
* @param {State} state
* @returns {string}
*/
function attributes(node, state) {
const attributes = node.attributes || {}
/** @type {Array<string>} */
const values = []
/** @type {string | undefined} */
let classesFull
/** @type {string | undefined} */
let classes
/** @type {string | undefined} */
let id
/** @type {string} */
let key
for (key in attributes) {
if (
own.call(attributes, key) &&
attributes[key] !== undefined &&
attributes[key] !== null
) {
const value = String(attributes[key])
// To do: next major:
// Do not reorder `id` and `class` attributes when they do not turn into
// shortcuts.
// Additionally, join shortcuts: `#a .b.c d="e"` -> `#a.b.c d="e"`
if (key === 'id') {
id =
settings.preferShortcut !== false && shortcut.test(value)
? '#' + value
: quoted('id', value, node, state)
} else if (key === 'class') {
const list = value.split(/[\t\n\r ]+/g)
/** @type {Array<string>} */
const classesFullList = []
/** @type {Array<string>} */
const classesList = []
let index = -1
while (++index < list.length) {
;(settings.preferShortcut !== false && shortcut.test(list[index])
? classesList
: classesFullList
).push(list[index])
}
classesFull =
classesFullList.length > 0
? quoted('class', classesFullList.join(' '), node, state)
: ''
classes = classesList.length > 0 ? '.' + classesList.join('.') : ''
} else {
values.push(quoted(key, value, node, state))
}
}
}
if (classesFull) {
values.unshift(classesFull)
}
if (classes) {
values.unshift(classes)
}
if (id) {
values.unshift(id)
}
return values.length > 0 ? '{' + values.join(' ') + '}' : ''
}
/**
* @param {string} key
* @param {string} value
* @param {Directives} node
* @param {State} state
* @returns {string}
*/
function quoted(key, value, node, state) {
if (settings.collapseEmptyAttributes !== false && !value) return key
if (settings.preferUnquoted && unquoted.test(value)) {
return key + '=' + value
}
// If the alternative is less common than `quote`, switch.
const preferred = settings.quote || state.options.quote || '"'
const alternative = preferred === '"' ? "'" : '"'
// If the alternative is less common than `quote`, switch.
const appliedQuote =
settings.quoteSmart &&
ccount(value, preferred) > ccount(value, alternative)
? alternative
: preferred
const subset =
node.type === 'textDirective'
? [appliedQuote]
: [appliedQuote, '\n', '\r']
return (
key +
'=' +
appliedQuote +
stringifyEntitiesLight(value, {subset}) +
appliedQuote
)
}
}

@@ -202,5 +392,3 @@

'id',
parseEntities(this.sliceSerialize(token), {
attribute: true
})
parseEntities(this.sliceSerialize(token), {attribute: true})
])

@@ -218,5 +406,3 @@ }

'class',
parseEntities(this.sliceSerialize(token), {
attribute: true
})
parseEntities(this.sliceSerialize(token), {attribute: true})
])

@@ -290,65 +476,2 @@ }

/**
* @type {ToMarkdownHandle}
* @param {Directives} node
*/
function handleDirective(node, _, state, info) {
const tracker = state.createTracker(info)
const sequence = fence(node)
const exit = state.enter(node.type)
let value = tracker.move(sequence + (node.name || ''))
/** @type {LeafDirective | Paragraph | TextDirective | undefined} */
let label
if (node.type === 'containerDirective') {
const head = (node.children || [])[0]
label = inlineDirectiveLabel(head) ? head : undefined
} else {
label = node
}
if (label && label.children && label.children.length > 0) {
const exit = state.enter('label')
/** @type {ConstructName} */
const labelType = `${node.type}Label`
const subexit = state.enter(labelType)
value += tracker.move('[')
value += tracker.move(
// @ts-expect-error: `containerPhrasing` is typed correctly, but TS
// generates *hardcoded* types, which means that our dynamically added
// directives are not present.
// At some point, TS should fix that, and `from-markdown` should be fine.
state.containerPhrasing(label, {
...tracker.current(),
before: value,
after: ']'
})
)
value += tracker.move(']')
subexit()
exit()
}
value += tracker.move(attributes(node, state))
if (node.type === 'containerDirective') {
const head = (node.children || [])[0]
let shallow = node
if (inlineDirectiveLabel(head)) {
shallow = Object.assign({}, node, {children: node.children.slice(1)})
}
if (shallow && shallow.children && shallow.children.length > 0) {
value += tracker.move('\n')
value += tracker.move(state.containerFlow(shallow, tracker.current()))
}
value += tracker.move('\n' + sequence)
}
exit()
return value
}
/** @type {ToMarkdownHandle} */

@@ -360,86 +483,2 @@ function peekDirective() {

/**
* @param {Directives} node
* @param {State} state
* @returns {string}
*/
function attributes(node, state) {
const quote = state.options.quote || '"'
const subset = node.type === 'textDirective' ? [quote] : [quote, '\n', '\r']
const attrs = node.attributes || {}
/** @type {Array<string>} */
const values = []
/** @type {string | undefined} */
let classesFull
/** @type {string | undefined} */
let classes
/** @type {string | undefined} */
let id
/** @type {string} */
let key
for (key in attrs) {
if (
own.call(attrs, key) &&
attrs[key] !== undefined &&
attrs[key] !== null
) {
const value = String(attrs[key])
if (key === 'id') {
id = shortcut.test(value) ? '#' + value : quoted('id', value)
} else if (key === 'class') {
const list = value.split(/[\t\n\r ]+/g)
/** @type {Array<string>} */
const classesFullList = []
/** @type {Array<string>} */
const classesList = []
let index = -1
while (++index < list.length) {
;(shortcut.test(list[index]) ? classesList : classesFullList).push(
list[index]
)
}
classesFull =
classesFullList.length > 0
? quoted('class', classesFullList.join(' '))
: ''
classes = classesList.length > 0 ? '.' + classesList.join('.') : ''
} else {
values.push(quoted(key, value))
}
}
}
if (classesFull) {
values.unshift(classesFull)
}
if (classes) {
values.unshift(classes)
}
if (id) {
values.unshift(id)
}
return values.length > 0 ? '{' + values.join(' ') + '}' : ''
/**
* @param {string} key
* @param {string} value
* @returns {string}
*/
function quoted(key, value) {
return (
key +
(value
? '=' + quote + stringifyEntitiesLight(value, {subset}) + quote
: '')
)
}
}
/**
* @param {Nodes} node

@@ -446,0 +485,0 @@ * @returns {node is Paragraph & {data: {directiveLabel: true}}}

{
"name": "mdast-util-directive",
"version": "3.0.0",
"description": "mdast extension to parse and serialize generic directives (`:cite[smith04]`)",
"license": "MIT",
"keywords": [
"unist",
"mdast",
"mdast-util",
"util",
"utility",
"markdown",
"markup",
"generic",
"directive",
"container",
"extension"
],
"repository": "syntax-tree/mdast-util-directive",
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"bugs": "https://github.com/syntax-tree/mdast-util-directive/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"sideEffects": false,
"type": "module",
"exports": "./index.js",
"files": [
"lib/",
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/mdast": "^4.0.0",
"@types/unist": "^3.0.0",
"ccount": "^2.0.0",
"devlop": "^1.0.0",

@@ -47,24 +18,40 @@ "mdast-util-from-markdown": "^2.0.0",

},
"description": "mdast extension to parse and serialize generic directives (`:cite[smith04]`)",
"devDependencies": {
"@types/node": "^20.0.0",
"c8": "^8.0.0",
"@types/node": "^22.0.0",
"c8": "^10.0.0",
"micromark-extension-directive": "^3.0.0",
"prettier": "^2.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"prettier": "^3.0.0",
"remark-cli": "^12.0.0",
"remark-preset-wooorm": "^10.0.0",
"type-coverage": "^2.0.0",
"typescript": "^5.0.0",
"unist-util-remove-position": "^5.0.0",
"xo": "^0.54.0"
"xo": "^0.60.0"
},
"scripts": {
"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-prod": "node --conditions production test.js",
"test-api-dev": "node --conditions development test.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"
"exports": "./index.js",
"files": [
"index.d.ts",
"index.js",
"lib/"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"keywords": [
"container",
"directive",
"extension",
"generic",
"markdown",
"markup",
"mdast-util",
"mdast",
"unist",
"utility",
"util"
],
"license": "MIT",
"name": "mdast-util-directive",
"prettier": {

@@ -83,8 +70,19 @@ "bracketSpacing": false,

},
"repository": "syntax-tree/mdast-util-directive",
"scripts": {
"build": "tsc --build --clean && tsc --build && type-coverage",
"format": "remark --frail --output --quiet -- . && prettier --log-level warn --write -- . && xo --fix",
"test-api-dev": "node --conditions development test.js",
"test-api-prod": "node --conditions production test.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"
},
"sideEffects": false,
"typeCoverage": {
"atLeast": 100,
"detail": true,
"ignoreCatch": true,
"strict": true
},
"type": "module",
"version": "3.1.0",
"xo": {

@@ -94,12 +92,29 @@ "overrides": [

"files": [
"**/*.ts"
"**/*.d.ts"
],
"rules": {
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/consistent-type-definitions": "off"
"@typescript-eslint/array-type": [
"error",
{
"default": "generic"
}
],
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true
}
],
"@typescript-eslint/consistent-type-definitions": [
"error",
"interface"
]
}
}
],
"prettier": true
"prettier": true,
"rules": {
"unicorn/prefer-at": "off"
}
}
}

@@ -17,23 +17,24 @@ # mdast-util-directive

* [What is this?](#what-is-this)
* [When to use this](#when-to-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`directiveFromMarkdown()`](#directivefrommarkdown)
* [`directiveToMarkdown()`](#directivetomarkdown)
* [`ContainerDirective`](#containerdirective)
* [`Directives`](#directives)
* [`LeafDirective`](#leafdirective)
* [`TextDirective`](#textdirective)
* [HTML](#html)
* [Syntax](#syntax)
* [Syntax tree](#syntax-tree)
* [Nodes](#nodes)
* [Mixin](#mixin)
* [Types](#types)
* [Compatibility](#compatibility)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
* [What is this?](#what-is-this)
* [When to use this](#when-to-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`directiveFromMarkdown()`](#directivefrommarkdown)
* [`directiveToMarkdown(options?)`](#directivetomarkdownoptions)
* [`ContainerDirective`](#containerdirective)
* [`Directives`](#directives)
* [`LeafDirective`](#leafdirective)
* [`TextDirective`](#textdirective)
* [`ToMarkdownOptions`](#tomarkdownoptions)
* [HTML](#html)
* [Syntax](#syntax)
* [Syntax tree](#syntax-tree)
* [Nodes](#nodes)
* [Mixin](#mixin)
* [Types](#types)
* [Compatibility](#compatibility)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)

@@ -181,3 +182,3 @@ ## What is this?

### `directiveToMarkdown()`
### `directiveToMarkdown(options?)`

@@ -187,5 +188,8 @@ Create an extension for [`mdast-util-to-markdown`][mdast-util-to-markdown]

There are no options, but passing [`options.quote`][quote] to
`mdast-util-to-markdown` is honored for attributes.
###### Parameters
* `options`
([`ToMarkdownOptions`][api-to-markdown-options], optional)
— configuration
###### Returns

@@ -260,2 +264,25 @@

### `ToMarkdownOptions`
Configuration.
###### Parameters
* `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 `mdast-util-to-markdown` for titles)
— preferred quote to use around attribute values
## HTML

@@ -436,3 +463,4 @@

/**
* @typedef {import('mdast-util-directive')}
* @import {} from 'mdast-util-directive'
* @import {Root} from 'mdast'
*/

@@ -442,3 +470,3 @@

/** @type {import('mdast').Root} */
/** @type {Root} */
const tree = getMdastNodeSomeHow()

@@ -466,6 +494,6 @@

* [`remarkjs/remark-directive`][remark-directive]
— remark plugin to support generic directives
* [`micromark/micromark-extension-directive`][extension]
— micromark extension to parse directives
* [`remarkjs/remark-directive`][remark-directive]
— remark plugin to support generic directives
* [`micromark/micromark-extension-directive`][extension]
— micromark extension to parse directives

@@ -568,4 +596,6 @@ ## Contribute

[api-directive-to-markdown]: #directivetomarkdown
[api-directive-to-markdown]: #directivetomarkdownoptions
[api-to-markdown-options]: #tomarkdownoptions
[api-container-directive]: #containerdirective

@@ -572,0 +602,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc