Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Side by Side Diff: pkg/dartdoc/block_parser.dart

Issue 10919146: Get rid of a lot of () for getters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/dartdoc/ast.dart ('k') | pkg/dartdoc/dartdoc.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /// The line contains only whitespace or is empty. 5 /// The line contains only whitespace or is empty.
6 const _RE_EMPTY = const RegExp(@'^([ \t]*)$'); 6 const _RE_EMPTY = const RegExp(@'^([ \t]*)$');
7 7
8 /// A series of `=` or `-` (on the next line) define setext-style headers. 8 /// A series of `=` or `-` (on the next line) define setext-style headers.
9 const _RE_SETEXT = const RegExp(@'^((=+)|(-+))$'); 9 const _RE_SETEXT = const RegExp(@'^((=+)|(-+))$');
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 /// The markdown document this parser is parsing. 45 /// The markdown document this parser is parsing.
46 final Document document; 46 final Document document;
47 47
48 /// Index of the current line. 48 /// Index of the current line.
49 int pos; 49 int pos;
50 50
51 BlockParser(this.lines, this.document) 51 BlockParser(this.lines, this.document)
52 : pos = 0; 52 : pos = 0;
53 53
54 /// Gets the current line. 54 /// Gets the current line.
55 String get current() => lines[pos]; 55 String get current => lines[pos];
56 56
57 /// Gets the line after the current one or `null` if there is none. 57 /// Gets the line after the current one or `null` if there is none.
58 String get next() { 58 String get next {
59 // Don't read past the end. 59 // Don't read past the end.
60 if (pos >= lines.length - 1) return null; 60 if (pos >= lines.length - 1) return null;
61 return lines[pos + 1]; 61 return lines[pos + 1];
62 } 62 }
63 63
64 void advance() { 64 void advance() {
65 pos++; 65 pos++;
66 } 66 }
67 67
68 bool get isDone() => pos >= lines.length; 68 bool get isDone => pos >= lines.length;
69 69
70 /// Gets whether or not the current line matches the given pattern. 70 /// Gets whether or not the current line matches the given pattern.
71 bool matches(RegExp regex) { 71 bool matches(RegExp regex) {
72 if (isDone) return false; 72 if (isDone) return false;
73 return regex.firstMatch(current) != null; 73 return regex.firstMatch(current) != null;
74 } 74 }
75 75
76 /// Gets whether or not the current line matches the given pattern. 76 /// Gets whether or not the current line matches the given pattern.
77 bool matchesNext(RegExp regex) { 77 bool matchesNext(RegExp regex) {
78 if (next == null) return false; 78 if (next == null) return false;
79 return regex.firstMatch(next) != null; 79 return regex.firstMatch(next) != null;
80 } 80 }
81 } 81 }
82 82
83 class BlockSyntax { 83 class BlockSyntax {
84 /// Gets the collection of built-in block parsers. To turn a series of lines 84 /// Gets the collection of built-in block parsers. To turn a series of lines
85 /// into blocks, each of these will be tried in turn. Order matters here. 85 /// into blocks, each of these will be tried in turn. Order matters here.
86 static List<BlockSyntax> get syntaxes() { 86 static List<BlockSyntax> get syntaxes {
87 // Lazy initialize. 87 // Lazy initialize.
88 if (_syntaxes == null) { 88 if (_syntaxes == null) {
89 _syntaxes = [ 89 _syntaxes = [
90 new EmptyBlockSyntax(), 90 new EmptyBlockSyntax(),
91 new BlockHtmlSyntax(), 91 new BlockHtmlSyntax(),
92 new SetextHeaderSyntax(), 92 new SetextHeaderSyntax(),
93 new HeaderSyntax(), 93 new HeaderSyntax(),
94 new CodeBlockSyntax(), 94 new CodeBlockSyntax(),
95 new BlockquoteSyntax(), 95 new BlockquoteSyntax(),
96 new HorizontalRuleSyntax(), 96 new HorizontalRuleSyntax(),
97 new UnorderedListSyntax(), 97 new UnorderedListSyntax(),
98 new OrderedListSyntax(), 98 new OrderedListSyntax(),
99 new ParagraphSyntax() 99 new ParagraphSyntax()
100 ]; 100 ];
101 } 101 }
102 102
103 return _syntaxes; 103 return _syntaxes;
104 } 104 }
105 105
106 static List<BlockSyntax> _syntaxes; 106 static List<BlockSyntax> _syntaxes;
107 107
108 /// Gets the regex used to identify the beginning of this block, if any. 108 /// Gets the regex used to identify the beginning of this block, if any.
109 RegExp get pattern() => null; 109 RegExp get pattern => null;
110 110
111 bool get canEndBlock() => true; 111 bool get canEndBlock => true;
112 112
113 bool canParse(BlockParser parser) { 113 bool canParse(BlockParser parser) {
114 return pattern.firstMatch(parser.current) != null; 114 return pattern.firstMatch(parser.current) != null;
115 } 115 }
116 116
117 abstract Node parse(BlockParser parser); 117 abstract Node parse(BlockParser parser);
118 118
119 List<String> parseChildLines(BlockParser parser) { 119 List<String> parseChildLines(BlockParser parser) {
120 // Grab all of the lines that form the blockquote, stripping off the ">". 120 // Grab all of the lines that form the blockquote, stripping off the ">".
121 final childLines = <String>[]; 121 final childLines = <String>[];
122 122
123 while (!parser.isDone) { 123 while (!parser.isDone) {
124 final match = pattern.firstMatch(parser.current); 124 final match = pattern.firstMatch(parser.current);
125 if (match == null) break; 125 if (match == null) break;
126 childLines.add(match[1]); 126 childLines.add(match[1]);
127 parser.advance(); 127 parser.advance();
128 } 128 }
129 129
130 return childLines; 130 return childLines;
131 } 131 }
132 132
133 /// Gets whether or not [parser]'s current line should end the previous block. 133 /// Gets whether or not [parser]'s current line should end the previous block.
134 static bool isAtBlockEnd(BlockParser parser) { 134 static bool isAtBlockEnd(BlockParser parser) {
135 if (parser.isDone) return true; 135 if (parser.isDone) return true;
136 return syntaxes.some((s) => s.canParse(parser) && s.canEndBlock); 136 return syntaxes.some((s) => s.canParse(parser) && s.canEndBlock);
137 } 137 }
138 } 138 }
139 139
140 class EmptyBlockSyntax extends BlockSyntax { 140 class EmptyBlockSyntax extends BlockSyntax {
141 RegExp get pattern() => _RE_EMPTY; 141 RegExp get pattern => _RE_EMPTY;
142 142
143 Node parse(BlockParser parser) { 143 Node parse(BlockParser parser) {
144 parser.advance(); 144 parser.advance();
145 145
146 // Don't actually emit anything. 146 // Don't actually emit anything.
147 return null; 147 return null;
148 } 148 }
149 } 149 }
150 150
151 /// Parses setext-style headers. 151 /// Parses setext-style headers.
(...skipping 11 matching lines...) Expand all
163 final contents = parser.document.parseInline(parser.current); 163 final contents = parser.document.parseInline(parser.current);
164 parser.advance(); 164 parser.advance();
165 parser.advance(); 165 parser.advance();
166 166
167 return new Element(tag, contents); 167 return new Element(tag, contents);
168 } 168 }
169 } 169 }
170 170
171 /// Parses atx-style headers: `## Header ##`. 171 /// Parses atx-style headers: `## Header ##`.
172 class HeaderSyntax extends BlockSyntax { 172 class HeaderSyntax extends BlockSyntax {
173 RegExp get pattern() => _RE_HEADER; 173 RegExp get pattern => _RE_HEADER;
174 174
175 Node parse(BlockParser parser) { 175 Node parse(BlockParser parser) {
176 final match = pattern.firstMatch(parser.current); 176 final match = pattern.firstMatch(parser.current);
177 parser.advance(); 177 parser.advance();
178 final level = match[1].length; 178 final level = match[1].length;
179 final contents = parser.document.parseInline(match[2].trim()); 179 final contents = parser.document.parseInline(match[2].trim());
180 return new Element('h$level', contents); 180 return new Element('h$level', contents);
181 } 181 }
182 } 182 }
183 183
184 /// Parses email-style blockquotes: `> quote`. 184 /// Parses email-style blockquotes: `> quote`.
185 class BlockquoteSyntax extends BlockSyntax { 185 class BlockquoteSyntax extends BlockSyntax {
186 RegExp get pattern() => _RE_BLOCKQUOTE; 186 RegExp get pattern => _RE_BLOCKQUOTE;
187 187
188 Node parse(BlockParser parser) { 188 Node parse(BlockParser parser) {
189 final childLines = parseChildLines(parser); 189 final childLines = parseChildLines(parser);
190 190
191 // Recursively parse the contents of the blockquote. 191 // Recursively parse the contents of the blockquote.
192 final children = parser.document.parseLines(childLines); 192 final children = parser.document.parseLines(childLines);
193 193
194 return new Element('blockquote', children); 194 return new Element('blockquote', children);
195 } 195 }
196 } 196 }
197 197
198 /// Parses preformatted code blocks that are indented four spaces. 198 /// Parses preformatted code blocks that are indented four spaces.
199 class CodeBlockSyntax extends BlockSyntax { 199 class CodeBlockSyntax extends BlockSyntax {
200 RegExp get pattern() => _RE_INDENT; 200 RegExp get pattern => _RE_INDENT;
201 201
202 Node parse(BlockParser parser) { 202 Node parse(BlockParser parser) {
203 final childLines = parseChildLines(parser); 203 final childLines = parseChildLines(parser);
204 204
205 // The Markdown tests expect a trailing newline. 205 // The Markdown tests expect a trailing newline.
206 childLines.add(''); 206 childLines.add('');
207 207
208 // Escape the code. 208 // Escape the code.
209 final escaped = escapeHtml(Strings.join(childLines, '\n')); 209 final escaped = escapeHtml(Strings.join(childLines, '\n'));
210 210
211 return new Element('pre', [new Element.text('code', escaped)]); 211 return new Element('pre', [new Element.text('code', escaped)]);
212 } 212 }
213 } 213 }
214 214
215 /// Parses horizontal rules like `---`, `_ _ _`, `* * *`, etc. 215 /// Parses horizontal rules like `---`, `_ _ _`, `* * *`, etc.
216 class HorizontalRuleSyntax extends BlockSyntax { 216 class HorizontalRuleSyntax extends BlockSyntax {
217 RegExp get pattern() => _RE_HR; 217 RegExp get pattern => _RE_HR;
218 218
219 Node parse(BlockParser parser) { 219 Node parse(BlockParser parser) {
220 final match = pattern.firstMatch(parser.current); 220 final match = pattern.firstMatch(parser.current);
221 parser.advance(); 221 parser.advance();
222 return new Element.empty('hr'); 222 return new Element.empty('hr');
223 } 223 }
224 } 224 }
225 225
226 /// Parses inline HTML at the block level. This differs from other markdown 226 /// Parses inline HTML at the block level. This differs from other markdown
227 /// implementations in several ways: 227 /// implementations in several ways:
228 /// 228 ///
229 /// 1. This one is way way WAY simpler. 229 /// 1. This one is way way WAY simpler.
230 /// 2. All HTML tags at the block level will be treated as blocks. If you 230 /// 2. All HTML tags at the block level will be treated as blocks. If you
231 /// start a paragraph with `<em>`, it will not wrap it in a `<p>` for you. 231 /// start a paragraph with `<em>`, it will not wrap it in a `<p>` for you.
232 /// As soon as it sees something like HTML, it stops mucking with it until 232 /// As soon as it sees something like HTML, it stops mucking with it until
233 /// it hits the next block. 233 /// it hits the next block.
234 /// 3. Absolutely no HTML parsing or validation is done. We're a markdown 234 /// 3. Absolutely no HTML parsing or validation is done. We're a markdown
235 /// parser not an HTML parser! 235 /// parser not an HTML parser!
236 class BlockHtmlSyntax extends BlockSyntax { 236 class BlockHtmlSyntax extends BlockSyntax {
237 RegExp get pattern() => _RE_HTML; 237 RegExp get pattern => _RE_HTML;
238 238
239 bool get canEndBlock() => false; 239 bool get canEndBlock => false;
240 240
241 Node parse(BlockParser parser) { 241 Node parse(BlockParser parser) {
242 final childLines = []; 242 final childLines = [];
243 243
244 // Eat until we hit a blank line. 244 // Eat until we hit a blank line.
245 while (!parser.isDone && !parser.matches(_RE_EMPTY)) { 245 while (!parser.isDone && !parser.matches(_RE_EMPTY)) {
246 childLines.add(parser.current); 246 childLines.add(parser.current);
247 parser.advance(); 247 parser.advance();
248 } 248 }
249 249
250 return new Text(Strings.join(childLines, '\n')); 250 return new Text(Strings.join(childLines, '\n'));
251 } 251 }
252 } 252 }
253 253
254 class ListItem { 254 class ListItem {
255 bool forceBlock = false; 255 bool forceBlock = false;
256 final List<String> lines; 256 final List<String> lines;
257 257
258 ListItem(this.lines); 258 ListItem(this.lines);
259 } 259 }
260 260
261 /// Base class for both ordered and unordered lists. 261 /// Base class for both ordered and unordered lists.
262 class ListSyntax extends BlockSyntax { 262 class ListSyntax extends BlockSyntax {
263 bool get canEndBlock() => false; 263 bool get canEndBlock => false;
264 264
265 abstract String get listTag(); 265 abstract String get listTag;
266 266
267 Node parse(BlockParser parser) { 267 Node parse(BlockParser parser) {
268 final items = <ListItem>[]; 268 final items = <ListItem>[];
269 var childLines = <String>[]; 269 var childLines = <String>[];
270 270
271 endItem() { 271 endItem() {
272 if (childLines.length > 0) { 272 if (childLines.length > 0) {
273 items.add(new ListItem(childLines)); 273 items.add(new ListItem(childLines));
274 childLines = <String>[]; 274 childLines = <String>[];
275 } 275 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 itemNodes.add(new Element('li', contents)); 397 itemNodes.add(new Element('li', contents));
398 } 398 }
399 } 399 }
400 400
401 return new Element(listTag, itemNodes); 401 return new Element(listTag, itemNodes);
402 } 402 }
403 } 403 }
404 404
405 /// Parses unordered lists. 405 /// Parses unordered lists.
406 class UnorderedListSyntax extends ListSyntax { 406 class UnorderedListSyntax extends ListSyntax {
407 RegExp get pattern() => _RE_UL; 407 RegExp get pattern => _RE_UL;
408 String get listTag() => 'ul'; 408 String get listTag => 'ul';
409 } 409 }
410 410
411 /// Parses ordered lists. 411 /// Parses ordered lists.
412 class OrderedListSyntax extends ListSyntax { 412 class OrderedListSyntax extends ListSyntax {
413 RegExp get pattern() => _RE_OL; 413 RegExp get pattern => _RE_OL;
414 String get listTag() => 'ol'; 414 String get listTag => 'ol';
415 } 415 }
416 416
417 /// Parses paragraphs of regular text. 417 /// Parses paragraphs of regular text.
418 class ParagraphSyntax extends BlockSyntax { 418 class ParagraphSyntax extends BlockSyntax {
419 bool get canEndBlock() => false; 419 bool get canEndBlock => false;
420 420
421 bool canParse(BlockParser parser) => true; 421 bool canParse(BlockParser parser) => true;
422 422
423 Node parse(BlockParser parser) { 423 Node parse(BlockParser parser) {
424 final childLines = []; 424 final childLines = [];
425 425
426 // Eat until we hit something that ends a paragraph. 426 // Eat until we hit something that ends a paragraph.
427 while (!BlockSyntax.isAtBlockEnd(parser)) { 427 while (!BlockSyntax.isAtBlockEnd(parser)) {
428 childLines.add(parser.current); 428 childLines.add(parser.current);
429 parser.advance(); 429 parser.advance();
430 } 430 }
431 431
432 final contents = parser.document.parseInline( 432 final contents = parser.document.parseInline(
433 Strings.join(childLines, '\n')); 433 Strings.join(childLines, '\n'));
434 return new Element('p', contents); 434 return new Element('p', contents);
435 } 435 }
436 } 436 }
OLDNEW
« no previous file with comments | « pkg/dartdoc/ast.dart ('k') | pkg/dartdoc/dartdoc.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698