|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {factorySpace} from 'micromark-factory-space' |
|
import {markdownLineEnding, markdownSpace} from 'micromark-util-character' |
|
|
|
export const setextUnderline = { |
|
name: 'setextUnderline', |
|
tokenize: tokenizeSetextUnderline, |
|
resolveTo: resolveToSetextUnderline |
|
} |
|
|
|
|
|
function resolveToSetextUnderline(events, context) { |
|
|
|
let index = events.length |
|
|
|
let content |
|
|
|
let text |
|
|
|
let definition |
|
|
|
|
|
|
|
while (index--) { |
|
if (events[index][0] === 'enter') { |
|
if (events[index][1].type === 'content') { |
|
content = index |
|
break |
|
} |
|
if (events[index][1].type === 'paragraph') { |
|
text = index |
|
} |
|
} |
|
|
|
else { |
|
if (events[index][1].type === 'content') { |
|
|
|
events.splice(index, 1) |
|
} |
|
if (!definition && events[index][1].type === 'definition') { |
|
definition = index |
|
} |
|
} |
|
} |
|
const heading = { |
|
type: 'setextHeading', |
|
start: Object.assign({}, events[text][1].start), |
|
end: Object.assign({}, events[events.length - 1][1].end) |
|
} |
|
|
|
|
|
events[text][1].type = 'setextHeadingText' |
|
|
|
|
|
|
|
if (definition) { |
|
events.splice(text, 0, ['enter', heading, context]) |
|
events.splice(definition + 1, 0, ['exit', events[content][1], context]) |
|
events[content][1].end = Object.assign({}, events[definition][1].end) |
|
} else { |
|
events[content][1] = heading |
|
} |
|
|
|
|
|
events.push(['exit', heading, context]) |
|
return events |
|
} |
|
|
|
|
|
|
|
|
|
|
|
function tokenizeSetextUnderline(effects, ok, nok) { |
|
const self = this |
|
|
|
let marker |
|
return start |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function start(code) { |
|
let index = self.events.length |
|
|
|
let paragraph |
|
|
|
while (index--) { |
|
|
|
|
|
if ( |
|
self.events[index][1].type !== 'lineEnding' && |
|
self.events[index][1].type !== 'linePrefix' && |
|
self.events[index][1].type !== 'content' |
|
) { |
|
paragraph = self.events[index][1].type === 'paragraph' |
|
break |
|
} |
|
} |
|
|
|
|
|
|
|
if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { |
|
effects.enter('setextHeadingLine') |
|
marker = code |
|
return before(code) |
|
} |
|
return nok(code) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function before(code) { |
|
effects.enter('setextHeadingLineSequence') |
|
return inside(code) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function inside(code) { |
|
if (code === marker) { |
|
effects.consume(code) |
|
return inside |
|
} |
|
effects.exit('setextHeadingLineSequence') |
|
return markdownSpace(code) |
|
? factorySpace(effects, after, 'lineSuffix')(code) |
|
: after(code) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function after(code) { |
|
if (code === null || markdownLineEnding(code)) { |
|
effects.exit('setextHeadingLine') |
|
return ok(code) |
|
} |
|
return nok(code) |
|
} |
|
} |
|
|