Skip to content
This repository has been archived by the owner on Sep 5, 2020. It is now read-only.

MD improvements, client side warnings #195

Merged
merged 4 commits into from
Apr 21, 2015
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
223 changes: 118 additions & 105 deletions essentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,123 +2,122 @@ function html(input, replaceQuoteOff) {
if (replaceQuoteOff) return input.toString().replaceAll(['&', '<'], ['&amp;', '&lt;']);
return input.toString().replaceAll(['&', '<', '"'], ['&amp;', '&lt;', '&quot;']);
}
function markdownEscape(input) {
return input.replaceAll(['\\', '`', '*', '_', '-', '+', '.', '#', '>', '(', ')', '^', '$'], ['\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u000e', '\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014']);
function warning(message) {
//console.log(message);
//Ignore markdown warnings on server
}
function spanMarkdown(input) {
input = html(input);
while (input.match(/\^([\w\^]+)/)) input = input.replace(/\^([\w\^]+)/, '<sup>$1</sup>');
return input
.replaceAll('\u0001', '^')
.replace(/\[(.+?)\|(.+?)\]/g, '<abbr title="$2">$1</abbr>')
.replaceAll('\u0002', '[')
.replace(/\[\[(\d+)\](.*?)\]/g, '<sup class="reference" title="$2">[$1]</sup>')
.replace(/!\[([^\]]+)]\((https?:\/\/[^\s("\\]+\.[^\s"\\]+)\)/g, '<img alt="$1" src="$2" />')
.replace(/^(https?:\/\/([^\s("\\]+\.[^\s"\\]+\.(svg|png|tiff|jpg|jpeg)(\?[^\s"\\\/]*)?))/g, '<img src="$1" />')
.replace(/\[([^\]]+)]\((https?:\/\/[^\s("\\]+\.[^\s"\\]+)\)/g, '$1'.link('$2'))
.replace(/([^;["\\])(https?:\/\/([^\s("\\]+\.[^\s"\\]+\.(svg|png|tiff|jpg|jpeg)(\?[^\s"\\\/]*)?))/g, '$1<img src="$2" />')
.replace(/([^;["\\])(https?:\/\/([^\s("\\]+\.[^\s"\\]+))/g, '$1' + '$3'.link('$2'))
.replace(/^(https?:\/\/([^\s("\\]+\.[^\s"\\]+))/g, '$2'.link('$1'));
}
function inlineMarkdown(input) {
var backslash = '\u0001';
input = input.replaceAll('\\\\', backslash);
var graveaccent = '\u0002';
input = input.replaceAll('\\`', graveaccent);
var asterisk = '\u0003';
input = input.replaceAll('\\*', asterisk);
var underscore = '\u0004';
input = input.replaceAll('\\_', underscore);
var dash = '\u0005';
input = input.replaceAll('\\-', dash);
var plus = '\u0006';
input = input.replaceAll('\\+', plus);
var dot = '\u000e';
input = input.replaceAll('\\.', dot);
var hash = '\u000f';
input = input.replaceAll('\\#', hash);
var gt = '\u0010';
input = input.replaceAll('\\>', gt);
var paren = '\u0011';
input = input.replaceAll('\\(', paren);
var cparen = '\u0012';
input = input.replaceAll('\\)', cparen);
var carrot = '\u0013';
input = input.replaceAll('\\^', carrot);
var dollar = '\u0014';
input = input.replaceAll('\\$', dollar);
var open = [];
return input.split('`').map(function(val, i, arr) {
if (i % 2) return '<code>' + html(val.replaceAll([backslash, graveaccent, asterisk, underscore, dash, plus, dot, hash, gt, paren, cparen, carrot, dollar], ['\\\\', '\\`', '\\*', '\\_', '\\-', '\\+', '\\.', '\\#', '\\>', '\\(', '\\)', '\\^'])) + '</code>';
var parsed = val
.replace(/!\[([^\]]+)]\((https?:\/\/[^\s("\\]+\.[^\s"\\]+)\)/g, function(match, p1, p2) {
return '![' + markdownEscape(p1) + '](' + markdownEscape(p2) + ')';
})
.replace(/\[([^\]]+)]\((https?:\/\/[^\s("\\]+\.[^\s"\\]+)\)/g, function(match, p1, p2) {
return '[' + markdownEscape(p1) + '](' + markdownEscape(p2) + ')';
})
.replace(/([^;["\\])(https?:\/\/([^\s("\\]+\.[^\s"\\]+))/g, function(match, p1, p2) {
return markdownEscape(p1) + markdownEscape(p2);
})
.replace(/^(https?:\/\/([^\s("\\]+\.[^\s"\\]+))/g, function(match, p1) {
return markdownEscape(p1);
})
.replaceAll('**', '_')
.split('*').map(function(val, i, arr) {
var parsed = val.split('_').map(function(val, i, arr) {
var parsed = val.split('---').map(function(val, i, arr) {
var parsed = val.split('+++').map(function(val, i, arr) {
var parsed = html(val.replaceAll([backslash, graveaccent, asterisk, underscore, dash, plus, dot, hash, gt], ['\\', '`', '*', '_', '-', '+', '.', '#', '>']), true)
.replace(/!\[([^\]]+)]\((https?:\/\/[^\s("\\]+\.[^\s"\\]+)\)/g, '<img alt="$1" src="$2" />')
.replace(/^(https?:\/\/([^\s("\\]+\.[^\s"\\]+\.(svg|png|tiff|jpg|jpeg)(\?[^\s"\\\/]*)?))/, '<img src="$1" />')
.replace(/\[([^\]]+)]\((https?:\/\/[^\s("\\]+\.[^\s"\\]+)\)/g, '$1'.link('$2'))
.replace(/([^;["\\])(https?:\/\/([^\s("\\]+\.[^\s"\\]+\.(svg|png|tiff|jpg|jpeg)(\?[^\s"\\\/]*)?))/, '$1<img src="$2" />')
.replace(/([^;["\\])(https?:\/\/([^\s("\\]+\.[^\s"\\]+))/g, '$1' + '$3'.link('$2'))
.replace(/^(https?:\/\/([^\s("\\]+\.[^\s"\\]+))/g, '$2'.link('$1'))
.replace(/\^(\w+)/g, '<sup>$1</sup>');
if (i % 2) {
var p = open.indexOf('</ins>');
if (p != -1) {
open.splice(p, 1);
return '</ins>' + parsed;
} else if (arr[i + 1] === undefined) {
open.push('</ins>');
return '<ins>' + parsed;
}
}
return i % 2 ? '<ins>' + parsed + '</ins>' : parsed;
}).join('');
if (i % 2) {
var p = open.indexOf('</del>');
if (p != -1) {
open.splice(p, 1);
return '</del>' + parsed;
} else if (arr[i + 1] === undefined) {
open.push('</del>');
return '<del>' + parsed;
var output = '',
span = '',
current = [],
tags = {
'`': 'code',
'``': 'samp',
'*': 'em',
'**': 'strong',
'_': 'i',
'–––': 's',
'+++': 'ins',
'---': 'del',
'[c]': 'cite',
'[m]': 'mark',
'[u]': 'u',
'[v]': 'var',
'::': 'kbd',
'"': 'q'
},
stags = {
sup: {
start: '^(',
end: ')^'
},
sub: {
start: 'v(',
end: ')v'
},
small: {
start: '[sm]',
end: '[/sm]'
}
};
outer: for (var i = 0; i < input.length; i++) {
if (['code', 'samp'].indexOf(current[current.length - 1]) == -1) {
if (input[i] == '\\') span += input[++i].replace('^', '\u0001').replace('[', '\u0002');
else {
for (var l = 4; l >= 0; l--) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not from 3 to 1?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose 3 to 1 would work.

if (tags[input.substr(i, l)]) {
output += spanMarkdown(span);
span = '';
if (current[current.length - 1] == tags[input.substr(i, l)]) output += '</' + current.pop() + '>';
else {
if (current.indexOf(tags[input.substr(i, l)]) != -1) warning('Illegal nesting of "' + input.substr(i, l) + '"');
output += '<' + tags[input.substr(i, l)] + '>';
current.push(tags[input.substr(i, l)]);
}
}
return i % 2 ? '<del>' + parsed + '</del>' : parsed;
}).join('');
if (i % 2) {
var p = open.indexOf('</strong>');
if (p != -1) {
open.splice(p, 1);
return '</strong>' + parsed;
} else if (arr[i + 1] === undefined) {
open.push('</strong>');
return '<strong>' + parsed;
i += l - 1;
continue outer;
}
}
return i % 2 ? '<strong>' + parsed + '</strong>' : parsed;
}).join('');
if (i % 2) {
var p = open.indexOf('</em>');
if (p != -1) {
open.splice(p, 1);
return '</em>' + parsed;
} else if (arr[i + 1] === undefined) {
open.push('</em>');
return '<em>' + parsed;
for (var j in stags) {
for (var l = 5; l >= 0; l--) {
if (stags[j].start == input.substr(i, l)) {
output += spanMarkdown(span) + '<' + j + '>';
span = '';
current.push(stags[j].end);
i += l - 1;
continue outer;
} else if (stags[j].end == input.substr(i, l)) {
if (current[current.length - 1] == stags[j].end) {
output += spanMarkdown(span) + '</' + j + '>';
span = '';
current.pop();
i += l - 1;
continue outer;
} else {
warning('Illegal close tag "' + stags[j].end + '" found');
}
}
}
}
span += input[i];
}
return i % 2 ? '<em>' + parsed + '</em>' : parsed;
}).join('');
return parsed.replace(/\^\(([^)]+)\)/g, '<sup>$1</sup>').replace(/\$\(([^)]+)\)/g, '<sub>$1</sub>').replaceAll([paren, cparen, carrot, dollar], ['(', ')', '^', '$']);
}).join('') + open.join('');
} else if (current[current.length - 1] == 'code' && input[i] == '`') {
current.pop();
output += '</code>';
} else if (current[current.length - 1] == 'samp' && input.substr(i, 2) == '``') {
current.pop();
output += '</samp>';
i++;
} else output += html(input[i]);
}
output += spanMarkdown(span);
if (current.length) warning('Unclosed tags. <' + current.join('>, <') + '>');
for (var i = current.length - 1; i >= 0; i--) output += '</' + current[i] + '>';
return output;
}
function markdown(input) {
if (input.indexOf('\n') == -1 && input.substr(0, 2) != '> ' && input.substr(0, 2) != '- ' && input.substr(0, 2) != '* ' && input.substr(0, 4) != ' ' && input[0] != '\t' && !input.match(/^((\d+|[A-z])[.)]|#{1,6}) /)) return inlineMarkdown(input);
if (input.indexOf('\n') == -1 && input.substr(0, 2) != '> ' && input.substr(0, 3) != '>! ' && input.substr(0, 2) != '- ' && input.substr(0, 2) != '* ' && input.substr(0, 4) != ' ' && input[0] != '\t' && !input.match(/^((\d+|[A-z])[.)]|#{1,6}|cite\[\d+\]:) /) && !input.match(/^[-–—]{12,}$/)) return inlineMarkdown(input);
var blockquote = '',
ul = '',
ol = '',
li = '',
code = '';
code = '',
i;
return input.split('\n').map(function(val, i, arr) {
if (!val) return '';
var f;
Expand All @@ -132,6 +131,16 @@ function markdown(input) {
blockquote = '';
return '<blockquote>' + markdown(arg) + '</blockquote>';
}
} else if (val.substr(0, 3) == '>! ') {
val = val.substr(3);
if (arr[i + 1] && arr[i + 1].substr(0, 3) == '>! ') {
blockquote += val + '\n';
return '';
} else {
var arg = blockquote + val;
blockquote = '';
return '<blockquote class="spoiler">' + markdown(arg) + '</blockquote>';
}
} else if (val.substr(0, 2) == '- ' || val.substr(0, 2) == '* ') {
if (!ul) ul = '<ul>';
val = val.substr(2);
Expand Down Expand Up @@ -210,13 +219,17 @@ function markdown(input) {
return '';
} else if ((f = val.match(/^#{1,6} /)) && (f = f[0].length - 1)) {
return '<h' + f + '>' + inlineMarkdown(val.substr(f + 1)) + '</h' + f + '>';
} else if (val.match(/^[-–—]{12,}$/)) {
return '<hr />';
} else if (i = val.match(/^cite\[(\d+)\]: /)) {
return '<div><sup class="reference-list">' + i[1] + '</sup> ' + inlineMarkdown(val.substr(i[0].length)) + '</div>';
} else return '<p>' + inlineMarkdown(val) + '</p>';
}).join('');
}

module.exports = {
html: html,
markdownEscape: markdownEscape,
spanMarkdown: spanMarkdown,
inlineMarkdown: inlineMarkdown,
markdown: markdown
};
3 changes: 2 additions & 1 deletion html/chat/room.html
Original file line number Diff line number Diff line change
Expand Up @@ -586,14 +586,15 @@ <h2>Stars:</h2>
ta.addEventListener('keypress', pingsugs);
};
function send() {
if (!ta.value) return;
if (!ta.value || ta.mdValidate(true)) return;
socket.send(JSON.stringify({event: 'post', body: ta.value}));
location.hash = '';
ta.value = '';
cont.scrollTop = cont.scrollHeight;
ta.focus();
}
function edit() {
if (!ta.value || ta.mdValidate(true)) return;
socket.send(JSON.stringify({event: 'edit', body: ta.value, id: parseInt(editing)}));
document.getElementsByClassName('editing')[0].classList.remove('editing');
ta.hists = ta.hists || {};
Expand Down
21 changes: 21 additions & 0 deletions http/a/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,27 @@ code.blk {
hyphens: none;
-webkit-hyphens: none;
}
.md-err {
position: absolute;
display: inline-block;
margin-top: -1.3em;
background: #f00;
color: #fff;
padding: 2px 8px;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5);
animation: fadein 0.5s;
-webkit-animation: fadein 0.5s;
}
@keyframes fadein {
from {
opacity: 0;
}
}
@-webkit-keyframes fadein {
from {
opacity: 0;
}
}
h1 small, h2 small { font-size: .85rem }
h1 small { margin: .5em }
h2 small { margin: .2em .2em 0 0 }
Expand Down