This commit is contained in:
199
node_modules/micromark/dist/util/subtokenize.js
generated
vendored
Normal file
199
node_modules/micromark/dist/util/subtokenize.js
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
'use strict'
|
||||
|
||||
var assign = require('../constant/assign.js')
|
||||
var chunkedSplice = require('./chunked-splice.js')
|
||||
var shallow = require('./shallow.js')
|
||||
|
||||
function subtokenize(events) {
|
||||
var jumps = {}
|
||||
var index = -1
|
||||
var event
|
||||
var lineIndex
|
||||
var otherIndex
|
||||
var otherEvent
|
||||
var parameters
|
||||
var subevents
|
||||
var more
|
||||
|
||||
while (++index < events.length) {
|
||||
while (index in jumps) {
|
||||
index = jumps[index]
|
||||
}
|
||||
|
||||
event = events[index] // Add a hook for the GFM tasklist extension, which needs to know if text
|
||||
// is in the first content of a list item.
|
||||
|
||||
if (
|
||||
index &&
|
||||
event[1].type === 'chunkFlow' &&
|
||||
events[index - 1][1].type === 'listItemPrefix'
|
||||
) {
|
||||
subevents = event[1]._tokenizer.events
|
||||
otherIndex = 0
|
||||
|
||||
if (
|
||||
otherIndex < subevents.length &&
|
||||
subevents[otherIndex][1].type === 'lineEndingBlank'
|
||||
) {
|
||||
otherIndex += 2
|
||||
}
|
||||
|
||||
if (
|
||||
otherIndex < subevents.length &&
|
||||
subevents[otherIndex][1].type === 'content'
|
||||
) {
|
||||
while (++otherIndex < subevents.length) {
|
||||
if (subevents[otherIndex][1].type === 'content') {
|
||||
break
|
||||
}
|
||||
|
||||
if (subevents[otherIndex][1].type === 'chunkText') {
|
||||
subevents[otherIndex][1].isInFirstContentOfListItem = true
|
||||
otherIndex++
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Enter.
|
||||
|
||||
if (event[0] === 'enter') {
|
||||
if (event[1].contentType) {
|
||||
assign(jumps, subcontent(events, index))
|
||||
index = jumps[index]
|
||||
more = true
|
||||
}
|
||||
} // Exit.
|
||||
else if (event[1]._container || event[1]._movePreviousLineEndings) {
|
||||
otherIndex = index
|
||||
lineIndex = undefined
|
||||
|
||||
while (otherIndex--) {
|
||||
otherEvent = events[otherIndex]
|
||||
|
||||
if (
|
||||
otherEvent[1].type === 'lineEnding' ||
|
||||
otherEvent[1].type === 'lineEndingBlank'
|
||||
) {
|
||||
if (otherEvent[0] === 'enter') {
|
||||
if (lineIndex) {
|
||||
events[lineIndex][1].type = 'lineEndingBlank'
|
||||
}
|
||||
|
||||
otherEvent[1].type = 'lineEnding'
|
||||
lineIndex = otherIndex
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (lineIndex) {
|
||||
// Fix position.
|
||||
event[1].end = shallow(events[lineIndex][1].start) // Switch container exit w/ line endings.
|
||||
|
||||
parameters = events.slice(lineIndex, index)
|
||||
parameters.unshift(event)
|
||||
chunkedSplice(events, lineIndex, index - lineIndex + 1, parameters)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !more
|
||||
}
|
||||
|
||||
function subcontent(events, eventIndex) {
|
||||
var token = events[eventIndex][1]
|
||||
var context = events[eventIndex][2]
|
||||
var startPosition = eventIndex - 1
|
||||
var startPositions = []
|
||||
var tokenizer =
|
||||
token._tokenizer || context.parser[token.contentType](token.start)
|
||||
var childEvents = tokenizer.events
|
||||
var jumps = []
|
||||
var gaps = {}
|
||||
var stream
|
||||
var previous
|
||||
var index
|
||||
var entered
|
||||
var end
|
||||
var adjust // Loop forward through the linked tokens to pass them in order to the
|
||||
// subtokenizer.
|
||||
|
||||
while (token) {
|
||||
// Find the position of the event for this token.
|
||||
while (events[++startPosition][1] !== token) {
|
||||
// Empty.
|
||||
}
|
||||
|
||||
startPositions.push(startPosition)
|
||||
|
||||
if (!token._tokenizer) {
|
||||
stream = context.sliceStream(token)
|
||||
|
||||
if (!token.next) {
|
||||
stream.push(null)
|
||||
}
|
||||
|
||||
if (previous) {
|
||||
tokenizer.defineSkip(token.start)
|
||||
}
|
||||
|
||||
if (token.isInFirstContentOfListItem) {
|
||||
tokenizer._gfmTasklistFirstContentOfListItem = true
|
||||
}
|
||||
|
||||
tokenizer.write(stream)
|
||||
|
||||
if (token.isInFirstContentOfListItem) {
|
||||
tokenizer._gfmTasklistFirstContentOfListItem = undefined
|
||||
}
|
||||
} // Unravel the next token.
|
||||
|
||||
previous = token
|
||||
token = token.next
|
||||
} // Now, loop back through all events (and linked tokens), to figure out which
|
||||
// parts belong where.
|
||||
|
||||
token = previous
|
||||
index = childEvents.length
|
||||
|
||||
while (index--) {
|
||||
// Make sure we’ve at least seen something (final eol is part of the last
|
||||
// token).
|
||||
if (childEvents[index][0] === 'enter') {
|
||||
entered = true
|
||||
} else if (
|
||||
// Find a void token that includes a break.
|
||||
entered &&
|
||||
childEvents[index][1].type === childEvents[index - 1][1].type &&
|
||||
childEvents[index][1].start.line !== childEvents[index][1].end.line
|
||||
) {
|
||||
add(childEvents.slice(index + 1, end))
|
||||
// Help GC.
|
||||
token._tokenizer = token.next = undefined
|
||||
token = token.previous
|
||||
end = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Help GC.
|
||||
tokenizer.events = token._tokenizer = token.next = undefined // Do head:
|
||||
|
||||
add(childEvents.slice(0, end))
|
||||
index = -1
|
||||
adjust = 0
|
||||
|
||||
while (++index < jumps.length) {
|
||||
gaps[adjust + jumps[index][0]] = adjust + jumps[index][1]
|
||||
adjust += jumps[index][1] - jumps[index][0] - 1
|
||||
}
|
||||
|
||||
return gaps
|
||||
|
||||
function add(slice) {
|
||||
var start = startPositions.pop()
|
||||
jumps.unshift([start, start + slice.length - 1])
|
||||
chunkedSplice(events, start, 2, slice)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = subtokenize
|
||||
Reference in New Issue
Block a user