3 var whitespace = require('is-whitespace-character');
4 var locate = require('../locate/link');
5 var normalize = require('../util/normalize');
7 module.exports = reference;
8 reference.locator = locate;
11 var T_IMAGE = 'image';
12 var T_FOOTNOTE = 'footnote';
13 var REFERENCE_TYPE_SHORTCUT = 'shortcut';
14 var REFERENCE_TYPE_COLLAPSED = 'collapsed';
15 var REFERENCE_TYPE_FULL = 'full';
17 var C_BACKSLASH = '\\';
18 var C_BRACKET_OPEN = '[';
19 var C_BRACKET_CLOSE = ']';
21 function reference(eat, value, silent) {
23 var character = value.charAt(0);
25 var length = value.length;
29 var referenceType = REFERENCE_TYPE_SHORTCUT;
39 /* Check whether we’re eating an image. */
40 if (character === '!') {
43 character = value.charAt(++index);
46 if (character !== C_BRACKET_OPEN) {
54 /* Check whether we’re eating a footnote. */
56 self.options.footnotes &&
58 value.charAt(index) === C_CARET
68 while (index < length) {
69 character = value.charAt(index);
71 if (character === C_BRACKET_OPEN) {
74 } else if (character === C_BRACKET_CLOSE) {
82 if (character === C_BACKSLASH) {
84 character = value.charAt(++index);
93 character = value.charAt(index);
95 if (character !== C_BRACKET_CLOSE) {
100 subvalue += character;
103 while (index < length) {
104 character = value.charAt(index);
106 if (!whitespace(character)) {
114 character = value.charAt(index);
116 /* Inline footnotes cannot have an identifier. */
117 if (type !== T_FOOTNOTE && character === C_BRACKET_OPEN) {
122 while (index < length) {
123 character = value.charAt(index);
125 if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) {
129 if (character === C_BACKSLASH) {
130 identifier += C_BACKSLASH;
131 character = value.charAt(++index);
134 identifier += character;
138 character = value.charAt(index);
140 if (character === C_BRACKET_CLOSE) {
141 referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED;
142 queue += identifier + character;
155 identifier = content;
158 /* Brackets cannot be inside the identifier. */
159 if (referenceType !== REFERENCE_TYPE_FULL && bracketed) {
163 subvalue = intro + subvalue;
165 if (type === T_LINK && self.inLink) {
169 /* istanbul ignore if - never used (yet) */
174 if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) {
175 return eat(subvalue)({
177 children: this.tokenizeInline(content, eat.now())
182 now.column += intro.length;
183 now.offset += intro.length;
184 identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content;
187 type: type + 'Reference',
188 identifier: normalize(identifier)
191 if (type === T_LINK || type === T_IMAGE) {
192 node.referenceType = referenceType;
195 if (type === T_LINK) {
196 exit = self.enterLink();
197 node.children = self.tokenizeInline(content, now);
199 } else if (type === T_IMAGE) {
200 node.alt = self.decode.raw(self.unescape(content), now) || null;
203 return eat(subvalue)(node);