|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {factorySpace} from 'micromark-factory-space' |
|
import {markdownLineEnding, markdownSpace} from 'micromark-util-character' |
|
import {codes} from 'micromark-util-symbol/codes.js' |
|
import {types} from 'micromark-util-symbol/types.js' |
|
import {ok as assert} from 'uvu/assert' |
|
|
|
|
|
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 === types.content) { |
|
content = index |
|
break |
|
} |
|
|
|
if (events[index][1].type === types.paragraph) { |
|
text = index |
|
} |
|
} |
|
|
|
else { |
|
if (events[index][1].type === types.content) { |
|
|
|
events.splice(index, 1) |
|
} |
|
|
|
if (!definition && events[index][1].type === types.definition) { |
|
definition = index |
|
} |
|
} |
|
} |
|
|
|
assert(text !== undefined, 'expected a `text` index to be found') |
|
assert(content !== undefined, 'expected a `text` index to be found') |
|
|
|
const heading = { |
|
type: types.setextHeading, |
|
start: Object.assign({}, events[text][1].start), |
|
end: Object.assign({}, events[events.length - 1][1].end) |
|
} |
|
|
|
|
|
events[text][1].type = types.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 |
|
|
|
assert( |
|
code === codes.dash || code === codes.equalsTo, |
|
'expected `=` or `-`' |
|
) |
|
|
|
|
|
while (index--) { |
|
|
|
|
|
if ( |
|
self.events[index][1].type !== types.lineEnding && |
|
self.events[index][1].type !== types.linePrefix && |
|
self.events[index][1].type !== types.content |
|
) { |
|
paragraph = self.events[index][1].type === types.paragraph |
|
break |
|
} |
|
} |
|
|
|
|
|
|
|
if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { |
|
effects.enter(types.setextHeadingLine) |
|
marker = code |
|
return before(code) |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function before(code) { |
|
effects.enter(types.setextHeadingLineSequence) |
|
return inside(code) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function inside(code) { |
|
if (code === marker) { |
|
effects.consume(code) |
|
return inside |
|
} |
|
|
|
effects.exit(types.setextHeadingLineSequence) |
|
|
|
return markdownSpace(code) |
|
? factorySpace(effects, after, types.lineSuffix)(code) |
|
: after(code) |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function after(code) { |
|
if (code === codes.eof || markdownLineEnding(code)) { |
|
effects.exit(types.setextHeadingLine) |
|
return ok(code) |
|
} |
|
|
|
return nok(code) |
|
} |
|
} |
|
|