marked 0.3.19 → 0.4.0

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.
package/lib/marked.js CHANGED
@@ -16,20 +16,29 @@ var block = {
16
16
  code: /^( {4}[^\n]+\n*)+/,
17
17
  fences: noop,
18
18
  hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
19
- heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
19
+ heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
20
20
  nptable: noop,
21
21
  blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
22
22
  list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
23
- html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
23
+ html: '^ {0,3}(?:' // optional indentation
24
+ + '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
25
+ + '|comment[^\\n]*(\\n+|$)' // (2)
26
+ + '|<\\?[\\s\\S]*?\\?>\\n*' // (3)
27
+ + '|<![A-Z][\\s\\S]*?>\\n*' // (4)
28
+ + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*' // (5)
29
+ + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)' // (6)
30
+ + '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) open tag
31
+ + '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) closing tag
32
+ + ')',
24
33
  def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
25
34
  table: noop,
26
35
  lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
27
- paragraph: /^([^\n]+(?:\n?(?!hr|heading|lheading| {0,3}>|tag)[^\n]+)+)/,
36
+ paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,
28
37
  text: /^[^\n]+/
29
38
  };
30
39
 
31
- block._label = /(?:\\[\[\]]|[^\[\]])+/;
32
- block._title = /(?:"(?:\\"|[^"]|"[^"\n]*")*"|'\n?(?:[^'\n]+\n?)*'|\([^()]*\))/;
40
+ block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
41
+ block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
33
42
  block.def = edit(block.def)
34
43
  .replace('label', block._label)
35
44
  .replace('title', block._title)
@@ -47,23 +56,24 @@ block.list = edit(block.list)
47
56
  .replace('def', '\\n+(?=' + block.def.source + ')')
48
57
  .getRegex();
49
58
 
50
- block._tag = '(?!(?:'
51
- + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
52
- + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
53
- + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b';
54
-
55
- block.html = edit(block.html)
56
- .replace('comment', /<!--[\s\S]*?-->/)
57
- .replace('closed', /<(tag)[\s\S]+?<\/\1>/)
58
- .replace('closing', /<tag(?:"[^"]*"|'[^']*'|\s[^'"\/>\s]*)*?\/?>/)
59
- .replace(/tag/g, block._tag)
59
+ block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
60
+ + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
61
+ + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
62
+ + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
63
+ + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
64
+ + '|track|ul';
65
+ block._comment = /<!--(?!-?>)[\s\S]*?-->/;
66
+ block.html = edit(block.html, 'i')
67
+ .replace('comment', block._comment)
68
+ .replace('tag', block._tag)
69
+ .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
60
70
  .getRegex();
61
71
 
62
72
  block.paragraph = edit(block.paragraph)
63
73
  .replace('hr', block.hr)
64
74
  .replace('heading', block.heading)
65
75
  .replace('lheading', block.lheading)
66
- .replace('tag', '<' + block._tag)
76
+ .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
67
77
  .getRegex();
68
78
 
69
79
  block.blockquote = edit(block.blockquote)
@@ -97,8 +107,26 @@ block.gfm.paragraph = edit(block.paragraph)
97
107
  */
98
108
 
