Browse Source

Split links rule to link+image

pull/24/head
Alex Kocharin 10 years ago
parent
commit
6497e9a80f
  1. 3
      lib/parser_inline.js
  2. 3
      lib/presets/commonmark.js
  3. 3
      lib/presets/default.js
  4. 154
      lib/rules_inline/image.js
  5. 38
      lib/rules_inline/link.js

3
lib/parser_inline.js

@ -19,7 +19,8 @@ var _rules = [
[ 'backticks', require('./rules_inline/backticks') ], [ 'backticks', require('./rules_inline/backticks') ],
[ 'del', require('./rules_inline/del') ], [ 'del', require('./rules_inline/del') ],
[ 'emphasis', require('./rules_inline/emphasis') ], [ 'emphasis', require('./rules_inline/emphasis') ],
[ 'links', require('./rules_inline/links') ], [ 'link', require('./rules_inline/link') ],
[ 'image', require('./rules_inline/image') ],
[ 'footnote_inline', require('./rules_inline/footnote_inline') ], [ 'footnote_inline', require('./rules_inline/footnote_inline') ],
[ 'footnote_ref', require('./rules_inline/footnote_ref') ], [ 'footnote_ref', require('./rules_inline/footnote_ref') ],
[ 'autolink', require('./rules_inline/autolink') ], [ 'autolink', require('./rules_inline/autolink') ],

3
lib/presets/commonmark.js

@ -61,7 +61,8 @@ module.exports = {
'entity', 'entity',
'escape', 'escape',
'htmltag', 'htmltag',
'links', 'image',
'link',
'newline', 'newline',
'text' 'text'
] ]

3
lib/presets/default.js

@ -69,7 +69,8 @@ module.exports = {
'escape', 'escape',
'footnote_ref', 'footnote_ref',
'htmltag', 'htmltag',
'links', 'image',
'link',
'newline', 'newline',
'text' 'text'
] ]

154
lib/rules_inline/image.js

@ -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;
};

38
lib/rules_inline/links.js → lib/rules_inline/link.js

@ -1,4 +1,4 @@
// Process [links](<to> "stuff") // Process [link](<to> "stuff")
'use strict'; 'use strict';
@ -8,7 +8,7 @@ var parseLinkTitle = require('../helpers/parse_link_title');
var normalizeReference = require('../helpers/normalize_reference'); var normalizeReference = require('../helpers/normalize_reference');
module.exports = function links(state, silent) { module.exports = function link(state, silent) {
var code, var code,
href, href,
label, label,
@ -17,22 +17,14 @@ module.exports = function links(state, silent) {
pos, pos,
ref, ref,
title, title,
tokens,
isImage = false,
oldPos = state.pos, oldPos = state.pos,
max = state.posMax, max = state.posMax,
start = state.pos, start = state.pos;
marker = state.src.charCodeAt(start);
if (marker === 0x21/* ! */) { if (state.src.charCodeAt(state.pos) !== 0x5B/* [ */) { return false; }
isImage = true;
marker = state.src.charCodeAt(++start);
}
if (marker !== 0x5B/* [ */) { return false; }
labelStart = start + 1; labelStart = state.pos + 1;
labelEnd = parseLinkLabel(state, start, !isImage); labelEnd = parseLinkLabel(state, state.pos, true);
// parser failed to find ']', so it's not a valid link // parser failed to find ']', so it's not a valid link
if (labelEnd < 0) { return false; } if (labelEnd < 0) { return false; }
@ -137,23 +129,6 @@ module.exports = function links(state, silent) {
state.pos = labelStart; state.pos = labelStart;
state.posMax = labelEnd; state.posMax = labelEnd;
if (isImage) {
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
});
} else {
state.push({ state.push({
type: 'link_open', type: 'link_open',
href: href, href: href,
@ -164,7 +139,6 @@ module.exports = function links(state, silent) {
state.md.inline.tokenize(state); state.md.inline.tokenize(state);
state.push({ type: 'link_close', level: --state.level }); state.push({ type: 'link_close', level: --state.level });
} }
}
state.pos = pos; state.pos = pos;
state.posMax = max; state.posMax = max;
Loading…
Cancel
Save