You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.0 KiB
117 lines
3.0 KiB
'use strict' |
|
|
|
var markdownLineEnding = require('../character/markdown-line-ending.js') |
|
var shallow = require('../util/shallow.js') |
|
var factorySpace = require('./factory-space.js') |
|
|
|
var setextUnderline = { |
|
name: 'setextUnderline', |
|
tokenize: tokenizeSetextUnderline, |
|
resolveTo: resolveToSetextUnderline |
|
} |
|
|
|
function resolveToSetextUnderline(events, context) { |
|
var index = events.length |
|
var content |
|
var text |
|
var definition |
|
var heading // Find the opening of the content. |
|
// It’ll always exist: we don’t tokenize if it isn’t there. |
|
|
|
while (index--) { |
|
if (events[index][0] === 'enter') { |
|
if (events[index][1].type === 'content') { |
|
content = index |
|
break |
|
} |
|
|
|
if (events[index][1].type === 'paragraph') { |
|
text = index |
|
} |
|
} // Exit |
|
else { |
|
if (events[index][1].type === 'content') { |
|
// Remove the content end (if needed we’ll add it later) |
|
events.splice(index, 1) |
|
} |
|
|
|
if (!definition && events[index][1].type === 'definition') { |
|
definition = index |
|
} |
|
} |
|
} |
|
|
|
heading = { |
|
type: 'setextHeading', |
|
start: shallow(events[text][1].start), |
|
end: shallow(events[events.length - 1][1].end) |
|
} // Change the paragraph to setext heading text. |
|
|
|
events[text][1].type = 'setextHeadingText' // If we have definitions in the content, we’ll keep on having content, |
|
// but we need move it. |
|
|
|
if (definition) { |
|
events.splice(text, 0, ['enter', heading, context]) |
|
events.splice(definition + 1, 0, ['exit', events[content][1], context]) |
|
events[content][1].end = shallow(events[definition][1].end) |
|
} else { |
|
events[content][1] = heading |
|
} // Add the heading exit at the end. |
|
|
|
events.push(['exit', heading, context]) |
|
return events |
|
} |
|
|
|
function tokenizeSetextUnderline(effects, ok, nok) { |
|
var self = this |
|
var index = self.events.length |
|
var marker |
|
var paragraph // Find an opening. |
|
|
|
while (index--) { |
|
// Skip enter/exit of line ending, line prefix, and content. |
|
// We can now either have a definition or a paragraph. |
|
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 |
|
} |
|
} |
|
|
|
return start |
|
|
|
function start(code) { |
|
if (!self.lazy && (self.interrupt || paragraph)) { |
|
effects.enter('setextHeadingLine') |
|
effects.enter('setextHeadingLineSequence') |
|
marker = code |
|
return closingSequence(code) |
|
} |
|
|
|
return nok(code) |
|
} |
|
|
|
function closingSequence(code) { |
|
if (code === marker) { |
|
effects.consume(code) |
|
return closingSequence |
|
} |
|
|
|
effects.exit('setextHeadingLineSequence') |
|
return factorySpace(effects, closingSequenceEnd, 'lineSuffix')(code) |
|
} |
|
|
|
function closingSequenceEnd(code) { |
|
if (code === null || markdownLineEnding(code)) { |
|
effects.exit('setextHeadingLine') |
|
return ok(code) |
|
} |
|
|
|
return nok(code) |
|
} |
|
} |
|
|
|
module.exports = setextUnderline
|
|
|