Skip to content

Commit 43861f9

Browse files
author
Jiang Shang
committed
bugfix
1 parent c7a45be commit 43861f9

File tree

6 files changed

+240
-213
lines changed

6 files changed

+240
-213
lines changed

component.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hyperdown",
3-
"version": "0.1.0",
3+
"version": "0.1.2",
44
"repo": "segmentfault/hyperdown.js",
55
"description": "A markdown parser",
66
"keywords": ["markdown", "hyperdown", "html"],

dist/Parser.js

Lines changed: 78 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ var Parser = (function () {
8989
key: 'initText',
9090
value: function initText(text) {
9191
if (text) {
92-
text = text.replace('\t', ' ');
93-
text = text.replace('\r', '');
92+
text = text.replace(/\t/g, ' ');
93+
text = text.replace(/\r/g, '');
9494
} else {
9595
text = '';
9696
}
@@ -119,6 +119,7 @@ var Parser = (function () {
119119
html += '<li id="fn-' + index + '">' + val + '</li>';
120120

121121
index++;
122+
val = this.footnotes.pop();
122123
}
123124
html += '</ol></div>';
124125
}
@@ -134,7 +135,7 @@ var Parser = (function () {
134135
}, {
135136
key: 'parse',
136137
value: function parse(text) {
137-
var _this = this;
138+
var _this2 = this;
138139

139140
var lines = text.split("\n");
140141
var blocks = this.parseBlock(text, lines);
@@ -151,9 +152,9 @@ var Parser = (function () {
151152
var extract = lines.slice(start, end + 1);
152153
var method = 'parse' + type.slice(0, 1).toUpperCase() + type.slice(1);
153154
var beforeMethod = 'beforeParse' + type.slice(0, 1).toUpperCase() + type.slice(1);
154-
extract = _this.call(beforeMethod, extract, value);
155-
var result = _this[method](extract, value);
156-
result = _this.call('after' + method.slice(0, 1).toUpperCase() + method.slice(1), result, value);
155+
extract = _this2.call(beforeMethod, extract, value);
156+
var result = _this2[method](extract, value);
157+
result = _this2.call('after' + method.slice(0, 1).toUpperCase() + method.slice(1), result, value);
157158

158159
html += result;
159160
});
@@ -222,14 +223,20 @@ var Parser = (function () {
222223
var whiteList = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];
223224

224225
text = this.call('beforeParseInline', text);
225-
226+
var _this = this;
226227
// code
227-
var codeMatches = /(^|[^\\])`(.+?)`/.exec(text);
228-
if (codeMatches) {
229-
text = codeMatches[1] + this.makeHolder('<code>' + this.htmlspecialchars(codeMatches[2]) + '</code>');
230-
}
228+
text = text.replace(/(^|[^\\])(`+)(.+?)\2/g, function () {
229+
var codeMatches = /(^|[^\\])(`+)(.+?)\2/g.exec(text);
230+
return codeMatches[1] + _this.makeHolder('<code>' + _this.htmlspecialchars(codeMatches[3]) + '</code>');
231+
});
231232

232-
// escape unsafe tags
233+
// link
234+
text = text.replace(/<(https?:\/\/.+)>/ig, function () {
235+
var linkMatches = /<(https?:\/\/.+)>/ig.exec(text);
236+
return '<a href="' + linkMatches[1] + '">' + linkMatches[1] + '</a>';
237+
});
238+
239+
// encode unsafe tags
233240
var unsafeTagMatches = /<(\/?)([a-z0-9-]+)(\s+[^>]*)?>/i.exec(text);
234241
if (unsafeTagMatches) {
235242
var whiteLists = this.commonWhiteList + '|' + whiteList;
@@ -240,83 +247,84 @@ var Parser = (function () {
240247
}
241248
}
242249

243-
text = text.replace('<', '&lt;');
244-
text = text.replace('>', '&gt;');
250+
text = text.replace(/</g, '&lt;');
251+
text = text.replace(/>/g, '&gt;');
252+
253+
// footnote
254+
var footnotePattern = /\[\^((?:[^\]]|\]|\[)+?)\]/g;
245255

246-
var footnotePattern = /\[\^((?:[^\]]|\]|\[)+?)\]/;
247-
var footnoteMatches = footnotePattern.exec(text);
248-
if (footnoteMatches) {
249-
var id = this.footnotes.indexOf(footnoteMatches[1]);
256+
text = text.replace(footnotePattern, function () {
257+
var footnoteMatches = text.match(footnoteMatches);
258+
var id = _this.footnotes.indexOf(footnoteMatches[1]);
250259

251260
if (id === -1) {
252-
id = this.footnotes.length + 1;
253-
this.footnotes[id] = footnoteMatches[1];
261+
id = _this.footnotes.length + 1;
262+
_this.footnotes[id] = footnoteMatches[1];
254263
}
255264

256-
text = this.makeHolder('<sup id="fnref-' + id + '"><a href="#fn-' + id + '" class="footnote-ref">' + id + '</a></sup>');
257-
}
265+
return _this.makeHolder('<sup id="fnref-' + id + '"><a href="#fn-' + id + '" class="footnote-ref">' + id + '</a></sup>');
266+
});
258267

259268
// image
260269
var imagePattern1 = /!\[((?:[^\]]|\]|\[)*?)\]\(((?:[^\)]|\)|\()+?)\)/;
261270
var imageMatches1 = imagePattern1.exec(text);
262-
if (imageMatches1) {
263-
var escaped = this.escapeBracket(imageMatches1[1]);
264-
var url = this.escapeBracket(imageMatches1[2]);
265-
text = this.makeHolder('<img src="' + url + '" alt="' + escaped + '" title="' + escaped + '">');
266-
}
271+
text = text.replace(imagePattern1, function () {
272+
var escaped = _this.escapeBracket(imageMatches1[1]);
273+
var url = _this.escapeBracket(imageMatches1[2]);
274+
return _this.makeHolder('<img src="' + url + '" alt="' + escaped + '" title="' + escaped + '">');
275+
});
267276

268277
var imagePattern2 = /!\[((?:[^\]]|\]|\[)*?)\]\[((?:[^\]]|\]|\[)+?)\]/;
269278
var imageMatches2 = imagePattern2.exec(text);
270-
if (imageMatches2) {
271-
var escaped = this.escapeBracket(imageMatches2[1]);
279+
text = text.replace(imagePattern2, function () {
280+
var escaped = _this.escapeBracket(imageMatches2[1]);
272281
var result = '';
273-
if (this.definitions[imageMatches2[2]]) {
274-
result = '<img src="' + this.definitions[imageMatches2[2]] + '" alt="' + escaped + '" title="' + escaped + '">';
282+
if (_this.definitions[imageMatches2[2]]) {
283+
result = '<img src="' + _this.definitions[imageMatches2[2]] + '" alt="' + escaped + '" title="' + escaped + '">';
275284
} else {
276285
result = escaped;
277286
}
278-
text = this.makeHolder(result);
279-
}
287+
return _this.makeHolder(result);
288+
});
280289

281290
// link
282291
var linkPattern1 = /\[((?:[^\]]|\]|\[)+?)\]\(((?:[^\)]|\)|\()+?)\)/;
283292
var linkMatches1 = linkPattern1.exec(text);
284293

