| 'use strict' |
| |
| var trim = require('trim-trailing-lines') |
| |
| 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 || |
| character === tilde || |
| character === graveAccent |
| ) { |
| 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 = '' |
| |
| // Eat content. |
| while (index < length) { |
| character = value.charAt(index) |
| content += closing |
| exdentedContent += exdentedClosing |
| closing = '' |
| exdentedClosing = '' |
| |
| if (character !== lineFeed) { |
| content += character |
| exdentedClosing += character |
| index++ |
| continue |
| } |
| |
| // Add the newline to `subvalue` if its the first character. Otherwise, |
| // add it to the `closing` queue. |
| if (content) { |
| closing += character |
| exdentedClosing += character |
| } else { |
| subvalue += 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: trim(exdentedContent) |
| }) |
| } |