blogelator 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1251 @@
1
+ /**
2
+ * marked - a markdown parser
3
+ * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
4
+ * https://github.com/chjj/marked
5
+ */
6
+
7
+ ;(function() {
8
+
9
+ /**
10
+ * Block-Level Grammar
11
+ */
12
+
13
+ var block = {
14
+ newline: /^\n+/,
15
+ code: /^( {4}[^\n]+\n*)+/,
16
+ fences: noop,
17
+ hr: /^( *[-*_]){3,} *(?:\n+|$)/,
18
+ heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
19
+ nptable: noop,
20
+ lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
21
+ blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
22
+ list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
23
+ html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
24
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
25
+ table: noop,
26
+ paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
27
+ text: /^[^\n]+/
28
+ };
29
+
30
+ block.bullet = /(?:[*+-]|\d+\.)/;
31
+ block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
32
+ block.item = replace(block.item, 'gm')
33
+ (/bull/g, block.bullet)
34
+ ();
35
+
36
+ block.list = replace(block.list)
37
+ (/bull/g, block.bullet)
38
+ ('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)
39
+ ();
40
+
41
+ block._tag = '(?!(?:'
42
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
43
+ + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
44
+ + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
45
+
46
+ block.html = replace(block.html)
47
+ ('comment', /<!--[\s\S]*?-->/)
48
+ ('closed', /<(tag)[\s\S]+?<\/\1>/)
49
+ ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
50
+ (/tag/g, block._tag)
51
+ ();
52
+
53
+ block.paragraph = replace(block.paragraph)
54
+ ('hr', block.hr)
55
+ ('heading', block.heading)
56
+ ('lheading', block.lheading)
57
+ ('blockquote', block.blockquote)
58
+ ('tag', '<' + block._tag)
59
+ ('def', block.def)
60
+ ();
61
+
62
+ /**
63
+ * Normal Block Grammar
64
+ */
65
+
66
+ block.normal = merge({}, block);
67
+
68
+ /**
69
+ * GFM Block Grammar
70
+ */
71
+
72
+ block.gfm = merge({}, block.normal, {
73
+ fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
74
+ paragraph: /^/
75
+ });
76
+
77
+ block.gfm.paragraph = replace(block.paragraph)
78
+ ('(?!', '(?!'
79
+ + block.gfm.fences.source.replace('\\1', '\\2') + '|'
80
+ + block.list.source.replace('\\1', '\\3') + '|')
81
+ ();
82
+
83
+ /**
84
+ * GFM + Tables Block Grammar
85
+ */
86
+
87
+ block.tables = merge({}, block.gfm, {
88
+ nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
89
+ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
90
+ });
91
+
92
+ /**
93
+ * Block Lexer
94
+ */
95
+
96
+ function Lexer(options) {
97
+ this.tokens = [];
98
+ this.tokens.links = {};
99
+ this.options = options || marked.defaults;
100
+ this.rules = block.normal;
101
+
102
+ if (this.options.gfm) {
103
+ if (this.options.tables) {
104
+ this.rules = block.tables;
105
+ } else {
106
+ this.rules = block.gfm;
107
+ }
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Expose Block Rules
113
+ */
114
+
115
+ Lexer.rules = block;
116
+
117
+ /**
118
+ * Static Lex Method
119
+ */
120
+
121
+ Lexer.lex = function(src, options) {
122
+ var lexer = new Lexer(options);
123
+ return lexer.lex(src);
124
+ };
125
+
126
+ /**
127
+ * Preprocessing
128
+ */
129
+
130
+ Lexer.prototype.lex = function(src) {
131
+ src = src
132
+ .replace(/\r\n|\r/g, '\n')
133
+ .replace(/\t/g, ' ')
134
+ .replace(/\u00a0/g, ' ')
135
+ .replace(/\u2424/g, '\n');
136
+
137
+ return this.token(src, true);
138
+ };
139
+
140
+ /**
141
+ * Lexing
142
+ */
143
+
144
+ Lexer.prototype.token = function(src, top) {
145
+ var src = src.replace(/^ +$/gm, '')
146
+ , next
147
+ , loose
148
+ , cap
149
+ , bull
150
+ , b
151
+ , item
152
+ , space
153
+ , i
154
+ , l;
155
+
156
+ while (src) {
157
+ // newline
158
+ if (cap = this.rules.newline.exec(src)) {
159
+ src = src.substring(cap[0].length);
160
+ if (cap[0].length > 1) {
161
+ this.tokens.push({
162
+ type: 'space'
163
+ });
164
+ }
165
+ }
166
+
167
+ // code
168
+ if (cap = this.rules.code.exec(src)) {
169
+ src = src.substring(cap[0].length);
170
+ cap = cap[0].replace(/^ {4}/gm, '');
171
+ this.tokens.push({
172
+ type: 'code',
173
+ text: !this.options.pedantic
174
+ ? cap.replace(/\n+$/, '')
175
+ : cap
176
+ });
177
+ continue;
178
+ }
179
+
180
+ // fences (gfm)
181
+ if (cap = this.rules.fences.exec(src)) {
182
+ src = src.substring(cap[0].length);
183
+ this.tokens.push({
184
+ type: 'code',
185
+ lang: cap[2],
186
+ text: cap[3]
187
+ });
188
+ continue;
189
+ }
190
+
191
+ // heading
192
+ if (cap = this.rules.heading.exec(src)) {
193
+ src = src.substring(cap[0].length);
194
+ this.tokens.push({
195
+ type: 'heading',
196
+ depth: cap[1].length,
197
+ text: cap[2]
198
+ });
199
+ continue;
200
+ }
201
+
202
+ // table no leading pipe (gfm)
203
+ if (top && (cap = this.rules.nptable.exec(src))) {
204
+ src = src.substring(cap[0].length);
205
+
206
+ item = {
207
+ type: 'table',
208
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
209
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
210
+ cells: cap[3].replace(/\n$/, '').split('\n')
211
+ };
212
+
213
+ for (i = 0; i < item.align.length; i++) {
214
+ if (/^ *-+: *$/.test(item.align[i])) {
215
+ item.align[i] = 'right';
216
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
217
+ item.align[i] = 'center';
218
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
219
+ item.align[i] = 'left';
220
+ } else {
221
+ item.align[i] = null;
222
+ }
223
+ }
224
+
225
+ for (i = 0; i < item.cells.length; i++) {
226
+ item.cells[i] = item.cells[i].split(/ *\| */);
227
+ }
228
+
229
+ this.tokens.push(item);
230
+
231
+ continue;
232
+ }
233
+
234
+ // lheading
235
+ if (cap = this.rules.lheading.exec(src)) {
236
+ src = src.substring(cap[0].length);
237
+ this.tokens.push({
238
+ type: 'heading',
239
+ depth: cap[2] === '=' ? 1 : 2,
240
+ text: cap[1]
241
+ });
242
+ continue;
243
+ }
244
+
245
+ // hr
246
+ if (cap = this.rules.hr.exec(src)) {
247
+ src = src.substring(cap[0].length);
248
+ this.tokens.push({
249
+ type: 'hr'
250
+ });
251
+ continue;
252
+ }
253
+
254
+ // blockquote
255
+ if (cap = this.rules.blockquote.exec(src)) {
256
+ src = src.substring(cap[0].length);
257
+
258
+ this.tokens.push({
259
+ type: 'blockquote_start'
260
+ });
261
+
262
+ cap = cap[0].replace(/^ *> ?/gm, '');
263
+
264
+ // Pass `top` to keep the current
265
+ // "toplevel" state. This is exactly
266
+ // how markdown.pl works.
267
+ this.token(cap, top);
268
+
269
+ this.tokens.push({
270
+ type: 'blockquote_end'
271
+ });
272
+
273
+ continue;
274
+ }
275
+
276
+ // list
277
+ if (cap = this.rules.list.exec(src)) {
278
+ src = src.substring(cap[0].length);
279
+ bull = cap[2];
280
+
281
+ this.tokens.push({
282
+ type: 'list_start',
283
+ ordered: bull.length > 1
284
+ });
285
+
286
+ // Get each top-level item.
287
+ cap = cap[0].match(this.rules.item);
288
+
289
+ next = false;
290
+ l = cap.length;
291
+ i = 0;
292
+
293
+ for (; i < l; i++) {
294
+ item = cap[i];
295
+
296
+ // Remove the list item's bullet
297
+ // so it is seen as the next token.
298
+ space = item.length;
299
+ item = item.replace(/^ *([*+-]|\d+\.) +/, '');
300
+
301
+ // Outdent whatever the
302
+ // list item contains. Hacky.
303
+ if (~item.indexOf('\n ')) {
304
+ space -= item.length;
305
+ item = !this.options.pedantic
306
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
307
+ : item.replace(/^ {1,4}/gm, '');
308
+ }
309
+
310
+ // Determine whether the next list item belongs here.
311
+ // Backpedal if it does not belong in this list.
312
+ if (this.options.smartLists && i !== l - 1) {
313
+ b = block.bullet.exec(cap[i + 1])[0];
314
+ if (bull !== b && !(bull.length > 1 && b.length > 1)) {
315
+ src = cap.slice(i + 1).join('\n') + src;
316
+ i = l - 1;
317
+ }
318
+ }
319
+
320
+ // Determine whether item is loose or not.
321
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
322
+ // for discount behavior.
323
+ loose = next || /\n\n(?!\s*$)/.test(item);
324
+ if (i !== l - 1) {
325
+ next = item.charAt(item.length - 1) === '\n';
326
+ if (!loose) loose = next;
327
+ }
328
+
329
+ this.tokens.push({
330
+ type: loose
331
+ ? 'loose_item_start'
332
+ : 'list_item_start'
333
+ });
334
+
335
+ // Recurse.
336
+ this.token(item, false);
337
+
338
+ this.tokens.push({
339
+ type: 'list_item_end'
340
+ });
341
+ }
342
+
343
+ this.tokens.push({
344
+ type: 'list_end'
345
+ });
346
+
347
+ continue;
348
+ }
349
+
350
+ // html
351
+ if (cap = this.rules.html.exec(src)) {
352
+ src = src.substring(cap[0].length);
353
+ this.tokens.push({
354
+ type: this.options.sanitize
355
+ ? 'paragraph'
356
+ : 'html',
357
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
358
+ text: cap[0]
359
+ });
360
+ continue;
361
+ }
362
+
363
+ // def
364
+ if (top && (cap = this.rules.def.exec(src))) {
365
+ src = src.substring(cap[0].length);
366
+ this.tokens.links[cap[1].toLowerCase()] = {
367
+ href: cap[2],
368
+ title: cap[3]
369
+ };
370
+ continue;
371
+ }
372
+
373
+ // table (gfm)
374
+ if (top && (cap = this.rules.table.exec(src))) {
375
+ src = src.substring(cap[0].length);
376
+
377
+ item = {
378
+ type: 'table',
379
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
380
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
381
+ cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
382
+ };
383
+
384
+ for (i = 0; i < item.align.length; i++) {
385
+ if (/^ *-+: *$/.test(item.align[i])) {
386
+ item.align[i] = 'right';
387
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
388
+ item.align[i] = 'center';
389
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
390
+ item.align[i] = 'left';
391
+ } else {
392
+ item.align[i] = null;
393
+ }
394
+ }
395
+
396
+ for (i = 0; i < item.cells.length; i++) {
397
+ item.cells[i] = item.cells[i]
398
+ .replace(/^ *\| *| *\| *$/g, '')
399
+ .split(/ *\| */);
400
+ }
401
+
402
+ this.tokens.push(item);
403
+
404
+ continue;
405
+ }
406
+
407
+ // top-level paragraph
408
+ if (top && (cap = this.rules.paragraph.exec(src))) {
409
+ src = src.substring(cap[0].length);
410
+ this.tokens.push({
411
+ type: 'paragraph',
412
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
413
+ ? cap[1].slice(0, -1)
414
+ : cap[1]
415
+ });
416
+ continue;
417
+ }
418
+
419
+ // text
420
+ if (cap = this.rules.text.exec(src)) {
421
+ // Top-level should never reach here.
422
+ src = src.substring(cap[0].length);
423
+ this.tokens.push({
424
+ type: 'text',
425
+ text: cap[0]
426
+ });
427
+ continue;
428
+ }
429
+
430
+ if (src) {
431
+ throw new
432
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
433
+ }
434
+ }
435
+
436
+ return this.tokens;
437
+ };
438
+
439
+ /**
440
+ * Inline-Level Grammar
441
+ */
442
+
443
+ var inline = {
444
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
445
+ autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
446
+ url: noop,
447
+ tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
448
+ link: /^!?\[(inside)\]\(href\)/,
449
+ reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
450
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
451
+ strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
452
+ em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
453
+ code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
454
+ br: /^ {2,}\n(?!\s*$)/,
455
+ del: noop,
456
+ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
457
+ };
458
+
459
+ inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
460
+ inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
461
+
462
+ inline.link = replace(inline.link)
463
+ ('inside', inline._inside)
464
+ ('href', inline._href)
465
+ ();
466
+
467
+ inline.reflink = replace(inline.reflink)
468
+ ('inside', inline._inside)
469
+ ();
470
+
471
+ /**
472
+ * Normal Inline Grammar
473
+ */
474
+
475
+ inline.normal = merge({}, inline);
476
+
477
+ /**
478
+ * Pedantic Inline Grammar
479
+ */
480
+
481
+ inline.pedantic = merge({}, inline.normal, {
482
+ strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
483
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
484
+ });
485
+
486
+ /**
487
+ * GFM Inline Grammar
488
+ */
489
+
490
+ inline.gfm = merge({}, inline.normal, {
491
+ escape: replace(inline.escape)('])', '~|])')(),
492
+ url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
493
+ del: /^~~(?=\S)([\s\S]*?\S)~~/,
494
+ text: replace(inline.text)
495
+ (']|', '~]|')
496
+ ('|', '|https?://|')
497
+ ()
498
+ });
499
+
500
+ /**
501
+ * GFM + Line Breaks Inline Grammar
502
+ */
503
+
504
+ inline.breaks = merge({}, inline.gfm, {
505
+ br: replace(inline.br)('{2,}', '*')(),
506
+ text: replace(inline.gfm.text)('{2,}', '*')()
507
+ });
508
+
509
+ /**
510
+ * Inline Lexer & Compiler
511
+ */
512
+
513
+ function InlineLexer(links, options) {
514
+ this.options = options || marked.defaults;
515
+ this.links = links;
516
+ this.rules = inline.normal;
517
+ this.renderer = this.options.renderer || new Renderer;
518
+ this.renderer.options = this.options;
519
+
520
+ if (!this.links) {
521
+ throw new
522
+ Error('Tokens array requires a `links` property.');
523
+ }
524
+
525
+ if (this.options.gfm) {
526
+ if (this.options.breaks) {
527
+ this.rules = inline.breaks;
528
+ } else {
529
+ this.rules = inline.gfm;
530
+ }
531
+ } else if (this.options.pedantic) {
532
+ this.rules = inline.pedantic;
533
+ }
534
+ }
535
+
536
+ /**
537
+ * Expose Inline Rules
538
+ */
539
+
540
+ InlineLexer.rules = inline;
541
+
542
+ /**
543
+ * Static Lexing/Compiling Method
544
+ */
545
+
546
+ InlineLexer.output = function(src, links, options) {
547
+ var inline = new InlineLexer(links, options);
548
+ return inline.output(src);
549
+ };
550
+
551
+ /**
552
+ * Lexing/Compiling
553
+ */
554
+
555
+ InlineLexer.prototype.output = function(src) {
556
+ var out = ''
557
+ , link
558
+ , text
559
+ , href
560
+ , cap;
561
+
562
+ while (src) {
563
+ // escape
564
+ if (cap = this.rules.escape.exec(src)) {
565
+ src = src.substring(cap[0].length);
566
+ out += cap[1];
567
+ continue;
568
+ }
569
+
570
+ // autolink
571
+ if (cap = this.rules.autolink.exec(src)) {
572
+ src = src.substring(cap[0].length);
573
+ if (cap[2] === '@') {
574
+ text = cap[1].charAt(6) === ':'
575
+ ? this.mangle(cap[1].substring(7))
576
+ : this.mangle(cap[1]);
577
+ href = this.mangle('mailto:') + text;
578
+ } else {
579
+ text = escape(cap[1]);
580
+ href = text;
581
+ }
582
+ out += this.renderer.link(href, null, text);
583
+ continue;
584
+ }
585
+
586
+ // url (gfm)
587
+ if (cap = this.rules.url.exec(src)) {
588
+ src = src.substring(cap[0].length);
589
+ text = escape(cap[1]);
590
+ href = text;
591
+ out += this.renderer.link(href, null, text);
592
+ continue;
593
+ }
594
+
595
+ // tag
596
+ if (cap = this.rules.tag.exec(src)) {
597
+ src = src.substring(cap[0].length);
598
+ out += this.options.sanitize
599
+ ? escape(cap[0])
600
+ : cap[0];
601
+ continue;
602
+ }
603
+
604
+ // link
605
+ if (cap = this.rules.link.exec(src)) {
606
+ src = src.substring(cap[0].length);
607
+ out += this.outputLink(cap, {
608
+ href: cap[2],
609
+ title: cap[3]
610
+ });
611
+ continue;
612
+ }
613
+
614
+ // reflink, nolink
615
+ if ((cap = this.rules.reflink.exec(src))
616
+ || (cap = this.rules.nolink.exec(src))) {
617
+ src = src.substring(cap[0].length);
618
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
619
+ link = this.links[link.toLowerCase()];
620
+ if (!link || !link.href) {
621
+ out += cap[0].charAt(0);
622
+ src = cap[0].substring(1) + src;
623
+ continue;
624
+ }
625
+ out += this.outputLink(cap, link);
626
+ continue;
627
+ }
628
+
629
+ // strong
630
+ if (cap = this.rules.strong.exec(src)) {
631
+ src = src.substring(cap[0].length);
632
+ out += this.renderer.strong(this.output(cap[2] || cap[1]));
633
+ continue;
634
+ }
635
+
636
+ // em
637
+ if (cap = this.rules.em.exec(src)) {
638
+ src = src.substring(cap[0].length);
639
+ out += this.renderer.em(this.output(cap[2] || cap[1]));
640
+ continue;
641
+ }
642
+
643
+ // code
644
+ if (cap = this.rules.code.exec(src)) {
645
+ src = src.substring(cap[0].length);
646
+ out += this.renderer.codespan(escape(cap[2], true));
647
+ continue;
648
+ }
649
+
650
+ // br
651
+ if (cap = this.rules.br.exec(src)) {
652
+ src = src.substring(cap[0].length);
653
+ out += this.renderer.br();
654
+ continue;
655
+ }
656
+
657
+ // del (gfm)
658
+ if (cap = this.rules.del.exec(src)) {
659
+ src = src.substring(cap[0].length);
660
+ out += this.renderer.del(this.output(cap[1]));
661
+ continue;
662
+ }
663
+
664
+ // text
665
+ if (cap = this.rules.text.exec(src)) {
666
+ src = src.substring(cap[0].length);
667
+ out += escape(this.smartypants(cap[0]));
668
+ continue;
669
+ }
670
+
671
+ if (src) {
672
+ throw new
673
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
674
+ }
675
+ }
676
+
677
+ return out;
678
+ };
679
+
680
+ /**
681
+ * Compile Link
682
+ */
683
+
684
+ InlineLexer.prototype.outputLink = function(cap, link) {
685
+ var href = escape(link.href)
686
+ , title = link.title ? escape(link.title) : null;
687
+
688
+ return cap[0].charAt(0) !== '!'
689
+ ? this.renderer.link(href, title, this.output(cap[1]))
690
+ : this.renderer.image(href, title, escape(cap[1]));
691
+ };
692
+
693
+ /**
694
+ * Smartypants Transformations
695
+ */
696
+
697
+ InlineLexer.prototype.smartypants = function(text) {
698
+ if (!this.options.smartypants) return text;
699
+ return text
700
+ // em-dashes
701
+ .replace(/--/g, '\u2014')
702
+ // opening singles
703
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
704
+ // closing singles & apostrophes
705
+ .replace(/'/g, '\u2019')
706
+ // opening doubles
707
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
708
+ // closing doubles
709
+ .replace(/"/g, '\u201d')
710
+ // ellipses
711
+ .replace(/\.{3}/g, '\u2026');
712
+ };
713
+
714
+ /**
715
+ * Mangle Links
716
+ */
717
+
718
+ InlineLexer.prototype.mangle = function(text) {
719
+ var out = ''
720
+ , l = text.length
721
+ , i = 0
722
+ , ch;
723
+
724
+ for (; i < l; i++) {
725
+ ch = text.charCodeAt(i);
726
+ if (Math.random() > 0.5) {
727
+ ch = 'x' + ch.toString(16);
728
+ }
729
+ out += '&#' + ch + ';';
730
+ }
731
+
732
+ return out;
733
+ };
734
+
735
+ /**
736
+ * Renderer
737
+ */
738
+
739
+ function Renderer(options) {
740
+ this.options = options || {};
741
+ }
742
+
743
+ Renderer.prototype.code = function(code, lang, escaped) {
744
+ if (this.options.highlight) {
745
+ var out = this.options.highlight(code, lang);
746
+ if (out != null && out !== code) {
747
+ escaped = true;
748
+ code = out;
749
+ }
750
+ }
751
+
752
+ if (!lang) {
753
+ return '<pre><code>'
754
+ + (escaped ? code : escape(code, true))
755
+ + '\n</code></pre>';
756
+ }
757
+
758
+ return '<pre><code class="'
759
+ + this.options.langPrefix
760
+ + escape(lang, true)
761
+ + '">'
762
+ + (escaped ? code : escape(code, true))
763
+ + '\n</code></pre>\n';
764
+ };
765
+
766
+ Renderer.prototype.blockquote = function(quote) {
767
+ return '<blockquote>\n' + quote + '</blockquote>\n';
768
+ };
769
+
770
+ Renderer.prototype.html = function(html) {
771
+ return html;
772
+ };
773
+
774
+ Renderer.prototype.heading = function(text, level, raw) {
775
+ return '<h'
776
+ + level
777
+ + ' id="'
778
+ + this.options.headerPrefix
779
+ + raw.toLowerCase().replace(/[^\w]+/g, '-')
780
+ + '">'
781
+ + text
782
+ + '</h'
783
+ + level
784
+ + '>\n';
785
+ };
786
+
787
+ Renderer.prototype.hr = function() {
788
+ return '<hr>\n';
789
+ };
790
+
791
+ Renderer.prototype.list = function(body, ordered) {
792
+ var type = ordered ? 'ol' : 'ul';
793
+ return '<' + type + '>\n' + body + '</' + type + '>\n';
794
+ };
795
+
796
+ Renderer.prototype.listitem = function(text) {
797
+ return '<li>' + text + '</li>\n';
798
+ };
799
+
800
+ Renderer.prototype.paragraph = function(text) {
801
+ return '<p>' + text + '</p>\n';
802
+ };
803
+
804
+ Renderer.prototype.table = function(header, body) {
805
+ return '<table>\n'
806
+ + '<thead>\n'
807
+ + header
808
+ + '</thead>\n'
809
+ + '<tbody>\n'
810
+ + body
811
+ + '</tbody>\n'
812
+ + '</table>\n';
813
+ };
814
+
815
+ Renderer.prototype.tablerow = function(content) {
816
+ return '<tr>\n' + content + '</tr>\n';
817
+ };
818
+
819
+ Renderer.prototype.tablecell = function(content, flags) {
820
+ var type = flags.header ? 'th' : 'td';
821
+ var tag = flags.align
822
+ ? '<' + type + ' style="text-align:' + flags.align + '">'
823
+ : '<' + type + '>';
824
+ return tag + content + '</' + type + '>\n';
825
+ };
826
+
827
+ // span level renderer
828
+ Renderer.prototype.strong = function(text) {
829
+ return '<strong>' + text + '</strong>';
830
+ };
831
+
832
+ Renderer.prototype.em = function(text) {
833
+ return '<em>' + text + '</em>';
834
+ };
835
+
836
+ Renderer.prototype.codespan = function(text) {
837
+ return '<code>' + text + '</code>';
838
+ };
839
+
840
+ Renderer.prototype.br = function() {
841
+ return '<br>';
842
+ };
843
+
844
+ Renderer.prototype.del = function(text) {
845
+ return '<del>' + text + '</del>';
846
+ };
847
+
848
+ Renderer.prototype.link = function(href, title, text) {
849
+ if (this.options.sanitize) {
850
+ try {
851
+ var prot = decodeURIComponent(unescape(href))
852
+ .replace(/[^\w:]/g, '')
853
+ .toLowerCase();
854
+ } catch (e) {
855
+ return '';
856
+ }
857
+ if (prot.indexOf('javascript:') === 0) {
858
+ return '';
859
+ }
860
+ }
861
+ var out = '<a href="' + href + '"';
862
+ if (title) {
863
+ out += ' title="' + title + '"';
864
+ }
865
+ out += '>' + text + '</a>';
866
+ return out;
867
+ };
868
+
869
+ Renderer.prototype.image = function(href, title, text) {
870
+ var out = '<img src="' + href + '" alt="' + text + '"';
871
+ if (title) {
872
+ out += ' title="' + title + '"';
873
+ }
874
+ out += '>';
875
+ return out;
876
+ };
877
+
878
+ /**
879
+ * Parsing & Compiling
880
+ */
881
+
882
+ function Parser(options) {
883
+ this.tokens = [];
884
+ this.token = null;
885
+ this.options = options || marked.defaults;
886
+ this.options.renderer = this.options.renderer || new Renderer;
887
+ this.renderer = this.options.renderer;
888
+ this.renderer.options = this.options;
889
+ }
890
+
891
+ /**
892
+ * Static Parse Method
893
+ */
894
+
895
+ Parser.parse = function(src, options, renderer) {
896
+ var parser = new Parser(options, renderer);
897
+ return parser.parse(src);
898
+ };
899
+
900
+ /**
901
+ * Parse Loop
902
+ */
903
+
904
+ Parser.prototype.parse = function(src) {
905
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
906
+ this.tokens = src.reverse();
907
+
908
+ var out = '';
909
+ while (this.next()) {
910
+ out += this.tok();
911
+ }
912
+
913
+ return out;
914
+ };
915
+
916
+ /**
917
+ * Next Token
918
+ */
919
+
920
+ Parser.prototype.next = function() {
921
+ return this.token = this.tokens.pop();
922
+ };
923
+
924
+ /**
925
+ * Preview Next Token
926
+ */
927
+
928
+ Parser.prototype.peek = function() {
929
+ return this.tokens[this.tokens.length - 1] || 0;
930
+ };
931
+
932
+ /**
933
+ * Parse Text Tokens
934
+ */
935
+
936
+ Parser.prototype.parseText = function() {
937
+ var body = this.token.text;
938
+
939
+ while (this.peek().type === 'text') {
940
+ body += '\n' + this.next().text;
941
+ }
942
+
943
+ return this.inline.output(body);
944
+ };
945
+
946
+ /**
947
+ * Parse Current Token
948
+ */
949
+
950
+ Parser.prototype.tok = function() {
951
+ switch (this.token.type) {
952
+ case 'space': {
953
+ return '';
954
+ }
955
+ case 'hr': {
956
+ return this.renderer.hr();
957
+ }
958
+ case 'heading': {
959
+ return this.renderer.heading(
960
+ this.inline.output(this.token.text),
961
+ this.token.depth,
962
+ this.token.text);
963
+ }
964
+ case 'code': {
965
+ return this.renderer.code(this.token.text,
966
+ this.token.lang,
967
+ this.token.escaped);
968
+ }
969
+ case 'table': {
970
+ var header = ''
971
+ , body = ''
972
+ , i
973
+ , row
974
+ , cell
975
+ , flags
976
+ , j;
977
+
978
+ // header
979
+ cell = '';
980
+ for (i = 0; i < this.token.header.length; i++) {
981
+ flags = { header: true, align: this.token.align[i] };
982
+ cell += this.renderer.tablecell(
983
+ this.inline.output(this.token.header[i]),
984
+ { header: true, align: this.token.align[i] }
985
+ );
986
+ }
987
+ header += this.renderer.tablerow(cell);
988
+
989
+ for (i = 0; i < this.token.cells.length; i++) {
990
+ row = this.token.cells[i];
991
+
992
+ cell = '';
993
+ for (j = 0; j < row.length; j++) {
994
+ cell += this.renderer.tablecell(
995
+ this.inline.output(row[j]),
996
+ { header: false, align: this.token.align[j] }
997
+ );
998
+ }
999
+
1000
+ body += this.renderer.tablerow(cell);
1001
+ }
1002
+ return this.renderer.table(header, body);
1003
+ }
1004
+ case 'blockquote_start': {
1005
+ var body = '';
1006
+
1007
+ while (this.next().type !== 'blockquote_end') {
1008
+ body += this.tok();
1009
+ }
1010
+
1011
+ return this.renderer.blockquote(body);
1012
+ }
1013
+ case 'list_start': {
1014
+ var body = ''
1015
+ , ordered = this.token.ordered;
1016
+
1017
+ while (this.next().type !== 'list_end') {
1018
+ body += this.tok();
1019
+ }
1020
+
1021
+ return this.renderer.list(body, ordered);
1022
+ }
1023
+ case 'list_item_start': {
1024
+ var body = '';
1025
+
1026
+ while (this.next().type !== 'list_item_end') {
1027
+ body += this.token.type === 'text'
1028
+ ? this.parseText()
1029
+ : this.tok();
1030
+ }
1031
+
1032
+ return this.renderer.listitem(body);
1033
+ }
1034
+ case 'loose_item_start': {
1035
+ var body = '';
1036
+
1037
+ while (this.next().type !== 'list_item_end') {
1038
+ body += this.tok();
1039
+ }
1040
+
1041
+ return this.renderer.listitem(body);
1042
+ }
1043
+ case 'html': {
1044
+ var html = !this.token.pre && !this.options.pedantic
1045
+ ? this.inline.output(this.token.text)
1046
+ : this.token.text;
1047
+ return this.renderer.html(html);
1048
+ }
1049
+ case 'paragraph': {
1050
+ return this.renderer.paragraph(this.inline.output(this.token.text));
1051
+ }
1052
+ case 'text': {
1053
+ return this.renderer.paragraph(this.parseText());
1054
+ }
1055
+ }
1056
+ };
1057
+
1058
+ /**
1059
+ * Helpers
1060
+ */
1061
+
1062
+ function escape(html, encode) {
1063
+ return html
1064
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
1065
+ .replace(/</g, '&lt;')
1066
+ .replace(/>/g, '&gt;')
1067
+ .replace(/"/g, '&quot;')
1068
+ .replace(/'/g, '&#39;');
1069
+ }
1070
+
1071
+ function unescape(html) {
1072
+ return html.replace(/&([#\w]+);/g, function(_, n) {
1073
+ n = n.toLowerCase();
1074
+ if (n === 'colon') return ':';
1075
+ if (n.charAt(0) === '#') {
1076
+ return n.charAt(1) === 'x'
1077
+ ? String.fromCharCode(parseInt(n.substring(2), 16))
1078
+ : String.fromCharCode(+n.substring(1));
1079
+ }
1080
+ return '';
1081
+ });
1082
+ }
1083
+
1084
+ function replace(regex, opt) {
1085
+ regex = regex.source;
1086
+ opt = opt || '';
1087
+ return function self(name, val) {
1088
+ if (!name) return new RegExp(regex, opt);
1089
+ val = val.source || val;
1090
+ val = val.replace(/(^|[^\[])\^/g, '$1');
1091
+ regex = regex.replace(name, val);
1092
+ return self;
1093
+ };
1094
+ }
1095
+
1096
+ function noop() {}
1097
+ noop.exec = noop;
1098
+
1099
+ function merge(obj) {
1100
+ var i = 1
1101
+ , target
1102
+ , key;
1103
+
1104
+ for (; i < arguments.length; i++) {
1105
+ target = arguments[i];
1106
+ for (key in target) {
1107
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
1108
+ obj[key] = target[key];
1109
+ }
1110
+ }
1111
+ }
1112
+
1113
+ return obj;
1114
+ }
1115
+
1116
+
1117
+ /**
1118
+ * Marked
1119
+ */
1120
+
1121
+ function marked(src, opt, callback) {
1122
+ if (callback || typeof opt === 'function') {
1123
+ if (!callback) {
1124
+ callback = opt;
1125
+ opt = null;
1126
+ }
1127
+
1128
+ opt = merge({}, marked.defaults, opt || {});
1129
+
1130
+ var highlight = opt.highlight
1131
+ , tokens
1132
+ , pending
1133
+ , i = 0;
1134
+
1135
+ try {
1136
+ tokens = Lexer.lex(src, opt)
1137
+ } catch (e) {
1138
+ return callback(e);
1139
+ }
1140
+
1141
+ pending = tokens.length;
1142
+
1143
+ var done = function() {
1144
+ var out, err;
1145
+
1146
+ try {
1147
+ out = Parser.parse(tokens, opt);
1148
+ } catch (e) {
1149
+ err = e;
1150
+ }
1151
+
1152
+ opt.highlight = highlight;
1153
+
1154
+ return err
1155
+ ? callback(err)
1156
+ : callback(null, out);
1157
+ };
1158
+
1159
+ if (!highlight || highlight.length < 3) {
1160
+ return done();
1161
+ }
1162
+
1163
+ delete opt.highlight;
1164
+
1165
+ if (!pending) return done();
1166
+
1167
+ for (; i < tokens.length; i++) {
1168
+ (function(token) {
1169
+ if (token.type !== 'code') {
1170
+ return --pending || done();
1171
+ }
1172
+ return highlight(token.text, token.lang, function(err, code) {
1173
+ if (code == null || code === token.text) {
1174
+ return --pending || done();
1175
+ }
1176
+ token.text = code;
1177
+ token.escaped = true;
1178
+ --pending || done();
1179
+ });
1180
+ })(tokens[i]);
1181
+ }
1182
+
1183
+ return;
1184
+ }
1185
+ try {
1186
+ if (opt) opt = merge({}, marked.defaults, opt);
1187
+ return Parser.parse(Lexer.lex(src, opt), opt);
1188
+ } catch (e) {
1189
+ e.message += '\nPlease report this to https://github.com/chjj/marked.';
1190
+ if ((opt || marked.defaults).silent) {
1191
+ return '<p>An error occured:</p><pre>'
1192
+ + escape(e.message + '', true)
1193
+ + '</pre>';
1194
+ }
1195
+ throw e;
1196
+ }
1197
+ }
1198
+
1199
+ /**
1200
+ * Options
1201
+ */
1202
+
1203
+ marked.options =
1204
+ marked.setOptions = function(opt) {
1205
+ merge(marked.defaults, opt);
1206
+ return marked;
1207
+ };
1208
+
1209
+ marked.defaults = {
1210
+ gfm: true,
1211
+ tables: true,
1212
+ breaks: false,
1213
+ pedantic: false,
1214
+ sanitize: false,
1215
+ smartLists: false,
1216
+ silent: false,
1217
+ highlight: null,
1218
+ langPrefix: 'lang-',
1219
+ smartypants: false,
1220
+ headerPrefix: '',
1221
+ renderer: new Renderer
1222
+ };
1223
+
1224
+ /**
1225
+ * Expose
1226
+ */
1227
+
1228
+ marked.Parser = Parser;
1229
+ marked.parser = Parser.parse;
1230
+
1231
+ marked.Renderer = Renderer;
1232
+
1233
+ marked.Lexer = Lexer;
1234
+ marked.lexer = Lexer.lex;
1235
+
1236
+ marked.InlineLexer = InlineLexer;
1237
+ marked.inlineLexer = InlineLexer.output;
1238
+
1239
+ marked.parse = marked;
1240
+
1241
+ if (typeof exports === 'object') {
1242
+ module.exports = marked;
1243
+ } else if (typeof define === 'function' && define.amd) {
1244
+ define(function() { return marked; });
1245
+ } else {
1246
+ this.marked = marked;
1247
+ }
1248
+
1249
+ }).call(function() {
1250
+ return this || (typeof window !== 'undefined' ? window : global);
1251
+ }());