285-
if (linkMatches1) {
286-
var escaped = this.escapeBracket(linkMatches1[1]);
287-
var url = this.escapeBracket(linkMatches1[2]);
288-
text = this.makeHolder('<a href="' + url + '">' + escaped + '</a>');
289-
}
294+
text = text.replace(linkPattern1, function () {
295+
var escaped = _this.escapeBracket(linkMatches1[1]);
296+
var url = _this.escapeBracket(linkMatches1[2]);
297+
return _this.makeHolder('<a href="' + url + '">' + escaped + '</a>');
298+
});
290299

291300
var linkPattern2 = /\[((?:[^\]]|\]|\[)+?)\]\[((?:[^\]]|\]|\[)+?)\]/;
292301
var linkMatches2 = linkPattern2.exec(text);
293-
if (linkMatches2) {
294-
var escaped = this.escapeBracket(linkMatches2[1]);
302+
text = text.replace(linkPattern2, function () {
303+
var escaped = _this.escapeBracket(linkMatches2[1]);
295304

296-
var result = this.definitions[linkMatches2[2]] ? '<a href="' + this.definitions[linkMatches2[2]] + '">' + escaped + '</a>' : escaped;
305+
var result = _this.definitions[linkMatches2[2]] ? '<a href="' + _this.definitions[linkMatches2[2]] + '">' + escaped + '</a>' : escaped;
297306

298-
text = this.makeHolder(result);
299-
}
307+
return _this.makeHolder(result);
308+
});
300309

