diff options
| author | Jonathan Barronville | 2014-06-07 19:13:28 -0400 | 
|---|---|---|
| committer | Jonathan Barronville | 2014-06-07 19:13:28 -0400 | 
| commit | b56e5c671ce89f1c8ddc67a4ac8d2f59de04ea85 (patch) | |
| tree | 80ce4d67ff46505dc1ec77b72daf7bed59abf8b4 /bower_components/bootstrap/grunt/bs-lessdoc-parser.js | |
| parent | 67ad58c27c4a2704532246d044e1ecbae2a11022 (diff) | |
| download | sellevate-b56e5c671ce89f1c8ddc67a4ac8d2f59de04ea85.tar.bz2 | |
Yo.
Diffstat (limited to 'bower_components/bootstrap/grunt/bs-lessdoc-parser.js')
| -rw-r--r-- | bower_components/bootstrap/grunt/bs-lessdoc-parser.js | 236 | 
1 files changed, 236 insertions, 0 deletions
| diff --git a/bower_components/bootstrap/grunt/bs-lessdoc-parser.js b/bower_components/bootstrap/grunt/bs-lessdoc-parser.js new file mode 100644 index 0000000..5a86f13 --- /dev/null +++ b/bower_components/bootstrap/grunt/bs-lessdoc-parser.js @@ -0,0 +1,236 @@ +/*! + * Bootstrap Grunt task for parsing Less docstrings + * http://getbootstrap.com + * Copyright 2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +'use strict'; + +var markdown = require('markdown').markdown; + +function markdown2html(markdownString) { +  // the slice removes the <p>...</p> wrapper output by Markdown processor +  return markdown.toHTML(markdownString.trim()).slice(3, -4); +} + + +/* +Mini-language: +  //== This is a normal heading, which starts a section. Sections group variables together. +  //## Optional description for the heading + +  //=== This is a subheading. + +  //** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `<html>` stuff. +  @foo: #ffff; + +  //-- This is a heading for a section whose variables shouldn't be customizable + +  All other lines are ignored completely. +*/ + + +var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/; +var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/; +var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/; +var SECTION_DOCSTRING = /^[/]{2}#{2}(.*)$/; +var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]+);[ ]*$/; +var VAR_DOCSTRING = /^[/]{2}[*]{2}(.*)$/; + +function Section(heading, customizable) { +  this.heading = heading.trim(); +  this.id = this.heading.replace(/\s+/g, '-').toLowerCase(); +  this.customizable = customizable; +  this.docstring = null; +  this.subsections = []; +} + +Section.prototype.addSubSection = function (subsection) { +  this.subsections.push(subsection); +}; + +function SubSection(heading) { +  this.heading = heading.trim(); +  this.id = this.heading.replace(/\s+/g, '-').toLowerCase(); +  this.variables = []; +} + +SubSection.prototype.addVar = function (variable) { +  this.variables.push(variable); +}; + +function VarDocstring(markdownString) { +  this.html = markdown2html(markdownString); +} + +function SectionDocstring(markdownString) { +  this.html = markdown2html(markdownString); +} + +function Variable(name, defaultValue) { +  this.name = name; +  this.defaultValue = defaultValue; +  this.docstring = null; +} + +function Tokenizer(fileContent) { +  this._lines = fileContent.split('\n'); +  this._next = undefined; +} + +Tokenizer.prototype.unshift = function (token) { +  if (this._next !== undefined) { +    throw new Error('Attempted to unshift twice!'); +  } +  this._next = token; +}; + +Tokenizer.prototype._shift = function () { +  // returning null signals EOF +  // returning undefined means the line was ignored +  if (this._next !== undefined) { +    var result = this._next; +    this._next = undefined; +    return result; +  } +  if (this._lines.length <= 0) { +    return null; +  } +  var line = this._lines.shift(); +  var match = null; +  match = SUBSECTION_HEADING.exec(line); +  if (match !== null) { +    return new SubSection(match[1]); +  } +  match = CUSTOMIZABLE_HEADING.exec(line); +  if (match !== null) { +    return new Section(match[1], true); +  } +  match = UNCUSTOMIZABLE_HEADING.exec(line); +  if (match !== null) { +    return new Section(match[1], false); +  } +  match = SECTION_DOCSTRING.exec(line); +  if (match !== null) { +    return new SectionDocstring(match[1]); +  } +  match = VAR_DOCSTRING.exec(line); +  if (match !== null) { +    return new VarDocstring(match[1]); +  } +  var commentStart = line.lastIndexOf('//'); +  var varLine = (commentStart === -1) ? line : line.slice(0, commentStart); +  match = VAR_ASSIGNMENT.exec(varLine); +  if (match !== null) { +    return new Variable(match[1], match[2]); +  } +  return undefined; +}; + +Tokenizer.prototype.shift = function () { +  while (true) { +    var result = this._shift(); +    if (result === undefined) { +      continue; +    } +    return result; +  } +}; + +function Parser(fileContent) { +  this._tokenizer = new Tokenizer(fileContent); +} + +Parser.prototype.parseFile = function () { +  var sections = []; +  while (true) { +    var section = this.parseSection(); +    if (section === null) { +      if (this._tokenizer.shift() !== null) { +        throw new Error('Unexpected unparsed section of file remains!'); +      } +      return sections; +    } +    sections.push(section); +  } +}; + +Parser.prototype.parseSection = function () { +  var section = this._tokenizer.shift(); +  if (section === null) { +    return null; +  } +  if (!(section instanceof Section)) { +    throw new Error('Expected section heading; got: ' + JSON.stringify(section)); +  } +  var docstring = this._tokenizer.shift(); +  if (docstring instanceof SectionDocstring) { +    section.docstring = docstring; +  } +  else { +    this._tokenizer.unshift(docstring); +  } +  this.parseSubSections(section); + +  return section; +}; + +Parser.prototype.parseSubSections = function (section) { +  while (true) { +    var subsection = this.parseSubSection(); +    if (subsection === null) { +      if (section.subsections.length === 0) { +        // Presume an implicit initial subsection +        subsection = new SubSection(''); +        this.parseVars(subsection); +      } +      else { +        break; +      } +    } +    section.addSubSection(subsection); +  } + +  if (section.subsections.length === 1 && !(section.subsections[0].heading) && section.subsections[0].variables.length === 0) { +    // Ignore lone empty implicit subsection +    section.subsections = []; +  } +}; + +Parser.prototype.parseSubSection = function () { +  var subsection = this._tokenizer.shift(); +  if (subsection instanceof SubSection) { +    this.parseVars(subsection); +    return subsection; +  } +  this._tokenizer.unshift(subsection); +  return null; +}; + +Parser.prototype.parseVars = function (subsection) { +  while (true) { +    var variable = this.parseVar(); +    if (variable === null) { +      return; +    } +    subsection.addVar(variable); +  } +}; + +Parser.prototype.parseVar = function () { +  var docstring = this._tokenizer.shift(); +  if (!(docstring instanceof VarDocstring)) { +    this._tokenizer.unshift(docstring); +    docstring = null; +  } +  var variable = this._tokenizer.shift(); +  if (variable instanceof Variable) { +    variable.docstring = docstring; +    return variable; +  } +  this._tokenizer.unshift(variable); +  return null; +}; + + +module.exports = Parser; | 
