123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- 'use strict'
-
- var markdownLineEnding = require('../character/markdown-line-ending.js')
-
- var codeText = {
- name: 'codeText',
- tokenize: tokenizeCodeText,
- resolve: resolveCodeText,
- previous: previous
- }
-
- function resolveCodeText(events) {
- var tailExitIndex = events.length - 4
- var headEnterIndex = 3
- var index
- var enter // If we start and end with an EOL or a space.
-
- if (
- (events[headEnterIndex][1].type === 'lineEnding' ||
- events[headEnterIndex][1].type === 'space') &&
- (events[tailExitIndex][1].type === 'lineEnding' ||
- events[tailExitIndex][1].type === 'space')
- ) {
- index = headEnterIndex // And we have data.
-
- while (++index < tailExitIndex) {
- if (events[index][1].type === 'codeTextData') {
- // Then we have padding.
- events[tailExitIndex][1].type = events[headEnterIndex][1].type =
- 'codeTextPadding'
- headEnterIndex += 2
- tailExitIndex -= 2
- break
- }
- }
- } // Merge adjacent spaces and data.
-
- index = headEnterIndex - 1
- tailExitIndex++
-
- while (++index <= tailExitIndex) {
- if (enter === undefined) {
- if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') {
- enter = index
- }
- } else if (
- index === tailExitIndex ||
- events[index][1].type === 'lineEnding'
- ) {
- events[enter][1].type = 'codeTextData'
-
- if (index !== enter + 2) {
- events[enter][1].end = events[index - 1][1].end
- events.splice(enter + 2, index - enter - 2)
- tailExitIndex -= index - enter - 2
- index = enter + 2
- }
-
- enter = undefined
- }
- }
-
- return events
- }
-
- function previous(code) {
- // If there is a previous code, there will always be a tail.
- return (
- code !== 96 ||
- this.events[this.events.length - 1][1].type === 'characterEscape'
- )
- }
-
- function tokenizeCodeText(effects, ok, nok) {
- var sizeOpen = 0
- var size
- var token
- return start
-
- function start(code) {
- effects.enter('codeText')
- effects.enter('codeTextSequence')
- return openingSequence(code)
- }
-
- function openingSequence(code) {
- if (code === 96) {
- effects.consume(code)
- sizeOpen++
- return openingSequence
- }
-
- effects.exit('codeTextSequence')
- return gap(code)
- }
-
- function gap(code) {
- // EOF.
- if (code === null) {
- return nok(code)
- } // Closing fence?
- // Could also be data.
-
- if (code === 96) {
- token = effects.enter('codeTextSequence')
- size = 0
- return closingSequence(code)
- } // Tabs don’t work, and virtual spaces don’t make sense.
-
- if (code === 32) {
- effects.enter('space')
- effects.consume(code)
- effects.exit('space')
- return gap
- }
-
- if (markdownLineEnding(code)) {
- effects.enter('lineEnding')
- effects.consume(code)
- effects.exit('lineEnding')
- return gap
- } // Data.
-
- effects.enter('codeTextData')
- return data(code)
- } // In code.
-
- function data(code) {
- if (
- code === null ||
- code === 32 ||
- code === 96 ||
- markdownLineEnding(code)
- ) {
- effects.exit('codeTextData')
- return gap(code)
- }
-
- effects.consume(code)
- return data
- } // Closing fence.
-
- function closingSequence(code) {
- // More.
- if (code === 96) {
- effects.consume(code)
- size++
- return closingSequence
- } // Done!
-
- if (size === sizeOpen) {
- effects.exit('codeTextSequence')
- effects.exit('codeText')
- return ok(code)
- } // More or less accents: mark as data.
-
- token.type = 'codeTextData'
- return data(code)
- }
- }
-
- module.exports = codeText
|