corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /*!
2 * Bootstrap Grunt task for parsing Less docstrings
3 * http://getbootstrap.com
4 * Copyright 2014 Twitter, Inc.
5 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
6 */
7 'use strict';
8  
9 var markdown = require('markdown').markdown;
10  
11 function markdown2html(markdownString) {
12 // the slice removes the <p>...</p> wrapper output by Markdown processor
13 return markdown.toHTML(markdownString.trim()).slice(3, -4);
14 }
15  
16  
17 /*
18 Mini-language:
19 //== This is a normal heading, which starts a section. Sections group variables together.
20 //## Optional description for the heading
21  
22 //=== This is a subheading.
23  
24 //** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `<html>` stuff.
25 @foo: #ffff;
26  
27 //-- This is a heading for a section whose variables shouldn't be customizable
28  
29 All other lines are ignored completely.
30 */
31  
32  
33 var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/;
34 var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/;
35 var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/;
36 var SECTION_DOCSTRING = /^[/]{2}#{2}(.*)$/;
37 var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]+);[ ]*$/;
38 var VAR_DOCSTRING = /^[/]{2}[*]{2}(.*)$/;
39  
40 function Section(heading, customizable) {
41 this.heading = heading.trim();
42 this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
43 this.customizable = customizable;
44 this.docstring = null;
45 this.subsections = [];
46 }
47  
48 Section.prototype.addSubSection = function (subsection) {
49 this.subsections.push(subsection);
50 };
51  
52 function SubSection(heading) {
53 this.heading = heading.trim();
54 this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
55 this.variables = [];
56 }
57  
58 SubSection.prototype.addVar = function (variable) {
59 this.variables.push(variable);
60 };
61  
62 function VarDocstring(markdownString) {
63 this.html = markdown2html(markdownString);
64 }
65  
66 function SectionDocstring(markdownString) {
67 this.html = markdown2html(markdownString);
68 }
69  
70 function Variable(name, defaultValue) {
71 this.name = name;
72 this.defaultValue = defaultValue;
73 this.docstring = null;
74 }
75  
76 function Tokenizer(fileContent) {
77 this._lines = fileContent.split('\n');
78 this._next = undefined;
79 }
80  
81 Tokenizer.prototype.unshift = function (token) {
82 if (this._next !== undefined) {
83 throw new Error('Attempted to unshift twice!');
84 }
85 this._next = token;
86 };
87  
88 Tokenizer.prototype._shift = function () {
89 // returning null signals EOF
90 // returning undefined means the line was ignored
91 if (this._next !== undefined) {
92 var result = this._next;
93 this._next = undefined;
94 return result;
95 }
96 if (this._lines.length <= 0) {
97 <= 0) { return null;
98 <= 0) { }
99 <= 0) { var line = this._lines.shift();
100 <= 0) { var match = null;
101 <= 0) { match = SUBSECTION_HEADING.exec(line);
102 <= 0) { if (match !== null) {
103 <= 0) { return new SubSection(match[1]);
104 <= 0) { }
105 <= 0) { match = CUSTOMIZABLE_HEADING.exec(line);
106 <= 0) { if (match !== null) {
107 <= 0) { return new Section(match[1], true);
108 <= 0) { }
109 <= 0) { match = UNCUSTOMIZABLE_HEADING.exec(line);
110 <= 0) { if (match !== null) {
111 <= 0) { return new Section(match[1], false);
112 <= 0) { }
113 <= 0) { match = SECTION_DOCSTRING.exec(line);
114 <= 0) { if (match !== null) {
115 <= 0) { return new SectionDocstring(match[1]);
116 <= 0) { }
117 <= 0) { match = VAR_DOCSTRING.exec(line);
118 <= 0) { if (match !== null) {
119 <= 0) { return new VarDocstring(match[1]);
120 <= 0) { }
121 <= 0) { var commentStart = line.lastIndexOf('//');
122 <= 0) { var varLine = (commentStart === -1) ? line : line.slice(0, commentStart);
123 <= 0) { match = VAR_ASSIGNMENT.exec(varLine);
124 <= 0) { if (match !== null) {
125 <= 0) { return new Variable(match[1], match[2]);
126 <= 0) { }
127 <= 0) { return undefined;
128 <= 0) {};
129  
130 <= 0) {Tokenizer.prototype.shift = function () {
131 <= 0) { while (true) {
132 <= 0) { var result = this._shift();
133 <= 0) { if (result === undefined) {
134 <= 0) { continue;
135 <= 0) { }
136 <= 0) { return result;
137 <= 0) { }
138 <= 0) {};
139  
140 <= 0) {function Parser(fileContent) {
141 <= 0) { this._tokenizer = new Tokenizer(fileContent);
142 <= 0) {}
143  
144 <= 0) {Parser.prototype.parseFile = function () {
145 <= 0) { var sections = [];
146 <= 0) { while (true) {
147 <= 0) { var section = this.parseSection();
148 <= 0) { if (section === null) {
149 <= 0) { if (this._tokenizer.shift() !== null) {
150 <= 0) { throw new Error('Unexpected unparsed section of file remains!');
151 <= 0) { }
152 <= 0) { return sections;
153 <= 0) { }
154 <= 0) { sections.push(section);
155 <= 0) { }
156 <= 0) {};
157  
158 <= 0) {Parser.prototype.parseSection = function () {
159 <= 0) { var section = this._tokenizer.shift();
160 <= 0) { if (section === null) {
161 <= 0) { return null;
162 <= 0) { }
163 <= 0) { if (!(section instanceof Section)) {
164 <= 0) { throw new Error('Expected section heading; got: ' + JSON.stringify(section));
165 <= 0) { }
166 <= 0) { var docstring = this._tokenizer.shift();
167 <= 0) { if (docstring instanceof SectionDocstring) {
168 <= 0) { section.docstring = docstring;
169 <= 0) { }
170 <= 0) { else {
171 <= 0) { this._tokenizer.unshift(docstring);
172 <= 0) { }
173 <= 0) { this.parseSubSections(section);
174  
175 <= 0) { return section;
176 <= 0) {};
177  
178 <= 0) {Parser.prototype.parseSubSections = function (section) {
179 <= 0) { while (true) {
180 <= 0) { var subsection = this.parseSubSection();
181 <= 0) { if (subsection === null) {
182 <= 0) { if (section.subsections.length === 0) {
183 <= 0) { // Presume an implicit initial subsection
184 <= 0) { subsection = new SubSection('');
185 <= 0) { this.parseVars(subsection);
186 <= 0) { }
187 <= 0) { else {
188 <= 0) { break;
189 <= 0) { }
190 <= 0) { }
191 <= 0) { section.addSubSection(subsection);
192 <= 0) { }
193  
194 <= 0) { if (section.subsections.length === 1 && !(section.subsections[0].heading) && section.subsections[0].variables.length === 0) {
195 <= 0) { // Ignore lone empty implicit subsection
196 <= 0) { section.subsections = [];
197 <= 0) { }
198 <= 0) {};
199  
200 <= 0) {Parser.prototype.parseSubSection = function () {
201 <= 0) { var subsection = this._tokenizer.shift();
202 <= 0) { if (subsection instanceof SubSection) {
203 <= 0) { this.parseVars(subsection);
204 <= 0) { return subsection;
205 <= 0) { }
206 <= 0) { this._tokenizer.unshift(subsection);
207 <= 0) { return null;
208 <= 0) {};
209  
210 <= 0) {Parser.prototype.parseVars = function (subsection) {
211 <= 0) { while (true) {
212 <= 0) { var variable = this.parseVar();
213 <= 0) { if (variable === null) {
214 <= 0) { return;
215 <= 0) { }
216 <= 0) { subsection.addVar(variable);
217 <= 0) { }
218 <= 0) {};
219  
220 <= 0) {Parser.prototype.parseVar = function () {
221 <= 0) { var docstring = this._tokenizer.shift();
222 <= 0) { if (!(docstring instanceof VarDocstring)) {
223 <= 0) { this._tokenizer.unshift(docstring);
224 <= 0) { docstring = null;
225 <= 0) { }
226 <= 0) { var variable = this._tokenizer.shift();
227 <= 0) { if (variable instanceof Variable) {
228 <= 0) { variable.docstring = docstring;
229 <= 0) { return variable;
230 <= 0) { }
231 <= 0) { this._tokenizer.unshift(variable);
232 <= 0) { return null;
233 <= 0) {};
234  
235  
236 <= 0) {module.exports = Parser;