| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of markdown; | 5 part of markdown; |
| 6 | 6 |
| 7 /// The line contains only whitespace or is empty. | 7 /// The line contains only whitespace or is empty. |
| 8 final _RE_EMPTY = new RegExp(r'^([ \t]*)$'); | 8 final _RE_EMPTY = new RegExp(r'^([ \t]*)$'); |
| 9 | 9 |
| 10 /// A series of `=` or `-` (on the next line) define setext-style headers. | 10 /// A series of `=` or `-` (on the next line) define setext-style headers. |
| 11 final _RE_SETEXT = new RegExp(r'^((=+)|(-+))$'); | 11 final _RE_SETEXT = new RegExp(r'^((=+)|(-+))$'); |
| 12 | 12 |
| 13 /// Leading (and trailing) `#` define atx-style headers. | 13 /// Leading (and trailing) `#` define atx-style headers. |
| 14 final _RE_HEADER = new RegExp(r'^(#{1,6})(.*?)#*$'); | 14 final _RE_HEADER = new RegExp(r'^(#{1,6})(.*?)#*$'); |
| 15 | 15 |
| 16 /// The line starts with `>` with one optional space after. | 16 /// The line starts with `>` with one optional space after. |
| 17 final _RE_BLOCKQUOTE = new RegExp(r'^[ ]{0,3}>[ ]?(.*)$'); | 17 final _RE_BLOCKQUOTE = new RegExp(r'^[ ]{0,3}>[ ]?(.*)$'); |
| 18 | 18 |
| 19 /// A line indented four spaces. Used for code blocks and lists. | 19 /// A line indented four spaces. Used for code blocks and lists. |
| 20 final _RE_INDENT = new RegExp(r'^(?: |\t)(.*)$'); | 20 final _RE_INDENT = new RegExp(r'^(?: |\t)(.*)$'); |
| 21 | 21 |
| 22 /// GitHub style triple quoted code block. |
| 23 final _RE_CODE = new RegExp(r'^```(.*)$'); |
| 24 |
| 22 /// Three or more hyphens, asterisks or underscores by themselves. Note that | 25 /// Three or more hyphens, asterisks or underscores by themselves. Note that |
| 23 /// a line like `----` is valid as both HR and SETEXT. In case of a tie, | 26 /// a line like `----` is valid as both HR and SETEXT. In case of a tie, |
| 24 /// SETEXT should win. | 27 /// SETEXT should win. |
| 25 final _RE_HR = new RegExp(r'^[ ]{0,3}((-+[ ]{0,2}){3,}|' | 28 final _RE_HR = new RegExp(r'^[ ]{0,3}((-+[ ]{0,2}){3,}|' |
| 26 r'(_+[ ]{0,2}){3,}|' | 29 r'(_+[ ]{0,2}){3,}|' |
| 27 r'(\*+[ ]{0,2}){3,})$'); | 30 r'(\*+[ ]{0,2}){3,})$'); |
| 28 | 31 |
| 29 /// Really hacky way to detect block-level embedded HTML. Just looks for | 32 /// Really hacky way to detect block-level embedded HTML. Just looks for |
| 30 /// "<somename". | 33 /// "<somename". |
| 31 final _RE_HTML = new RegExp(r'^<[ ]*\w+[ >]'); | 34 final _RE_HTML = new RegExp(r'^<[ ]*\w+[ >]'); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 /// into blocks, each of these will be tried in turn. Order matters here. | 90 /// into blocks, each of these will be tried in turn. Order matters here. |
| 88 static List<BlockSyntax> get syntaxes { | 91 static List<BlockSyntax> get syntaxes { |
| 89 // Lazy initialize. | 92 // Lazy initialize. |
| 90 if (_syntaxes == null) { | 93 if (_syntaxes == null) { |
| 91 _syntaxes = [ | 94 _syntaxes = [ |
| 92 new EmptyBlockSyntax(), | 95 new EmptyBlockSyntax(), |
| 93 new BlockHtmlSyntax(), | 96 new BlockHtmlSyntax(), |
| 94 new SetextHeaderSyntax(), | 97 new SetextHeaderSyntax(), |
| 95 new HeaderSyntax(), | 98 new HeaderSyntax(), |
| 96 new CodeBlockSyntax(), | 99 new CodeBlockSyntax(), |
| 100 new GitHubCodeBlockSyntax(), |
| 97 new BlockquoteSyntax(), | 101 new BlockquoteSyntax(), |
| 98 new HorizontalRuleSyntax(), | 102 new HorizontalRuleSyntax(), |
| 99 new UnorderedListSyntax(), | 103 new UnorderedListSyntax(), |
| 100 new OrderedListSyntax(), | 104 new OrderedListSyntax(), |
| 101 new ParagraphSyntax() | 105 new ParagraphSyntax() |
| 102 ]; | 106 ]; |
| 103 } | 107 } |
| 104 | 108 |
| 105 return _syntaxes; | 109 return _syntaxes; |
| 106 } | 110 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 // The Markdown tests expect a trailing newline. | 237 // The Markdown tests expect a trailing newline. |
| 234 childLines.add(''); | 238 childLines.add(''); |
| 235 | 239 |
| 236 // Escape the code. | 240 // Escape the code. |
| 237 final escaped = escapeHtml(childLines.join('\n')); | 241 final escaped = escapeHtml(childLines.join('\n')); |
| 238 | 242 |
| 239 return new Element('pre', [new Element.text('code', escaped)]); | 243 return new Element('pre', [new Element.text('code', escaped)]); |
| 240 } | 244 } |
| 241 } | 245 } |
| 242 | 246 |
| 247 /// Parses preformatted code blocks between two ``` sequences. |
| 248 class GitHubCodeBlockSyntax extends BlockSyntax { |
| 249 RegExp get pattern => _RE_CODE; |
| 250 |
| 251 List<String> parseChildLines(BlockParser parser) { |
| 252 final childLines = <String>[]; |
| 253 parser.advance(); |
| 254 while (!parser.isDone) { |
| 255 var match = pattern.firstMatch(parser.current); |
| 256 if (match == null) { |
| 257 childLines.add(parser.current); |
| 258 parser.advance(); |
| 259 } else { |
| 260 parser.advance(); |
| 261 break; |
| 262 } |
| 263 } |
| 264 return childLines; |
| 265 } |
| 266 |
| 267 Node parse(BlockParser parser) { |
| 268 // Get the syntax identifier, if there is one. |
| 269 var syntax = pattern.firstMatch(parser.current).group(1); |
| 270 |
| 271 final childLines = parseChildLines(parser); |
| 272 |
| 273 // The Markdown tests expect a trailing newline. |
| 274 childLines.add(''); |
| 275 |
| 276 // Escape the code. |
| 277 final escaped = escapeHtml(childLines.join('\n')); |
| 278 |
| 279 return new Element('pre', [new Element.text('code', escaped)]); |
| 280 } |
| 281 } |
| 282 |
| 243 /// Parses horizontal rules like `---`, `_ _ _`, `* * *`, etc. | 283 /// Parses horizontal rules like `---`, `_ _ _`, `* * *`, etc. |
| 244 class HorizontalRuleSyntax extends BlockSyntax { | 284 class HorizontalRuleSyntax extends BlockSyntax { |
| 245 RegExp get pattern => _RE_HR; | 285 RegExp get pattern => _RE_HR; |
| 246 | 286 |
| 247 Node parse(BlockParser parser) { | 287 Node parse(BlockParser parser) { |
| 248 final match = pattern.firstMatch(parser.current); | 288 final match = pattern.firstMatch(parser.current); |
| 249 parser.advance(); | 289 parser.advance(); |
| 250 return new Element.empty('hr'); | 290 return new Element.empty('hr'); |
| 251 } | 291 } |
| 252 } | 292 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 // Eat until we hit something that ends a paragraph. | 494 // Eat until we hit something that ends a paragraph. |
| 455 while (!BlockSyntax.isAtBlockEnd(parser)) { | 495 while (!BlockSyntax.isAtBlockEnd(parser)) { |
| 456 childLines.add(parser.current); | 496 childLines.add(parser.current); |
| 457 parser.advance(); | 497 parser.advance(); |
| 458 } | 498 } |
| 459 | 499 |
| 460 final contents = parser.document.parseInline(childLines.join('\n')); | 500 final contents = parser.document.parseInline(childLines.join('\n')); |
| 461 return new Element('p', contents); | 501 return new Element('p', contents); |
| 462 } | 502 } |
| 463 } | 503 } |
| OLD | NEW |