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 /// Maintains the internal state needed to parse inline span elements in | 7 /// Maintains the internal state needed to parse inline span elements in |
8 /// markdown. | 8 /// markdown. |
9 class InlineParser { | 9 class InlineParser { |
10 static List<InlineSyntax> defaultSyntaxes = <InlineSyntax>[ | 10 static List<InlineSyntax> defaultSyntaxes = <InlineSyntax>[ |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 : _stack = <TagState>[] { | 73 : _stack = <TagState>[] { |
74 /// User specified syntaxes will be the first syntaxes to be evaluated. | 74 /// User specified syntaxes will be the first syntaxes to be evaluated. |
75 if (document.inlineSyntaxes != null) { | 75 if (document.inlineSyntaxes != null) { |
76 syntaxes = []; | 76 syntaxes = []; |
77 syntaxes.addAll(document.inlineSyntaxes); | 77 syntaxes.addAll(document.inlineSyntaxes); |
78 syntaxes.addAll(defaultSyntaxes); | 78 syntaxes.addAll(defaultSyntaxes); |
79 } else { | 79 } else { |
80 syntaxes = defaultSyntaxes; | 80 syntaxes = defaultSyntaxes; |
81 } | 81 } |
82 // Custom link resolver goes after the generic text syntax. | 82 // Custom link resolver goes after the generic text syntax. |
83 syntaxes.insertRange(1, 1, | 83 syntaxes.insert(1, new LinkSyntax(linkResolver: document.linkResolver)); |
84 new LinkSyntax(linkResolver: document.linkResolver)); | |
85 } | 84 } |
86 | 85 |
87 List<Node> parse() { | 86 List<Node> parse() { |
88 // Make a fake top tag to hold the results. | 87 // Make a fake top tag to hold the results. |
89 _stack.add(new TagState(0, 0, null)); | 88 _stack.add(new TagState(0, 0, null)); |
90 | 89 |
91 while (!isDone) { | 90 while (!isDone) { |
92 bool matched = false; | 91 bool matched = false; |
93 | 92 |
94 // See if any of the current tags on the stack match. We don't allow tags | 93 // See if any of the current tags on the stack match. We don't allow tags |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 /// If this is the last node in the stack, returns its children. | 380 /// If this is the last node in the stack, returns its children. |
382 List<Node> close(InlineParser parser, Match endMatch) { | 381 List<Node> close(InlineParser parser, Match endMatch) { |
383 // If there are unclosed tags on top of this one when it's closed, that | 382 // If there are unclosed tags on top of this one when it's closed, that |
384 // means they are mismatched. Mismatched tags are treated as plain text in | 383 // means they are mismatched. Mismatched tags are treated as plain text in |
385 // markdown. So for each tag above this one, we write its start tag as text | 384 // markdown. So for each tag above this one, we write its start tag as text |
386 // and then adds its children to this one's children. | 385 // and then adds its children to this one's children. |
387 int index = parser._stack.indexOf(this); | 386 int index = parser._stack.indexOf(this); |
388 | 387 |
389 // Remove the unmatched children. | 388 // Remove the unmatched children. |
390 final unmatchedTags = parser._stack.sublist(index + 1); | 389 final unmatchedTags = parser._stack.sublist(index + 1); |
391 parser._stack.removeRange(index + 1, parser._stack.length - index - 1); | 390 parser._stack.removeRange(index + 1, parser._stack.length); |
392 | 391 |
393 // Flatten them out onto this tag. | 392 // Flatten them out onto this tag. |
394 for (final unmatched in unmatchedTags) { | 393 for (final unmatched in unmatchedTags) { |
395 // Write the start tag as text. | 394 // Write the start tag as text. |
396 parser.writeTextRange(unmatched.startPos, unmatched.endPos); | 395 parser.writeTextRange(unmatched.startPos, unmatched.endPos); |
397 | 396 |
398 // Bequeath its children unto this tag. | 397 // Bequeath its children unto this tag. |
399 children.addAll(unmatched.children); | 398 children.addAll(unmatched.children); |
400 } | 399 } |
401 | 400 |
402 // Pop this off the stack. | 401 // Pop this off the stack. |
403 parser.writeText(); | 402 parser.writeText(); |
404 parser._stack.removeLast(); | 403 parser._stack.removeLast(); |
405 | 404 |
406 // If the stack is empty now, this is the special "results" node. | 405 // If the stack is empty now, this is the special "results" node. |
407 if (parser._stack.length == 0) return children; | 406 if (parser._stack.length == 0) return children; |
408 | 407 |
409 // We are still parsing, so add this to its parent's children. | 408 // We are still parsing, so add this to its parent's children. |
410 if (syntax.onMatchEnd(parser, endMatch, this)) { | 409 if (syntax.onMatchEnd(parser, endMatch, this)) { |
411 parser.consume(endMatch[0].length); | 410 parser.consume(endMatch[0].length); |
412 } else { | 411 } else { |
413 // Didn't close correctly so revert to text. | 412 // Didn't close correctly so revert to text. |
414 parser.start = startPos; | 413 parser.start = startPos; |
415 parser.advanceBy(endMatch[0].length); | 414 parser.advanceBy(endMatch[0].length); |
416 } | 415 } |
417 | 416 |
418 return null; | 417 return null; |
419 } | 418 } |
420 } | 419 } |
OLD | NEW |