UNPKG

@mapbox/jsxtreme-markdown

Version:
189 lines (151 loc) 3.79 kB
'use strict'; var whitespace = require('is-whitespace-character'); var locate = require('../locate/link'); var normalize = require('../util/normalize'); module.exports = reference; reference.locator = locate; var link = 'link'; var image = 'image'; var shortcut = 'shortcut'; var collapsed = 'collapsed'; var full = 'full'; var exclamationMark = '!'; var leftSquareBracket = '['; var backslash = '\\'; var rightSquareBracket = ']'; function reference(eat, value, silent) { var self = this; var commonmark = self.options.commonmark; var character = value.charAt(0); var index = 0; var length = value.length; var subvalue = ''; var intro = ''; var type = link; var referenceType = shortcut; var content; var identifier; var now; var node; var exit; var queue; var bracketed; var depth; // Check whether we’re eating an image. if (character === exclamationMark) { type = image; intro = character; character = value.charAt(++index); } if (character !== leftSquareBracket) { return; } index++; intro += character; queue = ''; // Eat the text. depth = 0; while (index < length) { character = value.charAt(index); if (character === leftSquareBracket) { bracketed = true; depth++; } else if (character === rightSquareBracket) { if (!depth) { break; } depth--; } if (character === backslash) { queue += backslash; character = value.charAt(++index); } queue += character; index++; } subvalue = queue; content = queue; character = value.charAt(index); if (character !== rightSquareBracket) { return; } index++; subvalue += character; queue = ''; if (!commonmark) { // The original markdown syntax definition explicitly allows for whitespace // between the link text and link label; commonmark departs from this, in // part to improve support for shortcut reference links while (index < length) { character = value.charAt(index); if (!whitespace(character)) { break; } queue += character; index++; } } character = value.charAt(index); if (character === leftSquareBracket) { identifier = ''; queue += character; index++; while (index < length) { character = value.charAt(index); if (character === leftSquareBracket || character === rightSquareBracket) { break; } if (character === backslash) { identifier += backslash; character = value.charAt(++index); } identifier += character; index++; } character = value.charAt(index); if (character === rightSquareBracket) { referenceType = identifier ? full : collapsed; queue += identifier + character; index++; } else { identifier = ''; } subvalue += queue; queue = ''; } else { if (!content) { return; } identifier = content; } // Brackets cannot be inside the identifier. if (referenceType !== full && bracketed) { return; } subvalue = intro + subvalue; if (type === link && self.inLink) { return null; } /* istanbul ignore if - never used (yet) */ if (silent) { return true; } now = eat.now(); now.column += intro.length; now.offset += intro.length; identifier = referenceType === full ? identifier : content; node = { type: type + 'Reference', identifier: normalize(identifier), label: identifier, referenceType: referenceType, }; if (type === link) { exit = self.enterLink(); node.children = self.tokenizeInline(content, now); exit(); } else { node.alt = self.decode.raw(self.unescape(content), now) || null; } return eat(subvalue)(node); }