Files
sgauthier 6e64e138e2
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
planning
2024-10-14 09:15:30 +02:00

215 lines
5.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict'
var asciiDigit = require('../character/ascii-digit.js')
var markdownSpace = require('../character/markdown-space.js')
var prefixSize = require('../util/prefix-size.js')
var sizeChunks = require('../util/size-chunks.js')
var factorySpace = require('./factory-space.js')
var partialBlankLine = require('./partial-blank-line.js')
var thematicBreak = require('./thematic-break.js')
var list = {
name: 'list',
tokenize: tokenizeListStart,
continuation: {
tokenize: tokenizeListContinuation
},
exit: tokenizeListEnd
}
var listItemPrefixWhitespaceConstruct = {
tokenize: tokenizeListItemPrefixWhitespace,
partial: true
}
var indentConstruct = {
tokenize: tokenizeIndent,
partial: true
}
function tokenizeListStart(effects, ok, nok) {
var self = this
var initialSize = prefixSize(self.events, 'linePrefix')
var size = 0
return start
function start(code) {
var kind =
self.containerState.type ||
(code === 42 || code === 43 || code === 45
? 'listUnordered'
: 'listOrdered')
if (
kind === 'listUnordered'
? !self.containerState.marker || code === self.containerState.marker
: asciiDigit(code)
) {
if (!self.containerState.type) {
self.containerState.type = kind
effects.enter(kind, {
_container: true
})
}
if (kind === 'listUnordered') {
effects.enter('listItemPrefix')
return code === 42 || code === 45
? effects.check(thematicBreak, nok, atMarker)(code)
: atMarker(code)
}
if (!self.interrupt || code === 49) {
effects.enter('listItemPrefix')
effects.enter('listItemValue')
return inside(code)
}
}
return nok(code)
}
function inside(code) {
if (asciiDigit(code) && ++size < 10) {
effects.consume(code)
return inside
}
if (
(!self.interrupt || size < 2) &&
(self.containerState.marker
? code === self.containerState.marker
: code === 41 || code === 46)
) {
effects.exit('listItemValue')
return atMarker(code)
}
return nok(code)
}
function atMarker(code) {
effects.enter('listItemMarker')
effects.consume(code)
effects.exit('listItemMarker')
self.containerState.marker = self.containerState.marker || code
return effects.check(
partialBlankLine, // Cant be empty when interrupting.
self.interrupt ? nok : onBlank,
effects.attempt(
listItemPrefixWhitespaceConstruct,
endOfPrefix,
otherPrefix
)
)
}
function onBlank(code) {
self.containerState.initialBlankLine = true
initialSize++
return endOfPrefix(code)
}
function otherPrefix(code) {
if (markdownSpace(code)) {
effects.enter('listItemPrefixWhitespace')
effects.consume(code)
effects.exit('listItemPrefixWhitespace')
return endOfPrefix
}
return nok(code)
}
function endOfPrefix(code) {
self.containerState.size =
initialSize + sizeChunks(self.sliceStream(effects.exit('listItemPrefix')))
return ok(code)
}
}
function tokenizeListContinuation(effects, ok, nok) {
var self = this
self.containerState._closeFlow = undefined
return effects.check(partialBlankLine, onBlank, notBlank)
function onBlank(code) {
self.containerState.furtherBlankLines =
self.containerState.furtherBlankLines ||
self.containerState.initialBlankLine // We have a blank line.
// Still, try to consume at most the items size.
return factorySpace(
effects,
ok,
'listItemIndent',
self.containerState.size + 1
)(code)
}
function notBlank(code) {
if (self.containerState.furtherBlankLines || !markdownSpace(code)) {
self.containerState.furtherBlankLines = self.containerState.initialBlankLine = undefined
return notInCurrentItem(code)
}
self.containerState.furtherBlankLines = self.containerState.initialBlankLine = undefined
return effects.attempt(indentConstruct, ok, notInCurrentItem)(code)
}
function notInCurrentItem(code) {
// While we do continue, we signal that the flow should be closed.
self.containerState._closeFlow = true // As were closing flow, were no longer interrupting.
self.interrupt = undefined
return factorySpace(
effects,
effects.attempt(list, ok, nok),
'linePrefix',
self.parser.constructs.disable.null.indexOf('codeIndented') > -1
? undefined
: 4
)(code)
}
}
function tokenizeIndent(effects, ok, nok) {
var self = this
return factorySpace(
effects,
afterPrefix,
'listItemIndent',
self.containerState.size + 1
)
function afterPrefix(code) {
return prefixSize(self.events, 'listItemIndent') ===
self.containerState.size
? ok(code)
: nok(code)
}
}
function tokenizeListEnd(effects) {
effects.exit(this.containerState.type)
}
function tokenizeListItemPrefixWhitespace(effects, ok, nok) {
var self = this
return factorySpace(
effects,
afterPrefix,
'listItemPrefixWhitespace',
self.parser.constructs.disable.null.indexOf('codeIndented') > -1
? undefined
: 4 + 1
)
function afterPrefix(code) {
return markdownSpace(code) ||
!prefixSize(self.events, 'listItemPrefixWhitespace')
? nok(code)
: ok(code)
}
}
module.exports = list