99
109
  block.tables = merge({}, block.gfm, {
100
- nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
101
- table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
110
+ nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
111
+ table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
112
+ });
113
+
114
+ /**
115
+ * Pedantic grammar
116
+ */
117
+
118
+ block.pedantic = merge({}, block.normal, {
119
+ html: edit(
120
+ '^ *(?:comment *(?:\\n|\\s*$)'
121
+ + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
122
+ + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
123
+ .replace('comment', block._comment)
124
+ .replace(/tag/g, '(?!(?:'
125
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
126
+ + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
127
+ + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
128
+ .getRegex(),
129
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/
102
130
  });
103
131
 
104
132
  /**
@@ -111,7 +139,9 @@ function Lexer(options) {
111
139
  this.options = options || marked.defaults;
112
140
  this.rules = block.normal;
113
141
 
114
- if (this.options.gfm) {
142
+ if (this.options.pedantic) {
143
+ this.rules = block.pedantic;
144
+ } else if (this.options.gfm) {
115
145
  if (this.options.tables) {
116
146
  this.rules = block.tables;
117
147
  } else {
@@ -165,7 +195,9 @@ Lexer.prototype.token = function(src, top) {
165
195
  i,
166
196
  tag,
167
197
  l,
168
- isordered;
198
+ isordered,
199
+ istask,
200
+ ischecked;
169
201
 
170
202
  while (src) {
171
203
  // newline
@@ -215,34 +247,36 @@ Lexer.prototype.token = function(src, top) {
215
247
 
216
248
  // table no leading pipe (gfm)
217
249
  if (top && (cap = this.rules.nptable.exec(src))) {
218
- src = src.substring(cap[0].length);
219
-
220
250
  item = {
221
251
  type: 'table',
222
- header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
252
+ header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
223
253
  align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
224
- cells: cap[3].replace(/\n$/, '').split('\n')
254
+ cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
225
255
  };
226
256
 
227
- for (i = 0; i < item.align.length; i++) {
228
- if (/^ *-+: *$/.test(item.align[i])) {
229
- item.align[i] = 'right';
230
- } else if (/^ *:-+: *$/.test(item.align[i])) {
231
- item.align[i] = 'center';
232
- } else if (/^ *:-+ *$/.test(item.align[i])) {
233
- item.align[i] = 'left';
234
- } else {
235
- item.align[i] = null;
257
+ if (item.header.length === item.align.length) {
258
+ src = src.substring(cap[0].length);
259
+
260
+ for (i = 0; i < item.align.length; i++) {
261
+ if (/^ *-+: *$/.test(item.align[i])) {
262
+ item.align[i] = 'right';
263
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
264
+ item.align[i] = 'center';
265
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
266
+ item.align[i] = 'left';
267
+ } else {
268
+ item.align[i] = null;
269
+ }
236
270
  }
237
- }
238
271
 
239
- for (i = 0; i < item.cells.length; i++) {
240
- item.cells[i] = item.cells[i].split(/ *\| */);
241
- }
272
+ for (i = 0; i < item.cells.length; i++) {
273
+ item.cells[i] = splitCells(item.cells[i], item.header.length);
274
+ }
242
275
 
243
- this.tokens.push(item);
276
+ this.tokens.push(item);
244
277
 
245
- continue;
278
+ continue;
279
+ }
246
280
  }
247
281
 
248
282
  // hr
@@ -331,10 +365,20 @@ Lexer.prototype.token = function(src, top) {
331
365
  if (!loose) loose = next;
332
366
  }
333
367
 
368
+ // Check for task list items
369
+ istask = /^\[[ xX]\] /.test(item);
370
+ ischecked = undefined;
371
+ if (istask) {
372
+ ischecked = item[1] !== ' ';
373
+ item = item.replace(/^\[[ xX]\] +/, '');
374
+ }
375
+
334
376
  this.tokens.push({
335
377
  type: loose
336
378
  ? 'loose_item_start'
337
- : 'list_item_start'
379
+ : 'list_item_start',
380
+ task: istask,
381
+ checked: ischecked
338
382
  });
339
383
 
340
384
  // Recurse.
