123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- '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)
- }
|