Files
coopgo/node_modules/micromark-extension-gfm-strikethrough/index.js
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

161 lines
4.3 KiB
JavaScript

module.exports = create
var classifyCharacter = require('micromark/dist/util/classify-character')
var chunkedSplice = require('micromark/dist/util/chunked-splice')
var resolveAll = require('micromark/dist/util/resolve-all')
var shallow = require('micromark/dist/util/shallow')
function create(options) {
var settings = options || {}
var single = settings.singleTilde
var tokenizer = {
tokenize: tokenizeStrikethrough,
resolveAll: resolveAllStrikethrough
}
if (single === null || single === undefined) {
single = true
}
return {text: {126: tokenizer}, insideSpan: {null: tokenizer}}
// Take events and resolve strikethrough.
function resolveAllStrikethrough(events, context) {
var index = -1
var strikethrough
var text
var open
var nextEvents
// Walk through all events.
while (++index < events.length) {
// Find a token that can close.
if (
events[index][0] === 'enter' &&
events[index][1].type === 'strikethroughSequenceTemporary' &&
events[index][1]._close
) {
open = index
// Now walk back to find an opener.
while (open--) {
// Find a token that can open the closer.
if (
events[open][0] === 'exit' &&
events[open][1].type === 'strikethroughSequenceTemporary' &&
events[open][1]._open &&
// If the sizes are the same:
events[index][1].end.offset - events[index][1].start.offset ===
events[open][1].end.offset - events[open][1].start.offset
) {
events[index][1].type = 'strikethroughSequence'
events[open][1].type = 'strikethroughSequence'
strikethrough = {
type: 'strikethrough',
start: shallow(events[open][1].start),
end: shallow(events[index][1].end)
}
text = {
type: 'strikethroughText',
start: shallow(events[open][1].end),
end: shallow(events[index][1].start)
}
// Opening.
nextEvents = [
['enter', strikethrough, context],
['enter', events[open][1], context],
['exit', events[open][1], context],
['enter', text, context]
]
// Between.
chunkedSplice(
nextEvents,
nextEvents.length,
0,
resolveAll(
context.parser.constructs.insideSpan.null,
events.slice(open + 1, index),
context
)
)
// Closing.
chunkedSplice(nextEvents, nextEvents.length, 0, [
['exit', text, context],
['enter', events[index][1], context],
['exit', events[index][1], context],
['exit', strikethrough, context]
])
chunkedSplice(events, open - 1, index - open + 3, nextEvents)
index = open + nextEvents.length - 2
break
}
}
}
}
return removeRemainingSequences(events)
}
function removeRemainingSequences(events) {
var index = -1
var length = events.length
while (++index < length) {
if (events[index][1].type === 'strikethroughSequenceTemporary') {
events[index][1].type = 'data'
}
}
return events
}
function tokenizeStrikethrough(effects, ok, nok) {
var previous = this.previous
var events = this.events
var size = 0
return start
function start(code) {
if (
code !== 126 ||
(previous === 126 &&
events[events.length - 1][1].type !== 'characterEscape')
) {
return nok(code)
}
effects.enter('strikethroughSequenceTemporary')
return more(code)
}
function more(code) {
var before = classifyCharacter(previous)
var token
var after
if (code === 126) {
// If this is the third marker, exit.
if (size > 1) return nok(code)
effects.consume(code)
size++
return more
}
if (size < 2 && !single) return nok(code)
token = effects.exit('strikethroughSequenceTemporary')
after = classifyCharacter(code)
token._open = !after || (after === 2 && before)
token._close = !before || (before === 2 && after)
return ok(code)
}
}
}