Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

micromark

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

micromark - npm Package Compare versions

Comparing version 3.0.0-alpha.2 to 3.0.0-alpha.3

lib/initialize/document.bak-7-errors.js

27

dev/lib/compile.js

@@ -348,3 +348,3 @@ /**

function prepareList(slice) {
const length = slice.length - 1 // Skip close.
const length = slice.length
let index = 0 // Skip open.

@@ -606,3 +606,2 @@ let containerBalance = 0

tag('>')
setData('fencedCodeInside', true)
setData('slurpOneLineEnding', true)

@@ -623,4 +622,24 @@ }

const count = getData('fencesCount')
// Send an extra line feed if we saw data.
if (getData('flowCodeSeenData')) lineEndingIfNeeded()
// One special case is if we are inside a container, and the fenced code was
// not closed (meaning it runs to the end).
// In that case, the following line ending, is considered *outside* the
// fenced code and block quote by micromark, but CM wants to treat that
// ending as part of the code.
if (
count !== undefined &&
count < 2 &&
// @ts-expect-error `tightStack` is always set.
data.tightStack.length > 0 &&
!getData('lastWasTag')
) {
lineEnding()
}
// But in most cases, it’s simpler: when we’ve seen some data, emit an extra
// line ending when needed.
if (getData('flowCodeSeenData')) {
lineEndingIfNeeded()
}
tag('</code></pre>')

@@ -627,0 +646,0 @@ if (count !== undefined && count < 2) lineEndingIfNeeded()

11

dev/lib/create-tokenizer.js

@@ -79,4 +79,3 @@ /**

check: constructFactory(onsuccessfulcheck),
interrupt: constructFactory(onsuccessfulcheck, {interrupt: true}),
lazy: constructFactory(onsuccessfulcheck, {lazy: true})
interrupt: constructFactory(onsuccessfulcheck, {interrupt: true})
}

@@ -136,3 +135,2 @@

// Otherwise, resolve, and exit.
// Note: TS can’t handle recursive types.
context.events = resolveAll(resolveAllConstructs, context.events, context)

@@ -238,3 +236,3 @@

undefined,
'expected code to not have been consumed'
'expected code to not have been consumed: this might be because `return x(code)` instead of `return x` was used'
)

@@ -456,3 +454,6 @@ assert(

return construct.tokenize.call(
fields ? Object.assign({}, context, fields) : context,
// If we do have fields, create an object w/ `context` as its
// prototype.
// This allows a “live binding”, which is needed for `interrupt`.
fields ? Object.assign(Object.create(context), fields) : context,
effects,

@@ -459,0 +460,0 @@ ok,

@@ -10,9 +10,4 @@ /** @type {InitialConstruct} */

export type State = import('micromark-util-types').State
export type Point = import('micromark-util-types').Point
export type StackState = Record<string, unknown>
export type StackItem = [Construct, StackState]
export type Result = {
flowContinue: boolean
lazy: boolean
continued: number
flowEnd: boolean
}

@@ -9,2 +9,3 @@ /**

* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').Point} Point
*/

@@ -15,8 +16,5 @@

* @typedef {[Construct, StackState]} StackItem
*
* @typedef {{flowContinue: boolean, lazy: boolean, continued: number, flowEnd: boolean}} Result
*/
import assert from 'assert'
import {blankLine} from 'micromark-core-commonmark'
import {factorySpace} from 'micromark-factory-space'

@@ -27,2 +25,3 @@ import {markdownLineEnding} from 'micromark-util-character'

import {types} from 'micromark-util-symbol/types.js'
import {splice} from 'micromark-util-chunked'

@@ -34,4 +33,2 @@ /** @type {InitialConstruct} */

const containerConstruct = {tokenize: tokenizeContainer}
/** @type {Construct} */
const lazyFlowConstruct = {tokenize: tokenizeLazyFlow}

@@ -43,7 +40,3 @@ /** @type {Initializer} */

