123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- 'use strict'
- module.exports = fencedCode
- var lineFeed = '\n'
- var tab = '\t'
- var space = ' '
- var tilde = '~'
- var graveAccent = '`'
- var minFenceCount = 3
- var tabSize = 4
- function fencedCode(eat, value, silent) {
- var self = this
- var gfm = self.options.gfm
- var length = value.length + 1
- var index = 0
- var subvalue = ''
- var fenceCount
- var marker
- var character
- var flag
- var lang
- var meta
- var queue
- var content
- var exdentedContent
- var closing
- var exdentedClosing
- var indent
- var now
- if (!gfm) {
- return
- }
- // Eat initial spacing.
- while (index < length) {
- character = value.charAt(index)
- if (character !== space && character !== tab) {
- break
- }
- subvalue += character
- index++
- }
- indent = index
- // Eat the fence.
- character = value.charAt(index)
- if (character !== tilde && character !== graveAccent) {
- return
- }
- index++
- marker = character
- fenceCount = 1
- subvalue += character
- while (index < length) {
- character = value.charAt(index)
- if (character !== marker) {
- break
- }
- subvalue += character
- fenceCount++
- index++
- }
- if (fenceCount < minFenceCount) {
- return
- }
- // Eat spacing before flag.
- while (index < length) {
- character = value.charAt(index)
- if (character !== space && character !== tab) {
- break
- }
- subvalue += character
- index++
- }
- // Eat flag.
- flag = ''
- queue = ''
- while (index < length) {
- character = value.charAt(index)
- if (
- character === lineFeed ||
- (marker === graveAccent && character === marker)
- ) {
- break
- }
- if (character === space || character === tab) {
- queue += character
- } else {
- flag += queue + character
- queue = ''
- }
- index++
- }
- character = value.charAt(index)
- if (character && character !== lineFeed) {
- return
- }
- if (silent) {
- return true
- }
- now = eat.now()
- now.column += subvalue.length
- now.offset += subvalue.length
- subvalue += flag
- flag = self.decode.raw(self.unescape(flag), now)
- if (queue) {
- subvalue += queue
- }
- queue = ''
- closing = ''
- exdentedClosing = ''
- content = ''
- exdentedContent = ''
- var skip = true
- // Eat content.
- while (index < length) {
- character = value.charAt(index)
- content += closing
- exdentedContent += exdentedClosing
- closing = ''
- exdentedClosing = ''
- if (character !== lineFeed) {
- content += character
- exdentedClosing += character
- index++
- continue
- }
- // The first line feed is ignored. Others aren’t.
- if (skip) {
- subvalue += character
- skip = false
- } else {
- closing += character
- exdentedClosing += character
- }
- queue = ''
- index++
- while (index < length) {
- character = value.charAt(index)
- if (character !== space) {
- break
- }
- queue += character
- index++
- }
- closing += queue
- exdentedClosing += queue.slice(indent)
- if (queue.length >= tabSize) {
- continue
- }
- queue = ''
- while (index < length) {
- character = value.charAt(index)
- if (character !== marker) {
- break
- }
- queue += character
- index++
- }
- closing += queue
- exdentedClosing += queue
- if (queue.length < fenceCount) {
- continue
- }
- queue = ''
- while (index < length) {
- character = value.charAt(index)
- if (character !== space && character !== tab) {
- break
- }
- closing += character
- exdentedClosing += character
- index++
- }
- if (!character || character === lineFeed) {
- break
- }
- }
- subvalue += content + closing
- // Get lang and meta from the flag.
- index = -1
- length = flag.length
- while (++index < length) {
- character = flag.charAt(index)
- if (character === space || character === tab) {
- if (!lang) {
- lang = flag.slice(0, index)
- }
- } else if (lang) {
- meta = flag.slice(index)
- break
- }
- }
- return eat(subvalue)({
- type: 'code',
- lang: lang || flag || null,
- meta: meta || null,
- value: exdentedContent
- })
- }
|