Alex Kocharin
10 years ago
5 changed files with 175 additions and 44 deletions
@ -0,0 +1,154 @@ |
|||
// Process ![image](<src> "title")
|
|||
|
|||
'use strict'; |
|||
|
|||
var parseLinkLabel = require('../helpers/parse_link_label'); |
|||
var parseLinkDestination = require('../helpers/parse_link_destination'); |
|||
var parseLinkTitle = require('../helpers/parse_link_title'); |
|||
var normalizeReference = require('../helpers/normalize_reference'); |
|||
|
|||
|
|||
module.exports = function image(state, silent) { |
|||
var code, |
|||
href, |
|||
label, |
|||
labelEnd, |
|||
labelStart, |
|||
pos, |
|||
ref, |
|||
title, |
|||
tokens, |
|||
start, |
|||
oldPos = state.pos, |
|||
max = state.posMax; |
|||
|
|||
if (state.src.charCodeAt(state.pos) !== 0x21/* ! */) { return false; } |
|||
if (state.src.charCodeAt(state.pos + 1) !== 0x5B/* [ */) { return false; } |
|||
|
|||
labelStart = state.pos + 2; |
|||
labelEnd = parseLinkLabel(state, state.pos + 1, false); |
|||
|
|||
// parser failed to find ']', so it's not a valid link
|
|||
if (labelEnd < 0) { return false; } |
|||
|
|||
pos = labelEnd + 1; |
|||
if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) { |
|||
//
|
|||
// Inline link
|
|||
//
|
|||
|
|||
// [link]( <href> "title" )
|
|||
// ^^ skipping these spaces
|
|||
pos++; |
|||
for (; pos < max; pos++) { |
|||
code = state.src.charCodeAt(pos); |
|||
if (code !== 0x20 && code !== 0x0A) { break; } |
|||
} |
|||
if (pos >= max) { return false; } |
|||
|
|||
// [link]( <href> "title" )
|
|||
// ^^^^^^ parsing link destination
|
|||
start = pos; |
|||
if (parseLinkDestination(state, pos)) { |
|||
href = state.linkContent; |
|||
pos = state.pos; |
|||
} else { |
|||
href = ''; |
|||
} |
|||
|
|||
// [link]( <href> "title" )
|
|||
// ^^ skipping these spaces
|
|||
start = pos; |
|||
for (; pos < max; pos++) { |
|||
code = state.src.charCodeAt(pos); |
|||
if (code !== 0x20 && code !== 0x0A) { break; } |
|||
} |
|||
|
|||
// [link]( <href> "title" )
|
|||
// ^^^^^^^ parsing link title
|
|||
if (pos < max && start !== pos && parseLinkTitle(state, pos)) { |
|||
title = state.linkContent; |
|||
pos = state.pos; |
|||
|
|||
// [link]( <href> "title" )
|
|||
// ^^ skipping these spaces
|
|||
for (; pos < max; pos++) { |
|||
code = state.src.charCodeAt(pos); |
|||
if (code !== 0x20 && code !== 0x0A) { break; } |
|||
} |
|||
} else { |
|||
title = ''; |
|||
} |
|||
|
|||
if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */) { |
|||
state.pos = oldPos; |
|||
return false; |
|||
} |
|||
pos++; |
|||
} else { |
|||
//
|
|||
// Link reference
|
|||
//
|
|||
if (typeof state.env.references === 'undefined') { return false; } |
|||
|
|||
// [foo] [bar]
|
|||
// ^^ optional whitespace (can include newlines)
|
|||
for (; pos < max; pos++) { |
|||
code = state.src.charCodeAt(pos); |
|||
if (code !== 0x20 && code !== 0x0A) { break; } |
|||
} |
|||
|
|||
if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */) { |
|||
start = pos + 1; |
|||
pos = parseLinkLabel(state, pos); |
|||
if (pos >= 0) { |
|||
label = state.src.slice(start, pos++); |
|||
} else { |
|||
pos = labelEnd + 1; |
|||
} |
|||
} else { |
|||
pos = labelEnd + 1; |
|||
} |
|||
|
|||
// covers label === '' and label === undefined
|
|||
// (collapsed reference link and shortcut reference link respectively)
|
|||
if (!label) { label = state.src.slice(labelStart, labelEnd); } |
|||
|
|||
ref = state.env.references[normalizeReference(label)]; |
|||
if (!ref) { |
|||
state.pos = oldPos; |
|||
return false; |
|||
} |
|||
href = ref.href; |
|||
title = ref.title; |
|||
} |
|||
|
|||
//
|
|||
// We found the end of the link, and know for a fact it's a valid link;
|
|||
// so all that's left to do is to call tokenizer.
|
|||
//
|
|||
if (!silent) { |
|||
state.pos = labelStart; |
|||
state.posMax = labelEnd; |
|||
|
|||
var newState = new state.md.inline.State( |
|||
state.src.slice(labelStart, labelEnd), |
|||
state.md, |
|||
state.env, |
|||
tokens = [] |
|||
); |
|||
newState.md.inline.tokenize(newState); |
|||
|
|||
state.push({ |
|||
type: 'image', |
|||
src: href, |
|||
title: title, |
|||
tokens: tokens, |
|||
level: state.level |
|||
}); |
|||
} |
|||
|
|||
state.pos = pos; |
|||
state.posMax = max; |
|||
return true; |
|||
}; |
Loading…
Reference in new issue