UNPKG

@mapbox/jsxtreme-markdown

Version:
254 lines (197 loc) 4.3 kB
'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, }); }