@@ -370,7 +414,7 @@ Lexer.prototype.token = function(src, top) {
370
414
  if (top && (cap = this.rules.def.exec(src))) {
371
415
  src = src.substring(cap[0].length);
372
416
  if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);
373
- tag = cap[1].toLowerCase();
417
+ tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
374
418
  if (!this.tokens.links[tag]) {
375
419
  this.tokens.links[tag] = {
376
420
  href: cap[2],
@@ -382,36 +426,38 @@ Lexer.prototype.token = function(src, top) {
382
426
 
383
427
  // table (gfm)
384
428
  if (top && (cap = this.rules.table.exec(src))) {
385
- src = src.substring(cap[0].length);
386
-
387
429
  item = {
388
430
  type: 'table',
389
- header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
431
+ header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
390
432
  align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
391
- cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
433
+ cells: cap[3] ? cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') : []
392
434
  };
393
435
 
394
- for (i = 0; i < item.align.length; i++) {
395
- if (/^ *-+: *$/.test(item.align[i])) {
396
- item.align[i] = 'right';
397
- } else if (/^ *:-+: *$/.test(item.align[i])) {
398
- item.align[i] = 'center';
399
- } else if (/^ *:-+ *$/.test(item.align[i])) {
400
- item.align[i] = 'left';
401
- } else {
402
- item.align[i] = null;
436
+ if (item.header.length === item.align.length) {
437
+ src = src.substring(cap[0].length);
438
+
439
+ for (i = 0; i < item.align.length; i++) {
440
+ if (/^ *-+: *$/.test(item.align[i])) {
441
+ item.align[i] = 'right';
442
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
443
+ item.align[i] = 'center';
444
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
445
+ item.align[i] = 'left';
446
+ } else {
447
+ item.align[i] = null;
448
+ }
403
449
  }
404
- }
405
450
 
406
- for (i = 0; i < item.cells.length; i++) {
407
- item.cells[i] = item.cells[i]
408
- .replace(/^ *\| *| *\| *$/g, '')
409
- .split(/ *\| */);
410
- }
451
+ for (i = 0; i < item.cells.length; i++) {
452
+ item.cells[i] = splitCells(
453
+ item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
454
+ item.header.length);
455
+ }
411
456
 
412
- this.tokens.push(item);
457
+ this.tokens.push(item);
413
458
 
414
- continue;
459
+ continue;
460
+ }
415
461
  }
416
462
 
417
463
  // lheading
@@ -461,39 +507,54 @@ Lexer.prototype.token = function(src, top) {
461
507
  */
462
508
 
463
509
  var inline = {
464
- escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
510
+ escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
465
511
  autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
466
512
  url: noop,
467
- tag: /^<!--[\s\S]*?-->|^<\/?[a-zA-Z0-9\-]+(?:"[^"]*"|'[^']*'|\s[^<'">\/\s]*)*?\/?>/,
468
- link: /^!?\[(inside)\]\(href\)/,
469
- reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
470
- nolink: /^!?\[((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\]/,
471
- strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
472
- em: /^_([^\s_](?:[^_]|__)+?[^\s_])_\b|^\*((?:\*\*|[^*])+?)\*(?!\*)/,
513
+ tag: '^comment'
514
+ + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
515
+ + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
516
+ + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
517
+ + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
518
+ + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
519
+ link: /^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,
520
+ reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
521
+ nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
522
+ strong: /^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,
523
+ em: /^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,
473
524
  code: /^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,
474
525
  br: /^ {2,}\n(?!\s*$)/,
475
526
  del: noop,
476
527
  text: /^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/
477
528
  };
478
529
 
530
+ inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
531
+
479
532
  inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
480
533
  inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
481
-
482
534
  inline.autolink = edit(inline.autolink)
483
535
  .replace('scheme', inline._scheme)
484
536
  .replace('email', inline._email)
485
- .getRegex()
537
+ .getRegex();
538
+
539
+ inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
540
+
541
+ inline.tag = edit(inline.tag)
542
+ .replace('comment', block._comment)
543
+ .replace('attribute', inline._attribute)
544
+ .getRegex();
486
545
 
487
- inline._inside = /(?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]]|\](?=[^\[]*\]))*/;
488
- inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
546
+ inline._label = /(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/;
547
+ inline._href = /\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/;
548
+ inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
489
549
 
490
550
  inline.link = edit(inline.link)
491
- .replace('inside', inline._inside)
551
+ .replace('label', inline._label)
492
552
  .replace('href', inline._href)
553
+ .replace('title', inline._title)
493
554
  .getRegex();
494
555
 
495
556
  inline.reflink = edit(inline.reflink)
496
- .replace('inside', inline._inside)
557
+ .replace('label', inline._label)
497
558
  .getRegex();
498
559
 
499
560
  /**
@@ -508,7 +569,13 @@ inline.normal = merge({}, inline);
508
569
 
509
570
  inline.pedantic = merge({}, inline.normal, {
510
571
  strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
511
- em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
572
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
573
+ link: edit(/^!?\[(label)\]\((.*?)\)/)
574
+ .replace('label', inline._label)
575
+ .getRegex(),
576
+ reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
577
+ .replace('label', inline._label)
578
+ .getRegex()
512
579
  });
513
580
 
514
581
  /**
@@ -552,14 +619,14 @@ function InlineLexer(links, options) {
552
619
  throw new Error('Tokens array requires a `links` property.');
553
620
  }
554
621
 
555
- if (this.options.gfm) {
622
+ if (this.options.pedantic) {
623
+ this.rules = inline.pedantic;
624
+ } else if (this.options.gfm) {
556
625
  if (this.options.breaks) {
557
626
  this.rules = inline.breaks;
558
627
  } else {
559
628
  this.rules = inline.gfm;
560
629
  }
561
- } else if (this.options.pedantic) {
562
- this.rules = inline.pedantic;
563
630
  }
564
631
  }
565
632
 
@@ -587,6 +654,7 @@ InlineLexer.prototype.output = function(src) {
587
654
  link,
588
655
  text,
589
656
  href,
657
+ title,
590
658
  cap;
591
659
 
592
660
  while (src) {
@@ -650,9 +718,23 @@ InlineLexer.prototype.output = function(src) {
650
718
  if (cap = this.rules.link.exec(src)) {
651
719
  src = src.substring(cap[0].length);
652
720
  this.inLink = true;
721
+ href = cap[2];
722
+ if (this.options.pedantic) {
723
+ link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
724
+
725
+ if (link) {
726
+ href = link[1];
727
+ title = link[3];
728
+ } else {
729
+ title = '';
730
+ }
731
+ } else {
732
+ title = cap[3] ? cap[3].slice(1, -1) : '';
733
+ }
734
+ href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
653
735
  out += this.outputLink(cap, {
654
- href: cap[2],
655
- title: cap[3]
736
+ href: InlineLexer.escapes(href),
737
+ title: InlineLexer.escapes(title)
656
738
  });
657
739
  this.inLink = false;
658
740
  continue;
@@ -678,14 +760,14 @@ InlineLexer.prototype.output = function(src) {
678
760
  // strong
679
761
  if (cap = this.rules.strong.exec(src)) {
680
762
  src = src.substring(cap[0].length);
681
- out += this.renderer.strong(this.output(cap[2] || cap[1]));
763
+ out += this.renderer.strong(this.output(cap[4] || cap[3] || cap[2] || cap[1]));
682
764
  continue;
683
765
  }
684
766
 
685
767
  // em
686
768
  if (cap = this.rules.em.exec(src)) {
687
769
  src = src.substring(cap[0].length);
688
- out += this.renderer.em(this.output(cap[2] || cap[1]));
770
+ out += this.renderer.em(this.output(cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]));
689
771
  continue;
690
772
  }
691
773
 
@@ -725,12 +807,16 @@ InlineLexer.prototype.output = function(src) {
725
807
  return out;
726
808
  };
727
809
 
810
+ InlineLexer.escapes = function(text) {
811
+ return text ? text.replace(InlineLexer.rules._escapes, '$1') : text;
812
+ }
813
+
728
814
  /**
729
815
  * Compile Link
730
816
  */
731
817
 
732
818
  InlineLexer.prototype.outputLink = function(cap, link) {
733
- var href = escape(link.href),
819
+ var href = link.href,
734
820
  title = link.title ? escape(link.title) : null;
735
821
 
736
822
  return cap[0].charAt(0) !== '!'
@@ -788,7 +874,7 @@ InlineLexer.prototype.mangle = function(text) {
788
874
  */
789
875
 
790
876
  function Renderer(options) {
791
- this.options = options || {};
877
+ this.options = options || marked.defaults;
792
878
  }
793
879
 
794
880
  Renderer.prototype.code = function(code, lang, escaped) {
@@ -803,7 +889,7 @@ Renderer.prototype.code = function(code, lang, escaped) {
803
889
  if (!lang) {
804
890
  return '<pre><code>'
805
891
  + (escaped ? code : escape(code, true))
806
- + '\n</code></pre>';
892
+ + '</code></pre>';
807
893
  }
808
894
 
809
895
  return '<pre><code class="'
@@ -811,7 +897,7 @@ Renderer.prototype.code = function(code, lang, escaped) {
811
897
  + escape(lang, true)
812
898
  + '">'
813
899
  + (escaped ? code : escape(code, true))
814
- + '\n</code></pre>\n';
900
+ + '</code></pre>\n';
815
901
  };
816
902
 
817
903
  Renderer.prototype.blockquote = function(quote) {
@@ -823,16 +909,20 @@ Renderer.prototype.html = function(html) {
823
909
  };
824
910
 
825
911
  Renderer.prototype.heading = function(text, level, raw) {
826
- return '<h'
827
- + level
828
- + ' id="'
829
- + this.options.headerPrefix
830
- + raw.toLowerCase().replace(/[^\w]+/g, '-')
831
- + '">'
832
- + text
833
- + '</h'
834
- + level
835
- + '>\n';
912
+ if (this.options.headerIds) {
913
+ return '<h'
914
+ + level
915
+ + ' id="'
916
+ + this.options.headerPrefix
917
+ + raw.toLowerCase().replace(/[^\w]+/g, '-')
918
+ + '">'
919
+ + text
920
+ + '</h'
921
+ + level
922
+ + '>\n';
923
+ }
924
+ // ignore IDs
925
+ return '<h' + level + '>' + text + '</h' + level + '>\n';
836
926
  };
837
927
 
838
928
  Renderer.prototype.hr = function() {
@@ -849,18 +939,26 @@ Renderer.prototype.listitem = function(text) {
849
939
  return '<li>' + text + '</li>\n';
850
940
  };
851
941
 
942
+ Renderer.prototype.checkbox = function(checked) {
943
+ return '<input '
944
+ + (checked ? 'checked="" ' : '')
945
+ + 'disabled="" type="checkbox"'
946
+ + (this.options.xhtml ? ' /' : '')
947
+ + '> ';
948
+ }
949
+
852
950
  Renderer.prototype.paragraph = function(text) {
853
951
  return '<p>' + text + '</p>\n';
854
952
  };
855
953
 
856
954
  Renderer.prototype.table = function(header, body) {
955
+ if (body) body = '<tbody>' + body + '</tbody>';
956
+
857
957
  return '<table>\n'
858
958
  + '<thead>\n'
859
959
  + header
860
960
  + '</thead>\n'
861
- + '<tbody>\n'
862
961
  + body
863
- + '</tbody>\n'
864
962
  + '</table>\n';
865
963
  };
866
964
 
@@ -871,7 +969,7 @@ Renderer.prototype.tablerow = function(content) {
871
969
  Renderer.prototype.tablecell = function(content, flags) {
872
970
  var type = flags.header ? 'th' : 'td';
873
971
  var tag = flags.align
874
- ? '<' + type + ' style="text-align:' + flags.align + '">'
972
+ ? '<' + type + ' align="' + flags.align + '">'
875
973
  : '<' + type + '>';
876
974
  return tag + content + '</' + type + '>\n';
877
975
  };
@@ -913,7 +1011,12 @@ Renderer.prototype.link = function(href, title, text) {
913
1011
  if (this.options.baseUrl && !originIndependentUrl.test(href)) {
914
1012
  href = resolveUrl(this.options.baseUrl, href);
915
1013
  }
916
- var out = '<a href="' + href + '"';
1014
+ try {
1015
+ href = encodeURI(href).replace(/%25/g, '%');
1016
+ } catch (e) {
1017
+ return text;
1018
+ }
1019
+ var out = '<a href="' + escape(href) + '"';
917
1020
  if (title) {
918
1021
  out += ' title="' + title + '"';
919
1022
  }
@@ -1115,6 +1218,10 @@ Parser.prototype.tok = function() {
1115
1218
  case 'list_item_start': {
1116
1219
  body = '';
1117
1220
 
1221
+ if (this.token.task) {
1222
+ body += this.renderer.checkbox(this.token.checked);
1223
+ }
1224
+
1118
1225
  while (this.next().type !== 'list_item_end') {
1119
1226
  body += this.token.type === 'text'
1120
1227
  ? this.parseText()
@@ -1133,10 +1240,8 @@ Parser.prototype.tok = function() {
1133
1240
  return this.renderer.listitem(body);
1134
1241
  }
1135
1242
  case 'html': {
1136
- var html = !this.token.pre && !this.options.pedantic
1137
- ? this.inline.output(this.token.text)
1138
- : this.token.text;
1139
- return this.renderer.html(html);
1243
+ // TODO parse inline content if parameter markdown=1
1244
+ return this.renderer.html(this.token.text);
1140
1245
  }
1141
1246
  case 'paragraph': {
1142
1247
  return this.renderer.paragraph(this.inline.output(this.token.text));
@@ -1175,7 +1280,7 @@ function unescape(html) {
1175
1280
  }
1176
1281
 
1177
1282
  function edit(regex, opt) {
1178
- regex = regex.source;
1283
+ regex = regex.source || regex;
1179
1284
  opt = opt || '';
1180
1285
  return {
1181
1286
  replace: function(name, val) {
@@ -1234,6 +1339,22 @@ function merge(obj) {
1234
1339
  return obj;
1235
1340
  }
1236
1341
 
1342
+ function splitCells(tableRow, count) {
1343
+ var cells = tableRow.replace(/([^\\])\|/g, '$1 |').split(/ +\| */),
1344
+ i = 0;
1345
+
1346
+ if (cells.length > count) {
1347
+ cells.splice(count);
1348
+ } else {
1349
+ while (cells.length < count) cells.push('');
1350
+ }
1351
+
1352
+ for (; i < cells.length; i++) {
1353
+ cells[i] = cells[i].replace(/\\\|/g, '|');
1354
+ }
1355
+ return cells;
1356
+ }
1357
+
1237
1358
  /**
1238
1359
  * Marked
1239
1360
  */
@@ -1341,24 +1462,29 @@ marked.setOptions = function(opt) {
1341
1462
  return marked;
1342
1463
  };
1343
1464
 
1344
- marked.defaults = {
1345
- gfm: true,
1346
- tables: true,
1347
- breaks: false,
1348
- pedantic: false,
1349
- sanitize: false,
1350
- sanitizer: null,
1351
- mangle: true,
1352
- smartLists: false,
1353
- silent: false,
1354
- highlight: null,
1355
- langPrefix: 'lang-',
1356
- smartypants: false,
1357
- headerPrefix: '',
1358
- renderer: new Renderer(),
1359
- xhtml: false,
1360
- baseUrl: null
1361
- };
1465
+ marked.getDefaults = function () {
1466
+ return {
1467
+ baseUrl: null,
1468
+ breaks: false,
1469
+ gfm: true,
1470
+ headerIds: true,
1471
+ headerPrefix: '',
1472
+ highlight: null,
1473
+ langPrefix: 'language-',
1474
+ mangle: true,
1475
+ pedantic: false,
1476
+ renderer: new Renderer(),
1477
+ sanitize: false,
1478
+ sanitizer: null,
1479
+ silent: false,
1480
+ smartLists: false,
1481
+ smartypants: false,
1482
+ tables: true,
1483
+ xhtml: false
1484
+ };
1485
+ }
1486
+
1487
+ marked.defaults = marked.getDefaults();
1362
1488
 
1363
1489
  /**
1364
1490
  * Expose
package/man/marked.1 CHANGED
@@ -23,7 +23,7 @@ cat in.md | marked > out.html
23
23
  .TP
24
24
  echo "hello *world*" | marked
25
25
  .TP
26
- marked \-o out.html in.md \-\-gfm
26
+ marked \-o out.html \-i in.md \-\-gfm
27
27
  .TP
28
28
  marked \-\-output="hello world.html" \-i in.md \-\-no-breaks
29
29
 
package/man/marked.1.txt CHANGED
@@ -22,7 +22,7 @@ EXAMPLES
22
22
 
23
23
  echo "hello *world*" | marked
24
24
 
25
- marked -o out.html in.md --gfm
25
+ marked -o out.html -i in.md --gfm
26
26
 
27
27
  marked --output="hello world.html" -i in.md --no-breaks
28
28