OLD | NEW |
1 library markdown.document; | 1 library markdown.src.document; |
2 | 2 |
3 import 'ast.dart'; | 3 import 'ast.dart'; |
4 import 'block_parser.dart'; | 4 import 'block_parser.dart'; |
5 import 'inline_parser.dart'; | 5 import 'inline_parser.dart'; |
6 | 6 |
7 /// Maintains the context needed to parse a markdown document. | 7 /// Maintains the context needed to parse a markdown document. |
8 class Document { | 8 class Document { |
9 final Map<String, Link> refLinks; | 9 final Map<String, Link> refLinks; |
10 List<InlineSyntax> inlineSyntaxes; | 10 List<InlineSyntax> inlineSyntaxes; |
11 Resolver linkResolver; | 11 Resolver linkResolver; |
12 Resolver imageLinkResolver; | 12 Resolver imageLinkResolver; |
13 | 13 |
14 Document({this.inlineSyntaxes, this.linkResolver, this.imageLinkResolver}) | 14 Document({this.inlineSyntaxes, this.linkResolver, this.imageLinkResolver}) |
15 : refLinks = <String, Link>{}; | 15 : refLinks = <String, Link>{}; |
16 | 16 |
17 parseRefLinks(List<String> lines) { | 17 parseRefLinks(List<String> lines) { |
18 // This is a hideous regex. It matches: | 18 // This is a hideous regex. It matches: |
19 // [id]: http:foo.com "some title" | 19 // [id]: http:foo.com "some title" |
20 // Where there may whitespace in there, and where the title may be in | 20 // Where there may whitespace in there, and where the title may be in |
21 // single quotes, double quotes, or parentheses. | 21 // single quotes, double quotes, or parentheses. |
22 final indent = r'^[ ]{0,3}'; // Leading indentation. | 22 var indent = r'^[ ]{0,3}'; // Leading indentation. |
23 final id = r'\[([^\]]+)\]'; // Reference id in [brackets]. | 23 var id = r'\[([^\]]+)\]'; // Reference id in [brackets]. |
24 final quote = r'"[^"]+"'; // Title in "double quotes". | 24 var quote = r'"[^"]+"'; // Title in "double quotes". |
25 final apos = r"'[^']+'"; // Title in 'single quotes'. | 25 var apos = r"'[^']+'"; // Title in 'single quotes'. |
26 final paren = r"\([^)]+\)"; // Title in (parentheses). | 26 var paren = r"\([^)]+\)"; // Title in (parentheses). |
27 final pattern = new RegExp( | 27 var pattern = |
28 '$indent$id:\\s+(\\S+)\\s*($quote|$apos|$paren|)\\s*\$'); | 28 new RegExp('$indent$id:\\s+(\\S+)\\s*($quote|$apos|$paren|)\\s*\$'); |
29 | 29 |
30 for (int i = 0; i < lines.length; i++) { | 30 for (var i = 0; i < lines.length; i++) { |
31 final match = pattern.firstMatch(lines[i]); | 31 var match = pattern.firstMatch(lines[i]); |
32 if (match != null) { | 32 if (match != null) { |
33 // Parse the link. | 33 // Parse the link. |
34 var id = match[1]; | 34 var id = match[1]; |
35 var url = match[2]; | 35 var url = match[2]; |
36 var title = match[3]; | 36 var title = match[3]; |
37 | 37 |
38 if (title == '') { | 38 if (title == '') { |
39 // No title. | 39 // No title. |
40 title = null; | 40 title = null; |
41 } else { | 41 } else { |
42 // Remove "", '', or (). | 42 // Remove "", '', or (). |
43 title = title.substring(1, title.length - 1); | 43 title = title.substring(1, title.length - 1); |
44 } | 44 } |
45 | 45 |
46 // References are case-insensitive. | 46 // References are case-insensitive. |
47 id = id.toLowerCase(); | 47 id = id.toLowerCase(); |
48 | 48 |
49 refLinks[id] = new Link(id, url, title); | 49 refLinks[id] = new Link(id, url, title); |
50 | 50 |
51 // Remove it from the output. We replace it with a blank line which will | 51 // Remove it from the output. We replace it with a blank line which will |
52 // get consumed by later processing. | 52 // get consumed by later processing. |
53 lines[i] = ''; | 53 lines[i] = ''; |
54 } | 54 } |
55 } | 55 } |
56 } | 56 } |
57 | 57 |
58 /// Parse the given [lines] of markdown to a series of AST nodes. | 58 /// Parse the given [lines] of markdown to a series of AST nodes. |
59 List<Node> parseLines(List<String> lines) { | 59 List<Node> parseLines(List<String> lines) { |
60 final parser = new BlockParser(lines, this); | 60 var parser = new BlockParser(lines, this); |
61 | 61 |
62 final blocks = []; | 62 var blocks = <Node>[]; |
63 while (!parser.isDone) { | 63 while (!parser.isDone) { |
64 for (final syntax in BlockSyntax.syntaxes) { | 64 for (var syntax in BlockSyntax.syntaxes) { |
65 if (syntax.canParse(parser)) { | 65 if (syntax.canParse(parser)) { |
66 final block = syntax.parse(parser); | 66 var block = syntax.parse(parser); |
67 if (block != null) blocks.add(block); | 67 if (block != null) blocks.add(block); |
68 break; | 68 break; |
69 } | 69 } |
70 } | 70 } |
71 } | 71 } |
72 | 72 |
73 return blocks; | 73 return blocks; |
74 } | 74 } |
75 | 75 |
76 /// Takes a string of raw text and processes all inline markdown tags, | 76 /// Takes a string of raw text and processes all inline markdown tags, |
77 /// returning a list of AST nodes. For example, given ``"*this **is** a* | 77 /// returning a list of AST nodes. For example, given ``"*this **is** a* |
78 /// `markdown`"``, returns: | 78 /// `markdown`"``, returns: |
79 /// `<em>this <strong>is</strong> a</em> <code>markdown</code>`. | 79 /// `<em>this <strong>is</strong> a</em> <code>markdown</code>`. |
80 List<Node> parseInline(String text) => new InlineParser(text, this).parse(); | 80 List<Node> parseInline(String text) => new InlineParser(text, this).parse(); |
81 } | 81 } |
82 | 82 |
83 class Link { | 83 class Link { |
84 final String id; | 84 final String id; |
85 final String url; | 85 final String url; |
86 final String title; | 86 final String title; |
87 Link(this.id, this.url, this.title); | 87 Link(this.id, this.url, this.title); |
88 } | 88 } |
OLD | NEW |