Ox.parseMarkdown: don't make replacements inside code spans/blocks; Ox.sanitizeHTML: add (failing) test; remove unneccessary escaping inside [] in regular expressions

This commit is contained in:
rolux 2012-06-24 15:37:46 +02:00
parent 8312105427
commit 966ceeb1f1

View file

@ -71,7 +71,7 @@
function addLinks(string, obfuscate) { function addLinks(string, obfuscate) {
return string return string
.replace( .replace(
/\b((https?:\/\/|www\.).+?)([\.,:;!\?\)\]]*?(\s|$))/gi, /\b((https?:\/\/|www\.).+?)([.,:;!?)\]]*?(\s|$))/gi,
function(match, url, prefix, end) { function(match, url, prefix, end) {
prefix = prefix.toLowerCase() == 'www.' ? 'http://' : ''; prefix = prefix.toLowerCase() == 'www.' ? 'http://' : '';
return Ox.formatString( return Ox.formatString(
@ -81,7 +81,7 @@
} }
) )
.replace( .replace(
/\b([0-9A-Z\.\+\-_]+@(?:[0-9A-Z\-]+\.)+[A-Z]{2,6})\b/gi, /\b([0-9A-Z.+\-_]+@(?:[0-9A-Z\-]+\.)+[A-Z]{2,6})\b/gi,
obfuscate ? function(match, mail) { obfuscate ? function(match, mail) {
return Ox.encodeEmailAddress(mail); return Ox.encodeEmailAddress(mail);
} : '<a href="mailto:$1">$1</a>' } : '<a href="mailto:$1">$1</a>'
@ -370,14 +370,21 @@
/*@ /*@
Ox.parseMarkdown <f> Parses (a tiny subset of) Markdown. Ox.parseMarkdown <f> Parses (a tiny subset of) Markdown.
Supports `*emphasis*`, `_emphasis_`, `**strong**`, `__strong__`,
`` `code` ``, ``` ``code with backtick (`)`` ```,
```` ```classname\ngithub-style\ncode blocks\n``` ````,
`<mail@example.com>`, `<http://example.com>` and
`[text](http://example.com "title")`.
> Ox.parseMarkdown('*foo* **bar** `baz` ``back`tick``') > Ox.parseMarkdown('*foo* **bar** `baz` ``back`tick``')
'<em>foo</em> <strong>bar</strong> <code>baz</code> <code>back`tick</code>' '<em>foo</em> <strong>bar</strong> <code>baz</code> <code>back`tick</code>'
> Ox.parseMarkdown('foo\n\nbar\n\nbaz') > Ox.parseMarkdown('foo\n\nbar\n\nbaz')
'foo<br><br>bar<br><br>baz' 'foo<br><br>bar<br><br>baz'
> Ox.parseMarkdown('\n```foo\n\nbar\n\nbaz\n```') > Ox.parseMarkdown('```foo\n\nbar\n\nbaz\n```')
'<pre><code class="foo">bar<br><br>baz</code></pre>' '<pre><code class="foo">bar\n\nbaz\n</code></pre>'
> Ox.parseMarkdown('<http://example.com>') > Ox.parseMarkdown('<http://example.com>')
'<a href="http://example.com">http://example.com</a>' '<a href="http://example.com">http://example.com</a>'
> Ox.parseMarkdown('`<http://example.com>`')
'<code>&lt;http://example.com></code>'
> Ox.parseMarkdown('[example](http://example.com "example.com")') > Ox.parseMarkdown('[example](http://example.com "example.com")')
'<a href="http://example.com" title="example.com">example</a>' '<a href="http://example.com" title="example.com">example</a>'
> Ox.parseMarkdown('[example](http://example.com?foo=bar&bar=baz)') > Ox.parseMarkdown('[example](http://example.com?foo=bar&bar=baz)')
@ -393,7 +400,29 @@
*/ */
Ox.parseMarkdown = function(string) { Ox.parseMarkdown = function(string) {
// see https://github.com/coreyti/showdown/blob/master/src/showdown.js // see https://github.com/coreyti/showdown/blob/master/src/showdown.js
var array = [];
return string.replace(/\r\n/g, '\n').replace(/\r/g, '\n') return string.replace(/\r\n/g, '\n').replace(/\r/g, '\n')
.replace(
/(?:^|\n)```(.*)\n([^`]+)\n```/g,
function(match, classname, code) {
array.push(
'<pre><code'
+ (classname ? ' class="' + classname + '"' : '') + '>'
+ code.trim().replace(/</g, '&lt;') + '\n</code></pre>'
);
return salt.join(array.length - 1);
}
)
.replace(
/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
function(match, prev, backticks, code, next) {
array.push(
prev + '<code>'
+ code.trim().replace(/</g, '&lt;') + '</code>'
);
return salt.join(array.length - 1);
}
)
.replace( .replace(
/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g, /(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
'<strong>$2</strong>' '<strong>$2</strong>'
@ -402,21 +431,6 @@
/(\*|_)(?=\S)([^\r]*?\S)\1/g, /(\*|_)(?=\S)([^\r]*?\S)\1/g,
'<em>$2</em>' '<em>$2</em>'
) )
.replace(
/\n```(.*)\n([^`]+)\n```/g,
function(match, classname, code) {
return '<pre><code'
+ (classname ? ' class="' + classname + '"' : '') + '>'
+ code.trim().replace(/</g, '&lt;') + '\n</code></pre>';
}
)
.replace(
/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
function(match, prev, backticks, code, next) {
return prev + '<code>'
+ code.trim().replace(/</g, '&lt;') + '</code>';
}
)
.replace( .replace(
/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, /(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,
function(match, all, text, id, url, rest, quote, title) { function(match, all, text, id, url, rest, quote, title) {
@ -435,7 +449,13 @@
return Ox.encodeEmailAddress(mail); return Ox.encodeEmailAddress(mail);
} }
) )
.replace(/\n\n/g, '<br><br>'); .replace(/\n\n/g, '<br><br>')
.replace(
new RegExp(salt.join('(\\d+)'), 'g'),
function(match, index) {
return array[parseInt(index)];
}
);
}; };
/*@ /*@
@ -476,13 +496,18 @@
'<b>foo</b>' '<b>foo</b>'
> Ox.sanitizeHTML('&&amp;') > Ox.sanitizeHTML('&&amp;')
'&amp;&amp;' '&amp;&amp;'
> Ox.sanitizeHTML('<http://foo.com>')
'&lt;<a href="http://foo.com">http://foo.com</a>&gt;'
@*/ @*/
Ox.sanitizeHTML = function(html, tags) { Ox.sanitizeHTML = function(html, tags) {
var matches = []; var matches = [];
tags = tags || defaultTags; tags = tags || defaultTags;
// html = Ox.clean(html); fixme: can this be a parameter? // html = Ox.clean(html); fixme: can this be a parameter?
if (tags.indexOf('[]') > -1) { if (tags.indexOf('[]') > -1) {
html = html.replace(/\[((\/|https?:\/\/|mailto:).+?) (.+?)\]/gi, '<a href="$1">$3</a>'); html = html.replace(
/\[((\/|https?:\/\/|mailto:).+?) (.+?)\]/gi,
'<a href="$1">$3</a>'
);
tags = tags.filter(function(tag) { tags = tags.filter(function(tag) {
return tag != '[]'; return tag != '[]';
}); });