const stack = []
/** @type {Construct} */
const inspectConstruct = {tokenize: tokenizeInspect, partial: true}
let continued = 0
/** @type {Result|undefined} */
let inspectResult
/** @type {TokenizeContext|undefined} */

@@ -53,2 +46,4 @@ let childFlow

let childToken
/** @type {number} */
let lineStartOffset

@@ -59,2 +54,12 @@ return start

function start(code) {
// First we iterate through the open blocks, starting with the root
// document, and descending through last children down to the last open
// block.
// Each block imposes a condition that the line must satisfy if the block is
// to remain open.
// For example, a block quote requires a `>` character.
// A paragraph requires a non-blank line.
// In this phase we may match all or just some of the open blocks.
// But we cannot close unmatched blocks yet, because we may have a lazy
// continuation line.
if (continued < stack.length) {

@@ -65,3 +70,3 @@ const item = stack[continued]

item[0].continuation,
'expected `contination` to be defined on container construct'
'expected `continuation` to be defined on container construct'
)

@@ -71,7 +76,8 @@ return effects.attempt(

documentContinue,
documentContinued
checkNewContainers
)(code)
}
return documentContinued(code)
// Done.
return checkNewContainers(code)
}

@@ -81,2 +87,7 @@

function documentContinue(code) {
assert(
self.containerState,
'expected `containerState` to be defined after continuation'
)
if (self.containerState._closeFlow) closeFlow()
continued++

@@ -87,14 +98,54 @@ return start(code)

/** @type {State} */
function documentContinued(code) {
// If we’re in a concrete construct (such as when expecting another line of
// HTML, or we resulted in lazy content), we can immediately start flow.
if (inspectResult && inspectResult.flowContinue) {
return flowStart(code)
function checkNewContainers(code) {
// Next, after consuming the continuation markers for existing blocks, we
// look for new block starts (e.g. `>` for a block quote).
// If we encounter a new block start, we close any blocks unmatched in
// step 1 before creating the new block as a child of the last matched
// block.
if (continued === stack.length) {
// No need to `check` whether there’s a container, of `exitContainers`
// would be moot.
// We can instead immediately `attempt` to parse one.
if (!childFlow) {
return documentContinued(code)
}
// If we have concrete content, such as block HTML or fenced code,
// we can’t have containers “pierce” into them, so we can immediately
// start.
if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) {
return flowStart(code)
}
// If we do have flow, we’d be interrupting it w/ a new container.
self.interrupt = true
}
self.interrupt =
childFlow &&
childFlow.currentConstruct &&
childFlow.currentConstruct.interruptible
// Check if there is a new container.
self.containerState = {}
return effects.check(
containerConstruct,
thereIsANewContainer,
thereIsNoNewContainer
)(code)
}
/** @type {State} */
function thereIsANewContainer(code) {
if (childFlow) closeFlow()
exitContainers(continued)
return documentContinued(code)
}
/** @type {State} */
function thereIsNoNewContainer(code) {
self.parser.lazy[self.now().line] = continued !== stack.length
lineStartOffset = self.now().offset
return flowStart(code)
}
/** @type {State} */
function documentContinued(code) {
// Try new containers.
self.containerState = {}
return effects.attempt(

@@ -117,4 +168,5 @@ containerConstruct,

)
continued++
stack.push([self.currentConstruct, self.containerState])
self.containerState = undefined
// Try another.
return documentContinued(code)

@@ -126,3 +178,4 @@ }

if (code === codes.eof) {
exitContainers(0, true)
if (childFlow) closeFlow()
exitContainers(0)
effects.consume(code)

@@ -133,3 +186,2 @@ return

childFlow = childFlow || self.parser.flow(self.now())
effects.enter(types.chunkFlow, {

@@ -147,4 +199,6 @@ contentType: constants.contentTypeFlow,

if (code === codes.eof) {
continueFlow(effects.exit(types.chunkFlow))
return flowStart(code)
writeToChild(effects.exit(types.chunkFlow), true)
exitContainers(0)
effects.consume(code)
return
}

@@ -154,4 +208,7 @@

effects.consume(code)
continueFlow(effects.exit(types.chunkFlow))
return effects.check(inspectConstruct, documentAfterPeek)
writeToChild(effects.exit(types.chunkFlow))
// Get ready for the next line.
continued = 0
self.interrupt = undefined
return start
}

@@ -163,21 +220,113 @@

/** @type {State} */
function documentAfterPeek(code) {
assert(inspectResult, 'expected `inspectResult` to be defined after peek')
exitContainers(inspectResult.continued, inspectResult.flowEnd)
continued = 0
return start(code)
}
/**
* @param {Token} token
* @param {boolean} [eof]
* @returns {void}
*/
function continueFlow(token) {
function writeToChild(token, eof) {
assert(childFlow, 'expected `childFlow` to be defined when continuing')
const stream = self.sliceStream(token)
if (eof) stream.push(null)
token.previous = childToken
if (childToken) childToken.next = token
childToken = token
assert(childFlow, 'expected `childFlow` to be defined when continuing')
childFlow.lazy = inspectResult ? inspectResult.lazy : false
childFlow.defineSkip(token.start)
childFlow.write(self.sliceStream(token))
childFlow.write(stream)
// Alright, so we just added a lazy line:
//
// ```markdown
// > a
// b.
//
// Or:
//
// > ~~~c
// d
//
// Or:
//
// > | e |
// f
// ```
//
// The construct in the second example (fenced code) does not accept lazy
// lines, so it marked itself as done at the end of its first line, and
// then the content construct parses `d`.
// Most constructs in markdown match on the first line: if the first line
// forms a construct, a non-lazy line can’t “unmake” it.
//
// The construct in the third example is potentially a GFM table, and
// those are *weird*.
// It *could* be a table, from the first line, if the following line
// matches a condition.
// In this case, that second line is lazy, which “unmakes” the first line
// and turns the whole into one content block.
//
// We’ve now parsed the non-lazy and the lazy line, and can figure out
// whether the lazy line started a new flow block.
// If it did, we exit the current containers between the two flow blocks.
if (self.parser.lazy[token.start.line]) {
let index = childFlow.events.length
while (index--) {
if (
// The token starts before the line ending…
childFlow.events[index][1].start.offset < lineStartOffset &&
// …and either is not ended yet…
(!childFlow.events[index][1].end ||
// …or ends after it.
childFlow.events[index][1].end.offset > lineStartOffset)
) {
// Exit: there’s still something open, which means it’s a lazy line
// part of something.
return
}
}
const indexBeforeExits = self.events.length
let indexBeforeFlow = indexBeforeExits
/** @type {boolean|undefined} */
let seen
/** @type {Point|undefined} */
let point
// Find the previous chunk (the one before the lazy line).
while (indexBeforeFlow--) {
if (
self.events[indexBeforeFlow][0] === 'exit' &&
self.events[indexBeforeFlow][1].type === types.chunkFlow
) {
if (seen) {
point = self.events[indexBeforeFlow][1].end
break
}
seen = true
}
}
assert(point, 'could not find previous flow chunk')
exitContainers(continued)
// Fix positions.
index = indexBeforeExits
while (index < self.events.length) {
self.events[index][1].end = Object.assign({}, point)
index++
}
// Inject the exits earlier (they’re still also at the end).
splice(
self.events,
indexBeforeFlow + 1,
0,
self.events.slice(indexBeforeExits)
)
// Discard the duplicate exits.
self.events.length = index
}
}

@@ -187,19 +336,11 @@

* @param {number} size
* @param {boolean} end
* @returns {void}
*/
function exitContainers(size, end) {
function exitContainers(size) {
let index = stack.length
// Close the flow.
if (childFlow && end) {
childFlow.write([codes.eof])
childToken = undefined
childFlow = undefined
}
// Exit open containers.
while (index-- > size) {
self.containerState = stack[index][1]
const entry = stack[index]
self.containerState = entry[1]
assert(

@@ -215,131 +356,12 @@ entry[0].exit,

/** @type {Tokenizer} */
function tokenizeInspect(effects, ok) {
let subcontinued = 0
inspectResult = {
flowContinue: false,
lazy: false,
continued: 0,
flowEnd: false
}
return inspectStart
/** @type {State} */
function inspectStart(code) {
if (subcontinued < stack.length) {
const entry = stack[subcontinued]
self.containerState = entry[1]
assert(
entry[0].continuation,
'expected `continuation` to be defined on container construct'
)
return effects.attempt(
entry[0].continuation,
inspectContinue,
inspectLess
)(code)
}
assert(
childFlow,
'expected `childFlow` to be defined when starting inspection'
)
// If we’re continued but in a concrete flow, we can’t have more
// containers.
if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) {
assert(
inspectResult,
'expected `inspectResult` to be defined when starting inspection'
)
inspectResult.flowContinue = true
return inspectDone(code)
}
self.interrupt =
childFlow.currentConstruct && childFlow.currentConstruct.interruptible
self.containerState = {}
return effects.attempt(
containerConstruct,
inspectFlowEnd,
inspectDone
)(code)
}
/** @type {State} */
function inspectContinue(code) {
subcontinued++
assert(
self.containerState,
'expected `containerState` to be defined when continuing inspection'
)
return self.containerState._closeFlow
? inspectFlowEnd(code)
: inspectStart(code)
}
/** @type {State} */
function inspectLess(code) {
assert(
childFlow,
'expected `childFlow` to be defined when inspecting less'
)
if (childFlow.currentConstruct && childFlow.currentConstruct.lazy) {
// Maybe another container?
self.containerState = {}
return effects.attempt(
containerConstruct,
inspectFlowEnd,
// Maybe flow, or a blank line?
effects.attempt(
lazyFlowConstruct,
inspectFlowEnd,
effects.check(blankLine, inspectFlowEnd, inspectLazy)
)
)(code)
}
// Otherwise we’re interrupting.
return inspectFlowEnd(code)
}
/** @type {State} */
function inspectLazy(code) {
// Act as if all containers are continued.
subcontinued = stack.length
assert(
inspectResult,
'expected `inspectResult` to be defined when inspecting lazy'
)
inspectResult.lazy = true
inspectResult.flowContinue = true
return inspectDone(code)
}
// We’re done with flow if we have more containers, or an interruption.
/** @type {State} */
function inspectFlowEnd(code) {
assert(
inspectResult,
'expected `inspectResult` to be defined when inspecting flow end'
)
inspectResult.flowEnd = true
return inspectDone(code)
}
/** @type {State} */
function inspectDone(code) {
assert(
inspectResult,
'expected `inspectResult` to be defined when done inspecting'
)
inspectResult.continued = subcontinued
self.interrupt = undefined
self.containerState = undefined
return ok(code)
}
function closeFlow() {
assert(
self.containerState,
'expected `containerState` to be defined when closing flow'
)
assert(childFlow, 'expected `childFlow` to be defined when closing it')
childFlow.write([codes.eof])
childToken = undefined
childFlow = undefined
self.containerState._closeFlow = undefined
}

@@ -359,13 +381,1 @@ }

}
/** @type {Tokenizer} */
function tokenizeLazyFlow(effects, ok, nok) {
return factorySpace(
effects,
effects.lazy(this.parser.constructs.flow, ok, nok),
types.linePrefix,
this.parser.constructs.disable.null.includes('codeIndented')
? undefined
: constants.tabSize
)
}

@@ -31,2 +31,3 @@ /**

defined: [],
lazy: {},
constructs,

@@ -33,0 +34,0 @@ content: create(content),

@@ -342,4 +342,3 @@ /**

function prepareList(slice) {
const length = slice.length - 1 // Skip close.
const length = slice.length
let index = 0 // Skip open.

@@ -593,3 +592,2 @@

tag('>')
setData('fencedCodeInside', true)
setData('slurpOneLineEnding', true)

@@ -609,5 +607,22 @@ }

function onexitflowcode() {
const count = getData('fencesCount') // Send an extra line feed if we saw data.
const count = getData('fencesCount') // One special case is if we are inside a container, and the fenced code was
// not closed (meaning it runs to the end).
// In that case, the following line ending, is considered *outside* the
// fenced code and block quote by micromark, but CM wants to treat that
// ending as part of the code.
if (getData('flowCodeSeenData')) lineEndingIfNeeded()
if (
count !== undefined &&
count < 2 && // @ts-expect-error `tightStack` is always set.
data.tightStack.length > 0 &&
!getData('lastWasTag')
) {
lineEnding()
} // But in most cases, it’s simpler: when we’ve seen some data, emit an extra
// line ending when needed.
if (getData('flowCodeSeenData')) {
lineEndingIfNeeded()
}
tag('</code></pre>')

@@ -614,0 +629,0 @@ if (count !== undefined && count < 2) lineEndingIfNeeded()

@@ -88,5 +88,2 @@ /**

interrupt: true
}),
lazy: constructFactory(onsuccessfulcheck, {
lazy: true
})

@@ -143,3 +140,2 @@ }

addResult(initialize, 0) // Otherwise, resolve, and exit.
// Note: TS can’t handle recursive types.

@@ -401,3 +397,6 @@ context.events = resolveAll(resolveAllConstructs, context.events, context)

return construct.tokenize.call(
fields ? Object.assign({}, context, fields) : context,
// If we do have fields, create an object w/ `context` as its
// prototype.
// This allows a “live binding”, which is needed for `interrupt`.
fields ? Object.assign(Object.create(context), fields) : context,
effects,

@@ -404,0 +403,0 @@ ok,

@@ -10,9 +10,4 @@ /** @type {InitialConstruct} */

export type State = import('micromark-util-types').State
export type Point = import('micromark-util-types').Point
export type StackState = Record<string, unknown>
export type StackItem = [Construct, StackState]
export type Result = {
flowContinue: boolean
lazy: boolean
continued: number
flowEnd: boolean
}

@@ -9,2 +9,3 @@ /**

* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').Point} Point
*/

@@ -15,10 +16,8 @@

* @typedef {[Construct, StackState]} StackItem
*
* @typedef {{flowContinue: boolean, lazy: boolean, continued: number, flowEnd: boolean}} Result
*/
import {blankLine} from 'micromark-core-commonmark'
import {factorySpace} from 'micromark-factory-space'
import {markdownLineEnding} from 'micromark-util-character'
import {splice} from 'micromark-util-chunked'
/** @type {InitialConstruct} */
/** @type {InitialConstruct} */
export const document = {

@@ -32,7 +31,2 @@ tokenize: initializeDocument

}
/** @type {Construct} */
const lazyFlowConstruct = {
tokenize: tokenizeLazyFlow
}
/** @type {Initializer} */

@@ -45,12 +39,3 @@

const stack = []
/** @type {Construct} */
const inspectConstruct = {
tokenize: tokenizeInspect,
partial: true
}
let continued = 0
/** @type {Result|undefined} */
let inspectResult
/** @type {TokenizeContext|undefined} */

@@ -62,2 +47,5 @@

let childToken
/** @type {number} */
let lineStartOffset
return start

@@ -67,2 +55,12 @@ /** @type {State} */

function start(code) {
// First we iterate through the open blocks, starting with the root
// document, and descending through last children down to the last open
// block.
// Each block imposes a condition that the line must satisfy if the block is
// to remain open.
// For example, a block quote requires a `>` character.
// A paragraph requires a non-blank line.
// In this phase we may match all or just some of the open blocks.
// But we cannot close unmatched blocks yet, because we may have a lazy
// continuation line.
if (continued < stack.length) {

@@ -74,7 +72,7 @@ const item = stack[continued]

documentContinue,
documentContinued
checkNewContainers
)(code)
}
} // Done.
return documentContinued(code)
return checkNewContainers(code)
}

@@ -84,2 +82,3 @@ /** @type {State} */

function documentContinue(code) {
if (self.containerState._closeFlow) closeFlow()
continued++

@@ -90,14 +89,51 @@ return start(code)

function documentContinued(code) {
// If we’re in a concrete construct (such as when expecting another line of
// HTML, or we resulted in lazy content), we can immediately start flow.
if (inspectResult && inspectResult.flowContinue) {
return flowStart(code)
}
function checkNewContainers(code) {
// Next, after consuming the continuation markers for existing blocks, we
// look for new block starts (e.g. `>` for a block quote).
// If we encounter a new block start, we close any blocks unmatched in
// step 1 before creating the new block as a child of the last matched
// block.
if (continued === stack.length) {
// No need to `check` whether there’s a container, of `exitContainers`
// would be moot.
// We can instead immediately `attempt` to parse one.
if (!childFlow) {
return documentContinued(code)
} // If we have concrete content, such as block HTML or fenced code,
// we can’t have containers “pierce” into them, so we can immediately
// start.
self.interrupt =
childFlow &&
childFlow.currentConstruct &&
childFlow.currentConstruct.interruptible
if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) {
return flowStart(code)
} // If we do have flow, we’d be interrupting it w/ a new container.
self.interrupt = true
} // Check if there is a new container.
self.containerState = {}
return effects.check(
containerConstruct,
thereIsANewContainer,
thereIsNoNewContainer
)(code)
}
/** @type {State} */
function thereIsANewContainer(code) {
if (childFlow) closeFlow()
exitContainers(continued)
return documentContinued(code)
}
/** @type {State} */
function thereIsNoNewContainer(code) {
self.parser.lazy[self.now().line] = continued !== stack.length
lineStartOffset = self.now().offset
return flowStart(code)
}
/** @type {State} */
function documentContinued(code) {
// Try new containers.
self.containerState = {}
return effects.attempt(

@@ -112,4 +148,5 @@ containerConstruct,

function containerContinue(code) {
stack.push([self.currentConstruct, self.containerState])
self.containerState = undefined
continued++
stack.push([self.currentConstruct, self.containerState]) // Try another.
return documentContinued(code)

@@ -121,3 +158,4 @@ }

if (code === null) {
exitContainers(0, true)
if (childFlow) closeFlow()
exitContainers(0)
effects.consume(code)

@@ -139,4 +177,6 @@ return

if (code === null) {
continueFlow(effects.exit('chunkFlow'))
return flowStart(code)
writeToChild(effects.exit('chunkFlow'), true)
exitContainers(0)
effects.consume(code)
return
}

@@ -146,4 +186,7 @@

effects.consume(code)
continueFlow(effects.exit('chunkFlow'))
return effects.check(inspectConstruct, documentAfterPeek)
writeToChild(effects.exit('chunkFlow')) // Get ready for the next line.
continued = 0
self.interrupt = undefined
return start
}

@@ -154,136 +197,130 @@

}
/** @type {State} */
function documentAfterPeek(code) {
exitContainers(inspectResult.continued, inspectResult.flowEnd)
continued = 0
return start(code)
}
/**
* @param {Token} token
* @param {boolean} [eof]
* @returns {void}
*/
function continueFlow(token) {
function writeToChild(token, eof) {
const stream = self.sliceStream(token)
if (eof) stream.push(null)
token.previous = childToken
if (childToken) childToken.next = token
childToken = token
childFlow.lazy = inspectResult ? inspectResult.lazy : false
childFlow.defineSkip(token.start)
childFlow.write(self.sliceStream(token))
}
/**
* @param {number} size
* @param {boolean} end
* @returns {void}
*/
childFlow.write(stream) // Alright, so we just added a lazy line:
//
// ```markdown
// > a
// b.
//
// Or:
//
// > ~~~c
// d
//
// Or:
//
// > | e |
// f
// ```
//
// The construct in the second example (fenced code) does not accept lazy
// lines, so it marked itself as done at the end of its first line, and
// then the content construct parses `d`.
// Most constructs in markdown match on the first line: if the first line
// forms a construct, a non-lazy line can’t “unmake” it.
//
// The construct in the third example is potentially a GFM table, and
// those are *weird*.
// It *could* be a table, from the first line, if the following line
// matches a condition.
// In this case, that second line is lazy, which “unmakes” the first line
// and turns the whole into one content block.
//
// We’ve now parsed the non-lazy and the lazy line, and can figure out
// whether the lazy line started a new flow block.
// If it did, we exit the current containers between the two flow blocks.
function exitContainers(size, end) {
let index = stack.length // Close the flow.
if (self.parser.lazy[token.start.line]) {
let index = childFlow.events.length
if (childFlow && end) {
childFlow.write([null])
childToken = undefined
childFlow = undefined
} // Exit open containers.
while (index--) {
if (
// The token starts before the line ending…
childFlow.events[index][1].start.offset < lineStartOffset && // …and either is not ended yet…
(!childFlow.events[index][1].end || // …or ends after it.
childFlow.events[index][1].end.offset > lineStartOffset)
) {
// Exit: there’s still something open, which means it’s a lazy line
// part of something.
return
}
}
while (index-- > size) {
self.containerState = stack[index][1]
const entry = stack[index]
entry[0].exit.call(self, effects)
}
const indexBeforeExits = self.events.length
let indexBeforeFlow = indexBeforeExits
/** @type {boolean|undefined} */
stack.length = size
}
/** @type {Tokenizer} */
let seen
/** @type {Point|undefined} */
function tokenizeInspect(effects, ok) {
let subcontinued = 0
inspectResult = {
flowContinue: false,
lazy: false,
continued: 0,
flowEnd: false
}
return inspectStart
/** @type {State} */
let point // Find the previous chunk (the one before the lazy line).
function inspectStart(code) {
if (subcontinued < stack.length) {
const entry = stack[subcontinued]
self.containerState = entry[1]
return effects.attempt(
entry[0].continuation,
inspectContinue,
inspectLess
)(code)
}
while (indexBeforeFlow--) {
if (
self.events[indexBeforeFlow][0] === 'exit' &&
self.events[indexBeforeFlow][1].type === 'chunkFlow'
) {
if (seen) {
point = self.events[indexBeforeFlow][1].end
break
}
// If we’re continued but in a concrete flow, we can’t have more
// containers.
if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) {
inspectResult.flowContinue = true
return inspectDone(code)
seen = true
}
}
self.interrupt =
childFlow.currentConstruct && childFlow.currentConstruct.interruptible
self.containerState = {}
return effects.attempt(
containerConstruct,
inspectFlowEnd,
inspectDone
)(code)
}
/** @type {State} */
exitContainers(continued) // Fix positions.
function inspectContinue(code) {
subcontinued++
return self.containerState._closeFlow
? inspectFlowEnd(code)
: inspectStart(code)
}
/** @type {State} */
index = indexBeforeExits
function inspectLess(code) {
if (childFlow.currentConstruct && childFlow.currentConstruct.lazy) {
// Maybe another container?
self.containerState = {}
return effects.attempt(
containerConstruct,
inspectFlowEnd, // Maybe flow, or a blank line?
effects.attempt(
lazyFlowConstruct,
inspectFlowEnd,
effects.check(blankLine, inspectFlowEnd, inspectLazy)
)
)(code)
} // Otherwise we’re interrupting.
while (index < self.events.length) {
self.events[index][1].end = Object.assign({}, point)
index++
} // Inject the exits earlier (they’re still also at the end).
return inspectFlowEnd(code)
splice(
self.events,
indexBeforeFlow + 1,
0,
self.events.slice(indexBeforeExits)
) // Discard the duplicate exits.
self.events.length = index
}
/** @type {State} */
}
/**
* @param {number} size
* @returns {void}
*/
function inspectLazy(code) {
// Act as if all containers are continued.
subcontinued = stack.length
inspectResult.lazy = true
inspectResult.flowContinue = true
return inspectDone(code)
} // We’re done with flow if we have more containers, or an interruption.
function exitContainers(size) {
let index = stack.length // Exit open containers.
/** @type {State} */
function inspectFlowEnd(code) {
inspectResult.flowEnd = true
return inspectDone(code)
while (index-- > size) {
const entry = stack[index]
self.containerState = entry[1]
entry[0].exit.call(self, effects)
}
/** @type {State} */
function inspectDone(code) {
inspectResult.continued = subcontinued
self.interrupt = undefined
self.containerState = undefined
return ok(code)
}
stack.length = size
}
function closeFlow() {
childFlow.write([null])
childToken = undefined
childFlow = undefined
self.containerState._closeFlow = undefined
}
}

@@ -300,11 +337,1 @@ /** @type {Tokenizer} */

}
/** @type {Tokenizer} */
function tokenizeLazyFlow(effects, ok, nok) {
return factorySpace(
effects,
effects.lazy(this.parser.constructs.flow, ok, nok),
'linePrefix',
this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4
)
}

@@ -31,2 +31,3 @@ /**

defined: [],
lazy: {},
constructs,

@@ -33,0 +34,0 @@ content: create(content),

{
"name": "micromark",
"version": "3.0.0-alpha.2",
"version": "3.0.0-alpha.3",
"description": "small commonmark compliant markdown parser with positional info and concrete tokens",

@@ -101,14 +101,14 @@ "license": "MIT",

"debug": "^4.0.0",
"micromark-core-commonmark": "1.0.0-alpha.2",
"micromark-factory-space": "1.0.0-alpha.2",
"micromark-util-character": "1.0.0-alpha.2",
"micromark-util-chunked": "1.0.0-alpha.2",
"micromark-util-combine-extensions": "1.0.0-alpha.2",
"micromark-util-encode": "1.0.0-alpha.2",
"micromark-util-normalize-identifier": "1.0.0-alpha.2",
"micromark-util-resolve-all": "1.0.0-alpha.2",
"micromark-util-sanitize-uri": "1.0.0-alpha.2",
"micromark-util-subtokenize": "1.0.0-alpha.2",
"micromark-util-symbol": "1.0.0-alpha.2",
"micromark-util-types": "1.0.0-alpha.2",
"micromark-core-commonmark": "1.0.0-alpha.3",
"micromark-factory-space": "1.0.0-alpha.3",
"micromark-util-character": "1.0.0-alpha.3",
"micromark-util-chunked": "1.0.0-alpha.3",
"micromark-util-combine-extensions": "1.0.0-alpha.3",
"micromark-util-encode": "1.0.0-alpha.3",
"micromark-util-normalize-identifier": "1.0.0-alpha.3",
"micromark-util-resolve-all": "1.0.0-alpha.3",
"micromark-util-sanitize-uri": "1.0.0-alpha.3",
"micromark-util-subtokenize": "1.0.0-alpha.3",
"micromark-util-symbol": "1.0.0-alpha.3",
"micromark-util-types": "1.0.0-alpha.3",
"parse-entities": "^3.0.0"

@@ -115,0 +115,0 @@ },

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