-
Notifications
You must be signed in to change notification settings - Fork 10
/
rich-text-editor.source-markdown.html
99 lines (90 loc) · 3.94 KB
/
rich-text-editor.source-markdown.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Demo</title>
<link href="rich-text-editor.min.css" rel="stylesheet">
</head>
<body>
<h1>Convert HTML Source to Markdown</h1>
<p><textarea>Lorem ipsum **dolor** sit amet.</textarea></p>
<p><button onclick="console.log(editor.get());">Get Value</button></p>
<script src="rich-text-editor.min.js"></script>
<script>
// RMTE: Rich Markdown Text Editor
var RMTE = function(target, config) {
var $ = new RTE(target, config);
// HTML to Markdown
$.HTML_Markdown = function(content) {
function _(s, t, content) {
return content.replace(new RegExp('<' + s + '(?:\\s[^<>]*?)?>([\\s\\S]*?)<\\/' + s + '>', 'g'), function($, a) {
return t + a.replace(/([*_`~])/g, '\\$1') + t;
});
}
content = _('strong', '**', content);
content = _('b', '**', content);
content = _('em', '_', content);
content = _('i', '_', content);
content = _('code', '`', content);
content = _('del', '~~', content); // GFM
content = content.replace(/<a(\s[^<>]*?)?>([\s\S]*?)<\/a>/g, function($, a, b) {
var href = (a.match(/ href="((?:\\"|[^"])*?)"/i) || [])[1],
title = (a.match(/ title="((?:\\"|[^"])*?)"/i) || [])[1] || "";
return '[' + b.replace(/\n/g, ' ') + '](' + href + (title ? ' "' + title + '"' : "") + ')';
});
content = content.replace(/(?:<br(\s[^<>]*?)?\s*\/?>){2,}/g, '\n\n');
content = content.replace(/<br(\s[^<>]*?)?\s*\/?>/g, ' \n'); // hard break
content = content.replace(/<\/p>\s*<p(\s[^<>]*?)?>/g, '\n\n');
content = content.replace(/<\/p>|<p(\s[^<>]*?)?>/g, "");
return content;
};
// Markdown to HTML
$.Markdown_HTML = function(content) {
function _(s, t, content) {
s = s.replace(/./g, '\\$&');
return content.replace(new RegExp(s + '((?:\\\\.|[^' + s[1] + '\\n])*?)' + s, 'g'), function($, a) {
return '<' + t + '>' + a.replace(/\\([*_`~])/g, '$1') + '</' + t + '>';
});
}
content = _('**', 'strong', content);
content = _('_', 'em', content);
content = _('`', 'code', content);
content = _('~~', 'del', content); // GFM
content = content.replace(/\[(.*?)\]\(([^\s]*?)(\s.*?)?\)/g, function($, a, b, c) {
if (c) {
c = c.replace(/^\s+"((?:\\"|[^"])*?)"/, ' title="$1"');
}
return '<a href="' + b + '"' + (c || "") + '>' + a + '</a>';
});
content = content.replace(/<\/p>\s*<p(\s[^<>]*?)?>/g, '\n\n');
content = content.replace(/<\/p>|<p(\s[^<>]*?)?>/g, "");
content = content.replace(/<br(\s[^<>]*?)?\s*\/?>/g, '\n');
content = content.replace(/\n\n\n*/g, '<br><br>'); // create the fake `<p>` tag(s) for editor view
content = content.replace(/ \n/g, '<br>'); // line break
return content;
};
// Re-write the filter function
$.f = $.HTML_Markdown;
// Convert Markdown to HTML
$.view.innerHTML = $.Markdown_HTML($.get("", 0));
$.source.addEventListener("blur", function() {
$.view.innerHTML = $.Markdown_HTML($.get("", 0));
}, false);
$.view.addEventListener("paste", function() {
setTimeout(function() {
var v = $.get("", 0);
$.set("");
$.i($.Markdown_HTML(v));
}, 1);
}, false);
return $;
};
</script>
<script>
var editor = new RMTE(document.querySelector('textarea'), {
tools: ['b', 'i', 'a', 'x']
});
</script>
</body>
</html>