-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
237 lines (213 loc) · 5.84 KB
/
app.js
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// test
console.log("follow the deusmur 🐰")
// in this project, everything will be in the same file.
const textAreaInput = { value: "lorem ipsum" }
window.onload = () => {
// 1) init example markdown text
// 2) if user uses docwiz at the second time, load saved user data from local storage
init();
}
function init() {
textInput();
setInitialValues();
watch({id: "☯"})
}
function setInitialValues(){
setValueToInput({ inputId: "text-input", value: textAreaInput.value });
setValueToInput({ inputId: "html-output", value: textAreaInput.value });
}
function textInput() {
inputOnChange({inputId: "text-input", eventType: "input", selector: "byId" });
}
// first of all we need onchange event for textarea
function inputOnChange(args) {
const input = document.getElementById(args.inputId);
input.addEventListener(args.eventType, function (e) {
textAreaInput.value = e.target.value;
setValueToInput({ inputId: "☯", value: textAreaInput.value });
});
}
function setValueToInput(args) {
const input = document.getElementById(args.inputId);
input.innerHTML= args.value;
}
function watch(args) {
var element = document.getElementById(args.id);
element.addEventListener('DOMSubtreeModified', function () {
element = document.getElementById(args.id);
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function() {
console.log(`value changed to ${element.innerHTML}`)
// set new value to display
setValueToInput({ inputId: "html-output", value: parse(element.innerHTML) });
});
observer.observe(element, {childList: true});
});
}
// parser map starts
var
/**
* The parsed output string, in HTML format.
* @type {String}
*/
output = "",
BLOCK = "block",
INLINE = "inline",
/**
* Used to attach MarkdownToHtml object to `window` in browser
* context, or as an AMD module where appropriate.
* @type {Object}
*/
exports,
/**
* An array of parse rule descriptor objects. Each object has two keys;
* pattern (the RegExp to match), and replace (the replacement string or
* function to execute).
* @type {Array}
*/
parseMap = [
{
// <h1>
// A line starting with 1-6 hashes.
pattern: /(#{1,6})([^\n]+)/g,
replace: "<h$L1>$2</h$L1>",
type: BLOCK,
},
{
// <p>
// Any line surrounded by newlines that doesn't start with
// an HTML tag, asterisk or numeric value with dot following.
pattern: /\n(?!<\/?\w+>|\s?\*|\s?[0-9]+|>|\>|-{5,})([^\n]+)/g,
replace: "<p>$1</p>",
type: BLOCK,
},
{
// <blockquote>
// A greater-than character preceding any characters.
pattern: /\n(?:>|\>)\W*(.*)/g,
replace: "<blockquote><p>$1</p></blockquote>",
type: BLOCK,
},
{
// <ul>
//
pattern: /\n\s?\*\s*(.*)/g,
replace: "<ul>\n\t<li>$1</li>\n</ul>",
type: BLOCK,
},
{
// <ol>
//
pattern: /\n\s?[0-9]+\.\s*(.*)/g,
replace: "<ol>\n\t<li>$1</li>\n</ol>",
type: BLOCK,
},
{
// <strong>
// Either two asterisks or two underscores, followed by any
// characters, followed by the same two starting characters.
pattern: /(\*\*|__)(.*?)\1/g,
replace: "<strong>$2</strong>",
type: INLINE,
},
{
// <em>
// Either one asterisk or one underscore, followed by any
// characters, followed by the starting character.
pattern: /(\*|_)(.*?)\1/g,
replace: "<em>$2</em>",
type: INLINE,
},
{
// <a>
// Not starting with an exclamation mark, square brackets
// surrounding any characters, followed by parenthesis surrounding
// any characters.
pattern: /([^!])\[([^\[]+)\]\(([^\)]+)\)/g,
replace: "$1<a href=\"$3\">$2</a>",
type: INLINE,
},
{
// <img>
// Starting with an exclamation mark, then followed by square
// brackets surrounding any characters, followed by parenthesis
// surrounding any characters.
pattern: /!\[([^\[]+)\]\(([^\)]+)\)/g,
replace: "<img src=\"$2\" alt=\"$1\" />",
type: INLINE,
},
{
// <del>
// Double tilde characters surrounding any characters.
pattern: /\~\~(.*?)\~\~/g,
replace: "<del>$1</del>",
type: INLINE,
},
{
// <code>
//
pattern: /`(.*?)`/g,
replace: "<code>$1</code>",
type: INLINE,
},
{
// <hr>
//
pattern: /\n-{5,}\n/g,
replace: "<hr />",
type: BLOCK,
},
];
function parse(string) {
// Pad with newlines for compatibility.
output = "\n" + string + "\n";
parseMap.forEach(function(p) {
// Replace all matches of provided RegExp pattern with either the
// replacement string or callback function.
output = output.replace(p.pattern, function() {
// // console.log(this, arguments);
return replace.call(this, arguments, p.replace, p.type);
});
});
// Perform any post-processing required.
output = clean(output);
// Trim for any spaces or newlines.
output = output.trim();
// Tidy up newlines to condense where more than 1 occurs back to back.
output = output.replace(/[\n]{1,}/g, "\n");
return output;
}
function replace(matchList, replacement, type) {
var
i,
$$;
for(i in matchList) {
if(!matchList.hasOwnProperty(i)) {
continue;
}
// Replace $n with the matching regexp group.
replacement = replacement.split("$" + i).join(matchList[i]);
// Replace $Ln with the matching regexp group's string length.
replacement = replacement.split("$L" + i).join(matchList[i].length);
}
if(type === BLOCK) {
replacement = replacement.trim() + "\n";
}
return replacement;
}
function clean(string) {
var cleaningRuleArray = [
{
match: /<\/([uo]l)>\s*<\1>/g,
replacement: "",
},
{
match: /(<\/\w+>)<\/(blockquote)>\s*<\2>/g,
replacement: "$1",
},
];
cleaningRuleArray.forEach(function(rule) {
string = string.replace(rule.match, rule.replacement);
});
return string;
}