'use strict' var markdownLineEnding = require('../character/markdown-line-ending.js') var markdownLineEndingOrSpace = require('../character/markdown-line-ending-or-space.js') var markdownSpace = require('../character/markdown-space.js') var chunkedSplice = require('../util/chunked-splice.js') var factorySpace = require('./factory-space.js') var headingAtx = { name: 'headingAtx', tokenize: tokenizeHeadingAtx, resolve: resolveHeadingAtx } function resolveHeadingAtx(events, context) { var contentEnd = events.length - 2 var contentStart = 3 var content var text // Prefix whitespace, part of the opening. if (events[contentStart][1].type === 'whitespace') { contentStart += 2 } // Suffix whitespace, part of the closing. if ( contentEnd - 2 > contentStart && events[contentEnd][1].type === 'whitespace' ) { contentEnd -= 2 } if ( events[contentEnd][1].type === 'atxHeadingSequence' && (contentStart === contentEnd - 1 || (contentEnd - 4 > contentStart && events[contentEnd - 2][1].type === 'whitespace')) ) { contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 } if (contentEnd > contentStart) { content = { type: 'atxHeadingText', start: events[contentStart][1].start, end: events[contentEnd][1].end } text = { type: 'chunkText', start: events[contentStart][1].start, end: events[contentEnd][1].end, contentType: 'text' } chunkedSplice(events, contentStart, contentEnd - contentStart + 1, [ ['enter', content, context], ['enter', text, context], ['exit', text, context], ['exit', content, context] ]) } return events } function tokenizeHeadingAtx(effects, ok, nok) { var self = this var size = 0 return start function start(code) { effects.enter('atxHeading') effects.enter('atxHeadingSequence') return fenceOpenInside(code) } function fenceOpenInside(code) { if (code === 35 && size++ < 6) { effects.consume(code) return fenceOpenInside } if (code === null || markdownLineEndingOrSpace(code)) { effects.exit('atxHeadingSequence') return self.interrupt ? ok(code) : headingBreak(code) } return nok(code) } function headingBreak(code) { if (code === 35) { effects.enter('atxHeadingSequence') return sequence(code) } if (code === null || markdownLineEnding(code)) { effects.exit('atxHeading') return ok(code) } if (markdownSpace(code)) { return factorySpace(effects, headingBreak, 'whitespace')(code) } effects.enter('atxHeadingText') return data(code) } function sequence(code) { if (code === 35) { effects.consume(code) return sequence } effects.exit('atxHeadingSequence') return headingBreak(code) } function data(code) { if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { effects.exit('atxHeadingText') return headingBreak(code) } effects.consume(code) return data } } module.exports = headingAtx