301310
// escape
302-
var escapeMatches = /\\(`|\*|_|~)/.exec(text);
303-
if (escapeMatches) {
304-
text = this.makeHolder(this.htmlspecialchars(escapeMatches[1]));
305-
}
311+
text = text.replace(/\\(`|\*|_|~)/, function () {
312+
var escapeMatches = /\\(`|\*|_|~)/.exec(text);
313+
return _this.makeHolder(_this.htmlspecialchars(escapeMatches[1]));
314+
});
306315

307316
// strong and em and some fuck
308-
text = text.replace(/(\*{3})(.+?)\1/, "<strong><em>$2</em></strong>");
309-
text = text.replace(/(\*{2})(.+?)\1/, "<strong>$2</strong>");
310-
text = text.replace(/(\*)(.+?)\1/, "<em>$2</em>");
311-
text = text.replace(/(\s+)(_{3})(.+?)\2(\s+)/, "$1<strong><em>$3</em></strong>$4");
312-
text = text.replace(/(\s+)(_{2})(.+?)\2(\s+)/, "$1<strong>$3</strong>$4");
313-
text = text.replace(/(\s+)(_)(.+?)\2(\s+)/, "$1<em>$3</em>$4");
314-
text = text.replace(/(~{2})(.+?)\1/, "<del>$2</del>");
315-
text = text.replace(/<(https?:\/\/.+)>/i, "<a href=\"$1\">$1</a>");
316-
text = text.replace(/<([_a-z0-9-\.\+]+@[^@]+\.[a-z]{2,})>/i, "<a href=\"mailto:$1\">$1</a>");
317+
text = text.replace(/(\*{3})(.+?)\1/g, "<strong><em>$2</em></strong>");
318+
text = text.replace(/(\*{2})(.+?)\1/g, "<strong>$2</strong>");
319+
text = text.replace(/(\*)(.+?)\1/g, "<em>$2</em>");
320+
text = text.replace(/(\s+)(_{3})(.+?)\2(\s+)/g, "$1<strong><em>$3</em></strong>$4");
321+
text = text.replace(/(\s+)(_{2})(.+?)\2(\s+)/g, "$1<strong>$3</strong>$4");
322+
text = text.replace(/(\s+)(_)(.+?)\2(\s+)/g, "$1<em>$3</em>$4");
323+
text = text.replace(/(~{2})(.+?)\1/g, "<del>$2</del>");
324+
text = text.replace(/<([_a-z0-9-\.\+]+@[^@]+\.[a-z]{2,})>/ig, "<a href=\"mailto:$1\">$1</a>");
317325

318326
// autolink url
319-
text = text.replace(/(^|[^"])((http|https|ftp|mailto):[_a-z0-9-\.\/%#@\?\+=~\|\,]+)($|[^"])/i, "$1<a href=\"$2\">$2</a>$4");
327+
text = text.replace(/(^|[^"])((http|https|ftp|mailto):[_a-z0-9-\.\/%#@\?\+=~\|\,]+)($|[^"])/ig, "$1<a href=\"$2\">$2</a>$4");
320328

321329
text = this.call('afterParseInlineBeforeRelease', text);
322330

@@ -414,7 +422,7 @@ var Parser = (function () {
414422

415423
// footnote
416424
case /^\[\^((?:[^\]]|\]|\[)+?)\]:/.test(line):
417-
var footnoteMatches = line.match(/^\[\^((?:[^\]]|\]|\[)+?)\]:/);
425+
var footnoteMatches = /^\[\^((?:[^\]]|\]|\[)+?)\]:/.exec(line);
418426
var footnoteSpace = footnoteMatches[0].length - 1;
419427
this.startBlock('footnote', key, [footnoteSpace, footnoteMatches[1]]);
420428
break;
@@ -625,7 +633,7 @@ var Parser = (function () {
625633

626634
if ('normal' === type) {
627635
// combine two splitted list
628-
if (from === to && lines[from].match(/^\s*$/) && prevBlock.length && nextBlock.length) {
636+
if (from === to && lines[from].match(/^\s*$/) && prevBlock && nextBlock) {
629637
if (prevBlock[0] === 'list' && nextBlock[0] === 'list') {
630638
// combine 3 blocks
631639
blocks[key - 1] = ['list', prevBlock[1], nextBlock[2], null];
@@ -897,7 +905,7 @@ var Parser = (function () {
897905
}, {
898906
key: 'parseTable',
899907
value: function parseTable(lines, value) {
900-
var _this2 = this;
908+
var _this3 = this;
901909

902910
var _value = _slicedToArray(value, 2);
903911

@@ -976,7 +984,7 @@ var Parser = (function () {
976984
html += ' align="' + aligns[key] + '"';
977985
}
978986

979-
html += '>' + _this2.parseInline(text) + ('</' + tag + '>');
987+
html += '>' + _this3.parseInline(text) + ('</' + tag + '>');
980988
});
981989

982990
html += '</tr>';
@@ -1022,15 +1030,15 @@ var Parser = (function () {
10221030
}, {
10231031
key: 'parseNormal',
10241032
value: function parseNormal(lines) {
1025-
var _this3 = this;
1033+
var _this4 = this;
10261034

10271035
lines = lines.map(function (line) {
1028-
return _this3.parseInline(line);
1036+
return _this4.parseInline(line);
10291037
});
10301038

10311039
var str = lines.join("\n").trim();
1032-
str = str.replace(/(\n\s*){2,}/, "</p><p>");
1033-
str = str.replace(/\n/, "<br>");
1040+
str = str.replace(/(\n\s*){2,}/g, "</p><p>");
1041+
str = str.replace(/\n/g, "<br>");
10341042

10351043
return (/^\s*$/.test(str) ? '' : '<p>' + str + '</p>'
10361044
);
@@ -1052,8 +1060,7 @@ var Parser = (function () {
10521060
var note = _value2[1];
10531061

10541062
var index = this.footnotes.indexOf(note);
1055-
1056-
if (false !== index) {
1063+
if (-1 !== index) {
10571064
if (lines[0]) {
10581065
lines[0] = lines[0].replace(/^\[\^((?:[^\]]|\]|\[)+?)\]:/, '');
10591066
}
@@ -1120,10 +1127,10 @@ var Parser = (function () {
11201127
key: 'escapeBracket',
11211128
value: function escapeBracket(str) {
11221129
if (str) {
1123-
str = str.replace('\[', '[');
1124-
str = str.replace('\]', ']');
1125-
str = str.replace('\(', '(');
1126-
str = str.replace('\)', ')');
1130+
str = str.replace(/\[/g, '[');
1131+
str = str.replace(/\]/g, ']');
1132+
str = str.replace(/\(/g, '(');
1133+
str = str.replace(/\)/g, ')');
11271134
return str;
11281135
}
11291136
}

0 commit comments

Comments
 (0)