Socket
Socket
Sign inDemoInstall

micromark-extension-frontmatter

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

micromark-extension-frontmatter - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

5

dev/index.d.ts

@@ -0,3 +1,6 @@

export {frontmatter} from './lib/syntax.js'
export {frontmatterHtml} from './lib/html.js'
export {frontmatter} from './lib/syntax.js'
export type Info = import('./matters.js').Info
export type Matter = import('./matters.js').Matter
export type Options = import('./matters.js').Options
export type Preset = import('./matters.js').Preset
/**
* @typedef {import('./matters.js').Info} Info
* @typedef {import('./matters.js').Matter} Matter
* @typedef {import('./matters.js').Options} Options
* @typedef {import('./matters.js').Preset} Preset
*/
export {frontmatter} from './lib/syntax.js'
export {frontmatterHtml} from './lib/html.js'
export {frontmatter} from './lib/syntax.js'

21

dev/lib/html.d.ts
/**
* Add support for turning frontmatter in markdown to HTML.
* Create an extension for `micromark` to support frontmatter when serializing
* to HTML.
*
* Function that can be called to get an HTML extension for micromark (passed
* in `htmlExtensions`).
* > πŸ‘‰ **Note**: this makes sure nothing is generated in the output HTML for
* > frontmatter.
*
* This makes sure nothing is generated for frontmatter.
*
* Supports YAML by default.
* Can be configured to support other things.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {HtmlExtension}
* HTML extension for micromark (passed in `htmlExtensions`).
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support frontmatter when serializing to HTML.
*/
export function frontmatterHtml(
options?: import('../matters.js').Options | undefined
options?: Options | null | undefined
): HtmlExtension

@@ -20,0 +17,0 @@ export type HtmlExtension = import('micromark-util-types').HtmlExtension

