mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-12 16:44:17 +02:00
Use JS & Jade to generate the customizer variables form HTML from variables.less; fixes #11095
also updates variables file organization (courtesy @mdo)
This commit is contained in:
1684
docs/_includes/customizer-variables.html
Normal file
1684
docs/_includes/customizer-variables.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1161,6 +1161,13 @@ h1[id] {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.bs-customizer-input {
|
||||
float: left;
|
||||
width: 33.333333%;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
/* Downloads */
|
||||
.bs-customize-download .btn-outline {
|
||||
padding: 20px;
|
||||
|
1365
docs/customize.html
1365
docs/customize.html
File diff suppressed because it is too large
Load Diff
18
docs/customizer-variables.jade
Normal file
18
docs/customizer-variables.jade
Normal file
@@ -0,0 +1,18 @@
|
||||
// NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-vars-form` Grunt task using the customizer-variables.jade template.
|
||||
each section in sections
|
||||
if section.customizable
|
||||
h2(id=section.id)= section.heading
|
||||
if section.docstring
|
||||
p!= section.docstring.html
|
||||
div.row
|
||||
each variable in section.variables
|
||||
div.bs-customizer-input
|
||||
label(for="input-" + variable.name)= variable.name
|
||||
input.form-control(
|
||||
id="input-" + variable.name
|
||||
type="text"
|
||||
value=variable.defaultValue
|
||||
data-var=variable.name)
|
||||
if variable.docstring
|
||||
p.help-block!= variable.docstring.html
|
||||
// NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-vars-form` Grunt task using the customizer-variables.jade template.
|
179
docs/grunt/bs-lessdoc-parser.js
Normal file
179
docs/grunt/bs-lessdoc-parser.js
Normal file
@@ -0,0 +1,179 @@
|
||||
/* jshint node: true */
|
||||
|
||||
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
|
||||
|
||||
//** 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 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.variables = [];
|
||||
this.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 = 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.parseVars(section);
|
||||
return section;
|
||||
};
|
||||
|
||||
Parser.prototype.parseVars = function (section) {
|
||||
while (true) {
|
||||
var variable = this.parseVar();
|
||||
if (variable === null) {
|
||||
return;
|
||||
}
|
||||
section.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;
|
Reference in New Issue
Block a user