274 lines
5.0 KiB
JavaScript
274 lines
5.0 KiB
JavaScript
'use strict'
|
|
|
|
var whitespace = require('is-whitespace-character')
|
|
var normalize = require('../util/normalize')
|
|
|
|
module.exports = definition
|
|
|
|
var quotationMark = '"'
|
|
var apostrophe = "'"
|
|
var backslash = '\\'
|
|
var lineFeed = '\n'
|
|
var tab = '\t'
|
|
var space = ' '
|
|
var leftSquareBracket = '['
|
|
var rightSquareBracket = ']'
|
|
var leftParenthesis = '('
|
|
var rightParenthesis = ')'
|
|
var colon = ':'
|
|
var lessThan = '<'
|
|
var greaterThan = '>'
|
|
|
|
function definition(eat, value, silent) {
|
|
var self = this
|
|
var commonmark = self.options.commonmark
|
|
var index = 0
|
|
var length = value.length
|
|
var subvalue = ''
|
|
var beforeURL
|
|
var beforeTitle
|
|
var queue
|
|
var character
|
|
var test
|
|
var identifier
|
|
var url
|
|
var title
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (character !== space && character !== tab) {
|
|
break
|
|
}
|
|
|
|
subvalue += character
|
|
index++
|
|
}
|
|
|
|
character = value.charAt(index)
|
|
|
|
if (character !== leftSquareBracket) {
|
|
return
|
|
}
|
|
|
|
index++
|
|
subvalue += character
|
|
queue = ''
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (character === rightSquareBracket) {
|
|
break
|
|
} else if (character === backslash) {
|
|
queue += character
|
|
index++
|
|
character = value.charAt(index)
|
|
}
|
|
|
|
queue += character
|
|
index++
|
|
}
|
|
|
|
if (
|
|
!queue ||
|
|
value.charAt(index) !== rightSquareBracket ||
|
|
value.charAt(index + 1) !== colon
|
|
) {
|
|
return
|
|
}
|
|
|
|
identifier = queue
|
|
subvalue += queue + rightSquareBracket + colon
|
|
index = subvalue.length
|
|
queue = ''
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (character !== tab && character !== space && character !== lineFeed) {
|
|
break
|
|
}
|
|
|
|
subvalue += character
|
|
index++
|
|
}
|
|
|
|
character = value.charAt(index)
|
|
queue = ''
|
|
beforeURL = subvalue
|
|
|
|
if (character === lessThan) {
|
|
index++
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (!isEnclosedURLCharacter(character)) {
|
|
break
|
|
}
|
|
|
|
queue += character
|
|
index++
|
|
}
|
|
|
|
character = value.charAt(index)
|
|
|
|
if (character === isEnclosedURLCharacter.delimiter) {
|
|
subvalue += lessThan + queue + character
|
|
index++
|
|
} else {
|
|
if (commonmark) {
|
|
return
|
|
}
|
|
|
|
index -= queue.length + 1
|
|
queue = ''
|
|
}
|
|
}
|
|
|
|
if (!queue) {
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (!isUnclosedURLCharacter(character)) {
|
|
break
|
|
}
|
|
|
|
queue += character
|
|
index++
|
|
}
|
|
|
|
subvalue += queue
|
|
}
|
|
|
|
if (!queue) {
|
|
return
|
|
}
|
|
|
|
url = queue
|
|
queue = ''
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (character !== tab && character !== space && character !== lineFeed) {
|
|
break
|
|
}
|
|
|
|
queue += character
|
|
index++
|
|
}
|
|
|
|
character = value.charAt(index)
|
|
test = null
|
|
|
|
if (character === quotationMark) {
|
|
test = quotationMark
|
|
} else if (character === apostrophe) {
|
|
test = apostrophe
|
|
} else if (character === leftParenthesis) {
|
|
test = rightParenthesis
|
|
}
|
|
|
|
if (!test) {
|
|
queue = ''
|
|
index = subvalue.length
|
|
} else if (queue) {
|
|
subvalue += queue + character
|
|
index = subvalue.length
|
|
queue = ''
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (character === test) {
|
|
break
|
|
}
|
|
|
|
if (character === lineFeed) {
|
|
index++
|
|
character = value.charAt(index)
|
|
|
|
if (character === lineFeed || character === test) {
|
|
return
|
|
}
|
|
|
|
queue += lineFeed
|
|
}
|
|
|
|
queue += character
|
|
index++
|
|
}
|
|
|
|
character = value.charAt(index)
|
|
|
|
if (character !== test) {
|
|
return
|
|
}
|
|
|
|
beforeTitle = subvalue
|
|
subvalue += queue + character
|
|
index++
|
|
title = queue
|
|
queue = ''
|
|
} else {
|
|
return
|
|
}
|
|
|
|
while (index < length) {
|
|
character = value.charAt(index)
|
|
|
|
if (character !== tab && character !== space) {
|
|
break
|
|
}
|
|
|
|
subvalue += character
|
|
index++
|
|
}
|
|
|
|
character = value.charAt(index)
|
|
|
|
if (!character || character === lineFeed) {
|
|
if (silent) {
|
|
return true
|
|
}
|
|
|
|
beforeURL = eat(beforeURL).test().end
|
|
url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false})
|
|
|
|
if (title) {
|
|
beforeTitle = eat(beforeTitle).test().end
|
|
title = self.decode.raw(self.unescape(title), beforeTitle)
|
|
}
|
|
|
|
return eat(subvalue)({
|
|
type: 'definition',
|
|
identifier: normalize(identifier),
|
|
label: identifier,
|
|
title: title || null,
|
|
url: url
|
|
})
|
|
}
|
|
}
|
|
|
|
// Check if `character` can be inside an enclosed URI.
|
|
function isEnclosedURLCharacter(character) {
|
|
return (
|
|
character !== greaterThan &&
|
|
character !== leftSquareBracket &&
|
|
character !== rightSquareBracket
|
|
)
|
|
}
|
|
|
|
isEnclosedURLCharacter.delimiter = greaterThan
|
|
|
|
// Check if `character` can be inside an unclosed URI.
|
|
function isUnclosedURLCharacter(character) {
|
|
return (
|
|
character !== leftSquareBracket &&
|
|
character !== rightSquareBracket &&
|
|
!whitespace(character)
|
|
)
|
|
}
|