@@ -11,19 +11,16 @@ /**

/**
* Add support for turning frontmatter in markdown to HTML.
* Create an extension for `micromark` to support frontmatter when serializing
* to HTML.
*
* Function that can be called to get an HTML extension for micromark (passed
* in `htmlExtensions`).
* > πŸ‘‰ **Note**: this makes sure nothing is generated in the output HTML for
* > frontmatter.
*
* This makes sure nothing is generated for frontmatter.
*
* Supports YAML by default.
* Can be configured to support other things.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {HtmlExtension}
* HTML extension for micromark (passed in `htmlExtensions`).
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support frontmatter when serializing to HTML.
*/
export function frontmatterHtml(options) {
const settings = matters(options)
const listOfMatters = matters(options)
/** @type {HtmlExtension['enter']} */

@@ -35,4 +32,4 @@ const enter = {}

while (++index < settings.length) {
const type = settings[index].type
while (++index < listOfMatters.length) {
const type = listOfMatters[index].type
enter[type] = start

@@ -39,0 +36,0 @@ exit[type] = end

/**
* Add support for parsing frontmatter in markdown.
* Create an extension for `micromark` to enable frontmatter syntax.
*
* Function that can be called to get a syntax extension for micromark (passed
* in `extensions`).
*
* Supports YAML by default.
* Can be configured to support TOML and more.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Extension}
* Syntax extension for micromark (passed in `extensions`).
* Extension for `micromark` that can be passed in `extensions`, to
* enable frontmatter syntax.
*/
export function frontmatter(
options?: import('../matters.js').Options | undefined
): Extension
export function frontmatter(options?: Options | null | undefined): Extension
export type Construct = import('micromark-util-types').Construct
export type ConstructRecord = import('micromark-util-types').ConstructRecord
export type Extension = import('micromark-util-types').Extension
export type ConstructRecord = import('micromark-util-types').ConstructRecord
export type Construct = import('micromark-util-types').Construct
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 TokenizeContext = import('micromark-util-types').TokenizeContext
export type State = import('micromark-util-types').State
export type Info = import('../matters.js').Info
export type Matter = import('../matters.js').Matter
export type Options = import('../matters.js').Options
export type Matter = import('../matters.js').Matter
export type Info = import('../matters.js').Info
/**
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
* @typedef {import('micromark-util-types').Construct} Construct
* @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').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').State} State
*
* @typedef {import('../matters.js').Info} Info
* @typedef {import('../matters.js').Matter} Matter
* @typedef {import('../matters.js').Options} Options
* @typedef {import('../matters.js').Matter} Matter
* @typedef {import('../matters.js').Info} Info
*/

@@ -19,17 +20,12 @@

/**
* Add support for parsing frontmatter in markdown.
* Create an extension for `micromark` to enable frontmatter syntax.
*
* Function that can be called to get a syntax extension for micromark (passed
* in `extensions`).
*
* Supports YAML by default.
* Can be configured to support TOML and more.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Extension}
* Syntax extension for micromark (passed in `extensions`).
* Extension for `micromark` that can be passed in `extensions`, to
* enable frontmatter syntax.
*/
export function frontmatter(options) {
const settings = matters(options)
const listOfMatters = matters(options)
/** @type {ConstructRecord} */

@@ -39,10 +35,13 @@ const flow = {}

while (++index < settings.length) {
const matter = settings[index]
while (++index < listOfMatters.length) {
const matter = listOfMatters[index]
const code = fence(matter, 'open').charCodeAt(0)
if (code in flow) {
// @ts-expect-error it clearly does exist.
flow[code].push(parse(matter))
const construct = createConstruct(matter)
const existing = flow[code]
if (Array.isArray(existing)) {
existing.push(construct)
} else {
flow[code] = [parse(matter)]
// Never a single object, always an array.
flow[code] = [construct]
}

@@ -58,11 +57,17 @@ }

*/
function parse(matter) {
const name = matter.type
function createConstruct(matter) {
const anywhere = matter.anywhere
const valueType = name + 'Value'
const fenceType = name + 'Fence'
const frontmatterType = matter.type
const fenceType = frontmatterType + 'Fence'
const sequenceType = fenceType + 'Sequence'
const fenceConstruct = {tokenize: tokenizeFence, partial: true}
/** @type {string} */
const valueType = frontmatterType + 'Value'
const closingFenceConstruct = {tokenize: tokenizeClosingFence, partial: true}
/**
* Fence to look for.
*
* @type {string}
*/
let buffer
let bufferIndex = 0

@@ -80,44 +85,175 @@ return {tokenize: tokenizeFrontmatter, concrete: true}

/** @type {State} */
/**
* Start of frontmatter.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function start(code) {
const position = self.now()
if (position.column !== 1 || (!anywhere && position.line !== 1)) {
return nok(code)
if (
// Indent not allowed.
position.column === 1 &&
// Normally, only allowed in first line.
(position.line === 1 || anywhere)
) {
buffer = fence(matter, 'open')
bufferIndex = 0
if (code === buffer.charCodeAt(bufferIndex)) {
effects.enter(frontmatterType)
effects.enter(fenceType)
effects.enter(sequenceType)
return openSequence(code)
}
}
effects.enter(name)
buffer = fence(matter, 'open')
return effects.attempt(fenceConstruct, afterOpeningFence, nok)(code)
return nok(code)
}
/** @type {State} */
function afterOpeningFence(code) {
buffer = fence(matter, 'close')
return lineEnd(code)
/**
* In open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openSequence(code) {
if (bufferIndex === buffer.length) {
effects.exit(sequenceType)
if (markdownSpace(code)) {
effects.enter(types.whitespace)
return openSequenceWhitespace(code)
}
return openAfter(code)
}
if (code === buffer.charCodeAt(bufferIndex++)) {
effects.consume(code)
return openSequence
}
return nok(code)
}
/** @type {State} */
function lineStart(code) {
/**
* In whitespace after open sequence.
*
* ```markdown
* > | ---␠
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openSequenceWhitespace(code) {
if (markdownSpace(code)) {
effects.consume(code)
return openSequenceWhitespace
}
effects.exit(types.whitespace)
return openAfter(code)
}
/**
* After open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openAfter(code) {
if (markdownLineEnding(code)) {
effects.exit(fenceType)
effects.enter(types.lineEnding)
effects.consume(code)
effects.exit(types.lineEnding)
// Get ready for closing fence.
buffer = fence(matter, 'close')
bufferIndex = 0
return effects.attempt(closingFenceConstruct, after, contentStart)
}
// EOF is not okay.
return nok(code)
}
/**
* Start of content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentStart(code) {
if (code === codes.eof || markdownLineEnding(code)) {
return lineEnd(code)
return contentEnd(code)
}
effects.enter(valueType)
return lineData(code)
return contentInside(code)
}
/** @type {State} */
function lineData(code) {
/**
* In content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentInside(code) {
if (code === codes.eof || markdownLineEnding(code)) {
effects.exit(valueType)
return lineEnd(code)
return contentEnd(code)
}
effects.consume(code)
return lineData
return contentInside
}
/** @type {State} */
function lineEnd(code) {
/**
* End of content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentEnd(code) {
// Require a closing fence.

@@ -132,8 +268,20 @@ if (code === codes.eof) {

effects.exit(types.lineEnding)
return effects.attempt(fenceConstruct, after, lineStart)
return effects.attempt(closingFenceConstruct, after, contentStart)
}
/** @type {State} */
/**
* After frontmatter.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function after(code) {
effects.exit(name)
// `code` must be eol/eof.
effects.exit(frontmatterType)
return ok(code)

@@ -144,13 +292,24 @@ }

/** @type {Tokenizer} */
function tokenizeFence(effects, ok, nok) {
function tokenizeClosingFence(effects, ok, nok) {
let bufferIndex = 0
return start
return closeStart
/** @type {State} */
function start(code) {
/**
* Start of close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeStart(code) {
if (code === buffer.charCodeAt(bufferIndex)) {
effects.enter(fenceType)
effects.enter(sequenceType)
return insideSequence(code)
return closeSequence(code)
}

@@ -161,4 +320,15 @@

/** @type {State} */
function insideSequence(code) {
/**
* In close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeSequence(code) {
if (bufferIndex === buffer.length) {

@@ -169,6 +339,6 @@ effects.exit(sequenceType)

effects.enter(types.whitespace)
return insideWhitespace(code)
return closeSequenceWhitespace(code)
}
return fenceEnd(code)
return closeAfter(code)
}

@@ -178,3 +348,3 @@

effects.consume(code)
return insideSequence
return closeSequence
}

@@ -185,15 +355,37 @@

/** @type {State} */
function insideWhitespace(code) {
/**
* In whitespace after close sequence.
*
* ```markdown
* > | ---
* | title: "Venus"
* | ---␠
* ^
* ```
*
* @type {State}
*/
function closeSequenceWhitespace(code) {
if (markdownSpace(code)) {
effects.consume(code)
return insideWhitespace
return closeSequenceWhitespace
}
effects.exit(types.whitespace)
return fenceEnd(code)
return closeAfter(code)
}
/** @type {State} */
function fenceEnd(code) {
/**
* After close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeAfter(code) {
if (code === codes.eof || markdownLineEnding(code)) {

@@ -211,3 +403,3 @@ effects.exit(fenceType)

* @param {Matter} matter
* @param {'open'|'close'} prop
* @param {'open' | 'close'} prop
* @returns {string}

@@ -223,4 +415,4 @@ */

/**
* @param {Info|string} schema
* @param {'open'|'close'} prop
* @param {Info | string} schema
* @param {'open' | 'close'} prop
* @returns {string}

@@ -227,0 +419,0 @@ */

/**
* @param {Options} [options='yaml']
* Simplify one or more options.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Array<Matter>}
* List of matters.
*/
export function matters(options?: Options | undefined): Array<Matter>
export function matters(options?: Options | null | undefined): Array<Matter>
/**
* Either `'yaml'` or `'toml'`.
* Known name of a frontmatter style.
*/
export type Preset = 'yaml' | 'toml'
export type Preset = 'toml' | 'yaml'
/**
* Sequence.
*
* Depending on how this structure is used, it reflects a marker or a fence.
*/
export type Info = {
/**
* Opening.
*/
open: string
/**
* Closing.
*/
close: string
}
/**
* Fields describing a kind of matter.
*/
export type MatterProps = {
/**
* Type to tokenize as.
* Node type to tokenize as.
*/
type: string
/**
* If `true`, matter can be found anywhere in the document.
* If `false` (default), only matter at the start of the document is
* recognized.
* Whether matter can be found anywhere in the document, normally, only matter
* at the start of the document is recognized.
*
* > πŸ‘‰ **Note**: using this is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*/
anywhere?: boolean | undefined
anywhere?: boolean | null | undefined
}

@@ -31,13 +52,14 @@ /**

/**
* Character used to construct fences.
* By providing an object with `open` and `close` different characters can be
* used for opening and closing fences.
* For example the character `'-'` will result in `'---'` being used as the
* fence
* Character repeated 3 times, used as complete fences.
*
* For example the character `'-'` will result in `'---'` being used as the
* fence
* Pass `open` and `close` to specify different characters for opening and
* closing fences.
*/
marker: string | Info
marker: Info | string
/**
* If `marker` is set, `fence` must not be set.
*/
fence?: undefined
fence?: never
}

@@ -49,21 +71,29 @@ /**

/**
* String used as the complete fence.
* By providing an object with `open` and `close` different values can be used
* for opening and closing fences.
* This can be used too if fences contain different characters or lengths
* other than 3.
* Complete fences.
*
* This can be used when fences contain different characters or lengths
* other than 3.
* Pass `open` and `close` to interface to specify different characters for opening and
* closing fences.
*/
fence: string | Info
fence: Info | string
/**
* If `fence` is set, `marker` must not be set.
*/
marker?: undefined
marker?: never
}
/**
* Matter object describing frontmatter.
* Fields describing a kind of matter.
*
* > πŸ‘‰ **Note**: using `anywhere` is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*
* > πŸ‘‰ **Note**: `marker` and `fence` are mutually exclusive.
* > If `marker` is set, `fence` must not be set, and vice versa.
*/
export type Matter = (MatterProps & FenceProps) | (MatterProps & MarkerProps)
/**
* Matter object or preset, or many.
* Configuration.
*/
export type Options = Preset | Matter | Array<Preset | Matter>
export type Options = Matter | Preset | Array<Matter | Preset>
/**
* @typedef {'yaml'|'toml'} Preset
* Either `'yaml'` or `'toml'`.
* @typedef {'toml' | 'yaml'} Preset
* Known name of a frontmatter style.
*
* @typedef Info
* Sequence.
*
* Depending on how this structure is used, it reflects a marker or a fence.
* @property {string} open
* Opening.
* @property {string} close
* Closing.
*
* @typedef MatterProps
* Fields describing a kind of matter.
* @property {string} type
* Type to tokenize as.
* @property {boolean} [anywhere=false]
* If `true`, matter can be found anywhere in the document.
* If `false` (default), only matter at the start of the document is
* recognized.
* Node type to tokenize as.
* @property {boolean | null | undefined} [anywhere=false]
* Whether matter can be found anywhere in the document, normally, only matter
* at the start of the document is recognized.
*
* > πŸ‘‰ **Note**: using this is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*
* @typedef MarkerProps
* Marker configuration.
* @property {string|Info} marker
* Character used to construct fences.
* By providing an object with `open` and `close` different characters can be
* used for opening and closing fences.
* @property {Info | string} marker
* Character repeated 3 times, used as complete fences.
*
* For example the character `'-'` will result in `'---'` being used as the
* fence
* Pass `open` and `close` to specify different characters for opening and
* closing fences.
* @property {never} [fence]

@@ -30,16 +40,24 @@ * If `marker` is set, `fence` must not be set.

* Fence configuration.
* @property {string|Info} fence
* String used as the complete fence.
* By providing an object with `open` and `close` different values can be used
* for opening and closing fences.
* This can be used too if fences contain different characters or lengths
* @property {Info | string} fence
* Complete fences.
*
* This can be used when fences contain different characters or lengths
* other than 3.
* Pass `open` and `close` to interface to specify different characters for opening and
* closing fences.
* @property {never} [marker]
* If `fence` is set, `marker` must not be set.
*
* @typedef {(MatterProps & FenceProps)|(MatterProps & MarkerProps)} Matter
* Matter object describing frontmatter.
* @typedef {(MatterProps & FenceProps) | (MatterProps & MarkerProps)} Matter
* Fields describing a kind of matter.
*
* @typedef {Preset|Matter|Array<Preset|Matter>} Options
* Matter object or preset, or many.
* > πŸ‘‰ **Note**: using `anywhere` is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*
* > πŸ‘‰ **Note**: `marker` and `fence` are mutually exclusive.
* > If `marker` is set, `fence` must not be set, and vice versa.
*
* @typedef {Matter | Preset | Array<Matter | Preset>} Options
* Configuration.
*/

@@ -53,25 +71,35 @@

/**
* @param {Options} [options='yaml']
* Simplify one or more options.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Array<Matter>}
* List of matters.
*/
export function matters(options = 'yaml') {
export function matters(options) {
/** @type {Array<Matter>} */
const results = []
const result = []
let index = -1
// One preset or matter.
if (!Array.isArray(options)) {
options = [options]
}
/** @type {Array<Matter | Preset>} */
const presetsOrMatters = Array.isArray(options)
? options
: options
? [options]
: ['yaml']
while (++index < options.length) {
results[index] = matter(options[index])
while (++index < presetsOrMatters.length) {
result[index] = matter(presetsOrMatters[index])
}
return results
return result
}
/**
* @param {Preset|Matter} option
* Simplify an option.
*
* @param {Matter | Preset} option
* Configuration.
* @returns {Matter}
* Matters.
*/

@@ -78,0 +106,0 @@ function matter(option) {

@@ -0,3 +1,6 @@

export {frontmatter} from './lib/syntax.js'
export {frontmatterHtml} from './lib/html.js'
export {frontmatter} from './lib/syntax.js'
export type Info = import('./matters.js').Info
export type Matter = import('./matters.js').Matter
export type Options = import('./matters.js').Options
export type Preset = import('./matters.js').Preset
/**
* @typedef {import('./matters.js').Info} Info
* @typedef {import('./matters.js').Matter} Matter
* @typedef {import('./matters.js').Options} Options
* @typedef {import('./matters.js').Preset} Preset
*/
export {frontmatter} from './lib/syntax.js'
export {frontmatterHtml} from './lib/html.js'
export {frontmatter} from './lib/syntax.js'
/**
* Add support for turning frontmatter in markdown to HTML.
* Create an extension for `micromark` to support frontmatter when serializing
* to HTML.
*
* Function that can be called to get an HTML extension for micromark (passed
* in `htmlExtensions`).
* > πŸ‘‰ **Note**: this makes sure nothing is generated in the output HTML for
* > frontmatter.
*
* This makes sure nothing is generated for frontmatter.
*
* Supports YAML by default.
* Can be configured to support other things.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {HtmlExtension}
* HTML extension for micromark (passed in `htmlExtensions`).
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support frontmatter when serializing to HTML.
*/
export function frontmatterHtml(
options?: import('../matters.js').Options | undefined
options?: Options | null | undefined
): HtmlExtension

@@ -20,0 +17,0 @@ export type HtmlExtension = import('micromark-util-types').HtmlExtension

@@ -11,19 +11,16 @@ /**

/**
* Add support for turning frontmatter in markdown to HTML.
* Create an extension for `micromark` to support frontmatter when serializing
* to HTML.
*
* Function that can be called to get an HTML extension for micromark (passed
* in `htmlExtensions`).
* > πŸ‘‰ **Note**: this makes sure nothing is generated in the output HTML for
* > frontmatter.
*
* This makes sure nothing is generated for frontmatter.
*
* Supports YAML by default.
* Can be configured to support other things.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {HtmlExtension}
* HTML extension for micromark (passed in `htmlExtensions`).
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support frontmatter when serializing to HTML.
*/
export function frontmatterHtml(options) {
const settings = matters(options)
const listOfMatters = matters(options)
/** @type {HtmlExtension['enter']} */

@@ -34,4 +31,4 @@ const enter = {}

let index = -1
while (++index < settings.length) {
const type = settings[index].type
while (++index < listOfMatters.length) {
const type = listOfMatters[index].type
enter[type] = start

@@ -38,0 +35,0 @@ exit[type] = end

/**
* Add support for parsing frontmatter in markdown.
* Create an extension for `micromark` to enable frontmatter syntax.
*
* Function that can be called to get a syntax extension for micromark (passed
* in `extensions`).
*
* Supports YAML by default.
* Can be configured to support TOML and more.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Extension}
* Syntax extension for micromark (passed in `extensions`).
* Extension for `micromark` that can be passed in `extensions`, to
* enable frontmatter syntax.
*/
export function frontmatter(
options?: import('../matters.js').Options | undefined
): Extension
export function frontmatter(options?: Options | null | undefined): Extension
export type Construct = import('micromark-util-types').Construct
export type ConstructRecord = import('micromark-util-types').ConstructRecord
export type Extension = import('micromark-util-types').Extension
export type ConstructRecord = import('micromark-util-types').ConstructRecord
export type Construct = import('micromark-util-types').Construct
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 TokenizeContext = import('micromark-util-types').TokenizeContext
export type State = import('micromark-util-types').State
export type Info = import('../matters.js').Info
export type Matter = import('../matters.js').Matter
export type Options = import('../matters.js').Options
export type Matter = import('../matters.js').Matter
export type Info = import('../matters.js').Info
/**
* @typedef {import('micromark-util-types').Construct} Construct
* @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord
* @typedef {import('micromark-util-types').Construct} Construct
* @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').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').State} State
*
* @typedef {import('../matters.js').Info} Info
* @typedef {import('../matters.js').Matter} Matter
* @typedef {import('../matters.js').Options} Options
* @typedef {import('../matters.js').Matter} Matter
* @typedef {import('../matters.js').Info} Info
*/

@@ -17,28 +18,25 @@

/**
* Add support for parsing frontmatter in markdown.
* Create an extension for `micromark` to enable frontmatter syntax.
*
* Function that can be called to get a syntax extension for micromark (passed
* in `extensions`).
*
* Supports YAML by default.
* Can be configured to support TOML and more.
*
* @param {Options} [options='yaml']
* Configuration (optional).
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Extension}
* Syntax extension for micromark (passed in `extensions`).
* Extension for `micromark` that can be passed in `extensions`, to
* enable frontmatter syntax.
*/
export function frontmatter(options) {
const settings = matters(options)
const listOfMatters = matters(options)
/** @type {ConstructRecord} */
const flow = {}
let index = -1
while (++index < settings.length) {
const matter = settings[index]
while (++index < listOfMatters.length) {
const matter = listOfMatters[index]
const code = fence(matter, 'open').charCodeAt(0)
if (code in flow) {
// @ts-expect-error it clearly does exist.
flow[code].push(parse(matter))
const construct = createConstruct(matter)
const existing = flow[code]
if (Array.isArray(existing)) {
existing.push(construct)
} else {
flow[code] = [parse(matter)]
// Never a single object, always an array.
flow[code] = [construct]
}

@@ -55,14 +53,20 @@ }

*/
function parse(matter) {
const name = matter.type
function createConstruct(matter) {
const anywhere = matter.anywhere
const valueType = name + 'Value'
const fenceType = name + 'Fence'
const frontmatterType = matter.type
const fenceType = frontmatterType + 'Fence'
const sequenceType = fenceType + 'Sequence'
const fenceConstruct = {
tokenize: tokenizeFence,
const valueType = frontmatterType + 'Value'
const closingFenceConstruct = {
tokenize: tokenizeClosingFence,
partial: true
}
/** @type {string} */
/**
* Fence to look for.
*
* @type {string}
*/
let buffer
let bufferIndex = 0
return {

@@ -81,40 +85,165 @@ tokenize: tokenizeFrontmatter,

/** @type {State} */
/**
* Start of frontmatter.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function start(code) {
const position = self.now()
if (position.column !== 1 || (!anywhere && position.line !== 1)) {
return nok(code)
if (
// Indent not allowed.
position.column === 1 &&
// Normally, only allowed in first line.
(position.line === 1 || anywhere)
) {
buffer = fence(matter, 'open')
bufferIndex = 0
if (code === buffer.charCodeAt(bufferIndex)) {
effects.enter(frontmatterType)
effects.enter(fenceType)
effects.enter(sequenceType)
return openSequence(code)
}
}
effects.enter(name)
buffer = fence(matter, 'open')
return effects.attempt(fenceConstruct, afterOpeningFence, nok)(code)
return nok(code)
}
/** @type {State} */
function afterOpeningFence(code) {
buffer = fence(matter, 'close')
return lineEnd(code)
/**
* In open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openSequence(code) {
if (bufferIndex === buffer.length) {
effects.exit(sequenceType)
if (markdownSpace(code)) {
effects.enter('whitespace')
return openSequenceWhitespace(code)
}
return openAfter(code)
}
if (code === buffer.charCodeAt(bufferIndex++)) {
effects.consume(code)
return openSequence
}
return nok(code)
}
/** @type {State} */
function lineStart(code) {
/**
* In whitespace after open sequence.
*
* ```markdown
* > | ---␠
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openSequenceWhitespace(code) {
if (markdownSpace(code)) {
effects.consume(code)
return openSequenceWhitespace
}
effects.exit('whitespace')
return openAfter(code)
}
/**
* After open sequence.
*
* ```markdown
* > | ---
* ^
* | title: "Venus"
* | ---
* ```
*
* @type {State}
*/
function openAfter(code) {
if (markdownLineEnding(code)) {
effects.exit(fenceType)
effects.enter('lineEnding')
effects.consume(code)
effects.exit('lineEnding')
// Get ready for closing fence.
buffer = fence(matter, 'close')
bufferIndex = 0
return effects.attempt(closingFenceConstruct, after, contentStart)
}
// EOF is not okay.
return nok(code)
}
/**
* Start of content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentStart(code) {
if (code === null || markdownLineEnding(code)) {
return lineEnd(code)
return contentEnd(code)
}
effects.enter(valueType)
return lineData(code)
return contentInside(code)
}
/** @type {State} */
function lineData(code) {
/**
* In content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentInside(code) {
if (code === null || markdownLineEnding(code)) {
effects.exit(valueType)
return lineEnd(code)
return contentEnd(code)
}
effects.consume(code)
return lineData
return contentInside
}
/** @type {State} */
function lineEnd(code) {
/**
* End of content chunk.
*
* ```markdown
* | ---
* > | title: "Venus"
* ^
* | ---
* ```
*
* @type {State}
*/
function contentEnd(code) {
// Require a closing fence.

@@ -129,8 +258,20 @@ if (code === null) {

effects.exit('lineEnding')
return effects.attempt(fenceConstruct, after, lineStart)
return effects.attempt(closingFenceConstruct, after, contentStart)
}
/** @type {State} */
/**
* After frontmatter.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function after(code) {
effects.exit(name)
// `code` must be eol/eof.
effects.exit(frontmatterType)
return ok(code)

@@ -141,12 +282,23 @@ }

/** @type {Tokenizer} */
function tokenizeFence(effects, ok, nok) {
function tokenizeClosingFence(effects, ok, nok) {
let bufferIndex = 0
return start
return closeStart
/** @type {State} */
function start(code) {
/**
* Start of close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeStart(code) {
if (code === buffer.charCodeAt(bufferIndex)) {
effects.enter(fenceType)
effects.enter(sequenceType)
return insideSequence(code)
return closeSequence(code)
}

@@ -156,4 +308,15 @@ return nok(code)

/** @type {State} */
function insideSequence(code) {
/**
* In close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeSequence(code) {
if (bufferIndex === buffer.length) {

@@ -163,9 +326,9 @@ effects.exit(sequenceType)

effects.enter('whitespace')
return insideWhitespace(code)
return closeSequenceWhitespace(code)
}
return fenceEnd(code)
return closeAfter(code)
}
if (code === buffer.charCodeAt(bufferIndex++)) {
effects.consume(code)
return insideSequence
return closeSequence
}

@@ -175,14 +338,36 @@ return nok(code)

/** @type {State} */
function insideWhitespace(code) {
/**
* In whitespace after close sequence.
*
* ```markdown
* > | ---
* | title: "Venus"
* | ---␠
* ^
* ```
*
* @type {State}
*/
function closeSequenceWhitespace(code) {
if (markdownSpace(code)) {
effects.consume(code)
return insideWhitespace
return closeSequenceWhitespace
}
effects.exit('whitespace')
return fenceEnd(code)
return closeAfter(code)
}
/** @type {State} */
function fenceEnd(code) {
/**
* After close sequence.
*
* ```markdown
* | ---
* | title: "Venus"
* > | ---
* ^
* ```
*
* @type {State}
*/
function closeAfter(code) {
if (code === null || markdownLineEnding(code)) {

@@ -199,3 +384,3 @@ effects.exit(fenceType)

* @param {Matter} matter
* @param {'open'|'close'} prop
* @param {'open' | 'close'} prop
* @returns {string}

@@ -211,4 +396,4 @@ */

/**
* @param {Info|string} schema
* @param {'open'|'close'} prop
* @param {Info | string} schema
* @param {'open' | 'close'} prop
* @returns {string}

@@ -215,0 +400,0 @@ */

/**
* @param {Options} [options='yaml']
* Simplify one or more options.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Array<Matter>}
* List of matters.
*/
export function matters(options?: Options | undefined): Array<Matter>
export function matters(options?: Options | null | undefined): Array<Matter>
/**
* Either `'yaml'` or `'toml'`.
* Known name of a frontmatter style.
*/
export type Preset = 'yaml' | 'toml'
export type Preset = 'toml' | 'yaml'
/**
* Sequence.
*
* Depending on how this structure is used, it reflects a marker or a fence.
*/
export type Info = {
/**
* Opening.
*/
open: string
/**
* Closing.
*/
close: string
}
/**
* Fields describing a kind of matter.
*/
export type MatterProps = {
/**
* Type to tokenize as.
* Node type to tokenize as.
*/
type: string
/**
* If `true`, matter can be found anywhere in the document.
* If `false` (default), only matter at the start of the document is
* recognized.
* Whether matter can be found anywhere in the document, normally, only matter
* at the start of the document is recognized.
*
* > πŸ‘‰ **Note**: using this is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*/
anywhere?: boolean | undefined
anywhere?: boolean | null | undefined
}

@@ -31,13 +52,14 @@ /**

/**
* Character used to construct fences.
* By providing an object with `open` and `close` different characters can be
* used for opening and closing fences.
* For example the character `'-'` will result in `'---'` being used as the
* fence
* Character repeated 3 times, used as complete fences.
*
* For example the character `'-'` will result in `'---'` being used as the
* fence
* Pass `open` and `close` to specify different characters for opening and
* closing fences.
*/
marker: string | Info
marker: Info | string
/**
* If `marker` is set, `fence` must not be set.
*/
fence?: undefined
fence?: never
}

@@ -49,21 +71,29 @@ /**

/**
* String used as the complete fence.
* By providing an object with `open` and `close` different values can be used
* for opening and closing fences.
* This can be used too if fences contain different characters or lengths
* other than 3.
* Complete fences.
*
* This can be used when fences contain different characters or lengths
* other than 3.
* Pass `open` and `close` to interface to specify different characters for opening and
* closing fences.
*/
fence: string | Info
fence: Info | string
/**
* If `fence` is set, `marker` must not be set.
*/
marker?: undefined
marker?: never
}
/**
* Matter object describing frontmatter.
* Fields describing a kind of matter.
*
* > πŸ‘‰ **Note**: using `anywhere` is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*
* > πŸ‘‰ **Note**: `marker` and `fence` are mutually exclusive.
* > If `marker` is set, `fence` must not be set, and vice versa.
*/
export type Matter = (MatterProps & FenceProps) | (MatterProps & MarkerProps)
/**
* Matter object or preset, or many.
* Configuration.
*/
export type Options = Preset | Matter | Array<Preset | Matter>
export type Options = Matter | Preset | Array<Matter | Preset>
/**
* @typedef {'yaml'|'toml'} Preset
* Either `'yaml'` or `'toml'`.
* @typedef {'toml' | 'yaml'} Preset
* Known name of a frontmatter style.
*
* @typedef Info
* Sequence.
*
* Depending on how this structure is used, it reflects a marker or a fence.
* @property {string} open
* Opening.
* @property {string} close
* Closing.
*
* @typedef MatterProps
* Fields describing a kind of matter.
* @property {string} type
* Type to tokenize as.
* @property {boolean} [anywhere=false]
* If `true`, matter can be found anywhere in the document.
* If `false` (default), only matter at the start of the document is
* recognized.
* Node type to tokenize as.
* @property {boolean | null | undefined} [anywhere=false]
* Whether matter can be found anywhere in the document, normally, only matter
* at the start of the document is recognized.
*
* > πŸ‘‰ **Note**: using this is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*
* @typedef MarkerProps
* Marker configuration.
* @property {string|Info} marker
* Character used to construct fences.
* By providing an object with `open` and `close` different characters can be
* used for opening and closing fences.
* @property {Info | string} marker
* Character repeated 3 times, used as complete fences.
*
* For example the character `'-'` will result in `'---'` being used as the
* fence
* Pass `open` and `close` to specify different characters for opening and
* closing fences.
* @property {never} [fence]

@@ -30,16 +40,24 @@ * If `marker` is set, `fence` must not be set.

* Fence configuration.
* @property {string|Info} fence
* String used as the complete fence.
* By providing an object with `open` and `close` different values can be used
* for opening and closing fences.
* This can be used too if fences contain different characters or lengths
* @property {Info | string} fence
* Complete fences.
*
* This can be used when fences contain different characters or lengths
* other than 3.
* Pass `open` and `close` to interface to specify different characters for opening and
* closing fences.
* @property {never} [marker]
* If `fence` is set, `marker` must not be set.
*
* @typedef {(MatterProps & FenceProps)|(MatterProps & MarkerProps)} Matter
* Matter object describing frontmatter.
* @typedef {(MatterProps & FenceProps) | (MatterProps & MarkerProps)} Matter
* Fields describing a kind of matter.
*
* @typedef {Preset|Matter|Array<Preset|Matter>} Options
* Matter object or preset, or many.
* > πŸ‘‰ **Note**: using `anywhere` is a terrible idea.
* > It’s called frontmatter, not matter-in-the-middle or so.
* > This makes your markdown less portable.
*
* > πŸ‘‰ **Note**: `marker` and `fence` are mutually exclusive.
* > If `marker` is set, `fence` must not be set, and vice versa.
*
* @typedef {Matter | Preset | Array<Matter | Preset>} Options
* Configuration.
*/

@@ -55,23 +73,33 @@

/**
* @param {Options} [options='yaml']
* Simplify one or more options.
*
* @param {Options | null | undefined} [options='yaml']
* Configuration.
* @returns {Array<Matter>}
* List of matters.
*/
export function matters(options = 'yaml') {
export function matters(options) {
/** @type {Array<Matter>} */
const results = []
const result = []
let index = -1
// One preset or matter.
if (!Array.isArray(options)) {
options = [options]
/** @type {Array<Matter | Preset>} */
const presetsOrMatters = Array.isArray(options)
? options
: options
? [options]
: ['yaml']
while (++index < presetsOrMatters.length) {
result[index] = matter(presetsOrMatters[index])
}
while (++index < options.length) {
results[index] = matter(options[index])
}
return results
return result
}
/**
* @param {Preset|Matter} option
* Simplify an option.
*
* @param {Matter | Preset} option
* Configuration.
* @returns {Matter}
* Matters.
*/

@@ -78,0 +106,0 @@ function matter(option) {

{
"name": "micromark-extension-frontmatter",
"version": "1.0.1",
"version": "1.1.0",
"description": "micromark extension to support frontmatter (YAML, TOML, etc)",

@@ -59,3 +59,3 @@ "license": "MIT",

"devDependencies": {
"@types/tape": "^4.0.0",
"@types/node": "^18.0.0",
"c8": "^7.0.0",

@@ -67,13 +67,12 @@ "micromark": "^3.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",
"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-coverage": "c8 --100 --reporter lcov npm run test-api",
"test": "npm run build && npm run format && npm run test-coverage"

@@ -98,3 +97,3 @@ },

"plugins": [
"preset-wooorm"
"remark-preset-wooorm"
]

@@ -101,0 +100,0 @@ },

@@ -11,3 +11,3 @@ # micromark-extension-frontmatter

[micromark][] extension to support frontmatter (YAML, TOML, etc).
[micromark][] extensions to support frontmatter (YAML, TOML, and more).

@@ -23,2 +23,6 @@ ## Contents

* [`frontmatterHtml(options?)`](#frontmatterhtmloptions)
* [`Info`](#info)
* [`Matter`](#matter)
* [`Options`](#options)
* [`Preset`](#preset)
* [Examples](#examples)

@@ -38,24 +42,29 @@ * [Authoring](#authoring)

This package contains extensions that add support for frontmatter.
This package contains two extensions that add support for frontmatter syntax
as often used in markdown to [`micromark`][micromark].
As there is no spec for frontmatter in markdown, this extension follows how YAML
frontmatter works on github.com.
For the HTML part, instead of rendering YAML, it is ignored.
Other types of frontmatter can be parsed, which will by default also work the
same as on github.com.
Frontmatter is a metadata format in front of the content.
It’s typically written in YAML and is often used with markdown.
Frontmatter does not work everywhere so it makes markdown less portable.
As there is no spec for frontmatter in markdown, these extensions follow how
YAML frontmatter works on `github.com`.
It can also parse TOML frontmatter, just like YAML except that it uses a `+`.
## When to use this
These tools are all low-level.
In many cases, you want to use [`remark-frontmatter`][plugin] with remark
instead.
You can use these extensions when you are working with [`micromark`][micromark]
already.
When you do want to use `micromark`, you can use this.
When working with `mdast-util-from-markdown`, you must combine this package
with [`mdast-util-frontmatter`][util].
When you need a syntax tree, you can combine this package with
[`mdast-util-frontmatter`][mdast-util-frontmatter].
All these packages are used [`remark-frontmatter`][remark-frontmatter], 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+, 16.0+, or 18.0+), install with [npm][]:
In Node.js (version 14.14+), install with [npm][]:

@@ -82,2 +91,4 @@ ```sh

Say our module `example.js` looks as follows:
```js

@@ -95,3 +106,3 @@ import {micromark} from 'micromark'

Yields:
…now running `node example.js` yields:

@@ -104,6 +115,7 @@ ```html

This package exports the identifiers `frontmatter` and `frontmatterHtml`.
This package exports the identifiers [`frontmatter`][api-frontmatter] and
[`frontmatterHtml`][api-frontmatter-html].
There is no default export.
The export map supports the endorsed [`development` condition][condition].
The export map supports the [`development` condition][development].
Run `node --conditions development module.js` to get instrumented dev code.

@@ -114,60 +126,92 @@ Without this condition, production code is loaded.

Add support for parsing frontmatter in markdown.
Create an extension for [`micromark`][micromark] to enable frontmatter syntax.
Function that can be called to get a syntax extension for micromark (passed
in `extensions`).
###### Parameters
Supports YAML by default.
Can be configured to support TOML and more.
* `options` ([`Options`][api-options], default: `['yaml']`)
β€” configuration
##### `options`
###### Returns
Configuration (optional).
Extension for `micromark` that can be passed in `extensions`, to enable
frontmatter syntax ([`Extension`][micromark-extension]).
One [`preset`][preset] or [`Matter`][matter], or an array of them, defining all
the supported frontmatters (default: `'yaml'`).
### `frontmatterHtml(options?)`
##### `preset`
Create an extension for `micromark` to support frontmatter when serializing to
HTML.
Either `'yaml'` or `'toml'`:
> πŸ‘‰ **Note**: this makes sure nothing is generated in the output HTML for
> frontmatter.
* `'yaml'` β€” [`Matter`][matter] defined as `{type: 'yaml', marker: '-'}`
* `'toml'` β€” [`Matter`][matter] defined as `{type: 'toml', marker: '+'}`
###### Parameters
##### `Matter`
* `options` ([`Options`][api-options], default: `['yaml']`)
β€” configuration
An object with a `type` and either a `marker` or a `fence`:
###### Returns
Extension for `micromark` that can be passed in `htmlExtensions`, to support
frontmatter when serializing to HTML
([`HtmlExtension`][micromark-html-extension]).
### `Info`
Sequence (TypeScript type).
Depending on how this structure is used, it reflects a marker or a fence.
###### Fields
* `open` (`string`)
β€” opening
* `close` (`string`)
β€” closing
### `Matter`
Fields describing a kind of matter (TypeScript type).
> πŸ‘‰ **Note**: using `anywhere` is a terrible idea.
> It’s called frontmatter, not matter-in-the-middle or so.
> This makes your markdown less portable.
> πŸ‘‰ **Note**: `marker` and `fence` are mutually exclusive.
> If `marker` is set, `fence` must not be set, and vice versa.
###### Fields
* `type` (`string`)
β€” type to tokenize as
* `marker` (`string` or `{open: string, close: string}`)
β€” character used to construct fences.
By providing an object with `open` and `close` different characters can be
used for opening and closing fences.
For example the character `'-'` will result in `'---'` being used as the
fence
* `fence` (`string` or `{open: string, close: string}`)
β€” string used as the complete fence.
By providing an object with `open` and `close` different values can be used
for opening and closing fences.
This can be used too if fences contain different characters or lengths other
than 3
β€” node type to tokenize as
* `marker` (`string` or [`Info`][api-info])
β€” character repeated 3 times, used as complete fences
* `fence` (`string` or [`Info`][api-info])
β€” complete fences
* `anywhere` (`boolean`, default: `false`)
– if `true`, matter can be found anywhere in the document.
If `false` (default), only matter at the start of the document is recognized
β€” whether matter can be found anywhere in the document, normally only
matter at the start of the document is recognized
### `frontmatterHtml(options?)`
### `Options`
Add support for turning frontmatter in markdown to HTML.
Configuration (TypeScript type).
Function that can be called to get an HTML extension for micromark (passed
in `htmlExtensions`).
###### Type
This makes sure nothing is generated for frontmatter.
```ts
type Options = Matter | Preset | Array<Matter | Preset>
```
Supports YAML by default.
Can be configured to support other things.
### `Preset`
See `options` above for more info.
Known name of a frontmatter style (TypeScript type).
* `'yaml'` β€” [`Matter`][api-matter] defined as `{type: 'yaml', marker: '-'}`
* `'toml'` β€” [`Matter`][api-matter] defined as `{type: 'toml', marker: '+'}`
###### Type
```ts
type Preset = 'toml' | 'yaml'
```
## Examples

@@ -234,3 +278,3 @@

Frontmatter does not relate to HTML elements.
It is typically stripped, which is what this plugin does.
It is typically stripped, which is what these extensions do.

@@ -243,20 +287,41 @@ ## CSS

Frontmatter forms with, roughly, the following BNF:
Frontmatter forms with the following BNF:
```bnf
; Note: `fence` is an arbitrary, configured, fence.
frontmatter ::= fence *space_or_tab eol *( *code eol ) fence *space_or_tab
frontmatter ::= fence_open *( eol *line ) eol fence_close
fence_open ::= sequence_open *space_or_tab
fence_close ::= sequence_close *space_or_tab
; Note: options can define custom sequences.
sequence_open ::= 3'+' | 3'-'
; Note: options can define custom sequences.
; Restriction: `sequence_close` must correspond to `sequence_open`.
sequence_close ::= 3'+' | 3'-'
; Character groups for informational purposes.
byte ::= 0x00..=0xFFFF
eol ::= '\n' | '\r' | '\r\n'
line ::= byte - eol
```
Frontmatter can only occur once.
It cannot occur in a container.
It must have a closing fence.
Like flow constructs, it must be followed by an eol (line ending) or
eof (end of file).
## Types
This package is fully typed with [TypeScript][].
It exports the additional type `Options`.
It exports the additional types [`Info`][api-info], [`Matter`][api-matter],
[`Options`][api-options], [`Preset`][api-preset].
## 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+, 16.0+, and 18.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

@@ -268,5 +333,5 @@

* [`remarkjs/remark-frontmatter`][plugin]
* [`remark-frontmatter`][remark-frontmatter]
β€” remark plugin using this to support frontmatter
* [`syntax-tree/mdast-util-frontmatter`][util]
* [`mdast-util-frontmatter`][mdast-util-frontmatter]
β€” mdast utility to support frontmatter

@@ -334,12 +399,24 @@

[condition]: https://nodejs.org/api/packages.html#packages_resolving_user_conditions
[development]: https://nodejs.org/api/packages.html#packages_resolving_user_conditions
[micromark]: https://github.com/micromark/micromark
[util]: https://github.com/syntax-tree/mdast-util-frontmatter
[mdast-util-frontmatter]: https://github.com/syntax-tree/mdast-util-frontmatter
[plugin]: https://github.com/remarkjs/remark-frontmatter
[remark-frontmatter]: https://github.com/remarkjs/remark-frontmatter
[preset]: #preset
[micromark-extension]: https://github.com/micromark/micromark#syntaxextension
[matter]: #matter
[micromark-html-extension]: https://github.com/micromark/micromark#htmlextension
[api-frontmatter]: #frontmatteroptions
[api-frontmatter-html]: #frontmatterhtmloptions
[api-info]: #info
[api-matter]: #matter
[api-options]: #options
[api-preset]: #preset
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