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. 56
      lib/rules_inline/link.js

3
lib/parser_inline.js

@ -19,7 +19,8 @@ var _rules = [
[ 'backticks', require('./rules_inline/backticks') ],
[ 'del', require('./rules_inline/del') ],
[ '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_ref', require('./rules_inline/footnote_ref') ],
[ 'autolink', require('./rules_inline/autolink') ],

3
lib/presets/commonmark.js

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

3
lib/presets/default.js

@ -69,7 +69,8 @@ module.exports = {
'escape',
'footnote_ref',
'htmltag',
'links',
'image',
'link',
'newline',
'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;
};

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

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