mirror of
https://github.com/tenrok/bootstrap.git
synced 2026-05-27 14:46:01 +03:00
Merge branch 'master' into docs_derp
Conflicts: docs/assets/css/docs.css
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@
|
||||
|
||||
{% if page.slug == "customize" %}
|
||||
<script src="{{ site.baseurl }}assets/js/raw-files.js"></script>
|
||||
<script src="{{ site.baseurl }}assets/js/customize.js"></script>
|
||||
<script src="{{ site.baseurl }}assets/js/customize.min.js"></script>
|
||||
{% endif %}
|
||||
|
||||
{% comment %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*csslint ids: false, overqualified-elements: false*/
|
||||
/*!
|
||||
* Copyright 2013 Twitter, Inc.
|
||||
* Copyright 2011-2014 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
|
||||
* details, see http://creativecommons.org/licenses/by/3.0/.
|
||||
@@ -1255,6 +1256,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;
|
||||
@@ -1379,6 +1387,7 @@ h1[id] {
|
||||
|
||||
/* Pseudo :focus state for showing how it looks in the docs */
|
||||
#focusedInput {
|
||||
border-color: rgb(204,204,204); /* Restate unfocused value to make CSSLint happy that there's a pre-CSS3 fallback*/
|
||||
border-color: rgba(82,168,236,.8);
|
||||
outline: 0;
|
||||
outline: thin dotted \9; /* IE6-9 */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// ++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
/*!
|
||||
* Copyright 2013 Twitter, Inc.
|
||||
* Copyright 2011-2014 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
|
||||
* details, see http://creativecommons.org/licenses/by/3.0/.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Copyright 2013 Twitter, Inc.
|
||||
* Copyright 2011-2014 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
|
||||
* details, see http://creativecommons.org/licenses/by/3.0/.
|
||||
@@ -10,7 +10,7 @@
|
||||
window.onload = function () { // wait for load in a dumb way because B-0
|
||||
var cw = '/*!\n' +
|
||||
' * Bootstrap v3.0.3 (http://getbootstrap.com)\n' +
|
||||
' * Copyright 2013 Twitter, Inc.\n' +
|
||||
' * Copyright 2011-2014 Twitter, Inc.\n' +
|
||||
' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
|
||||
' */\n\n';
|
||||
|
||||
@@ -173,20 +173,55 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an Array of @import'd filenames from 'bootstrap.less' in the order
|
||||
// Returns an Array of @import'd filenames in the order
|
||||
// in which they appear in the file.
|
||||
function bootstrapLessFilenames() {
|
||||
function includedLessFilenames(lessFilename) {
|
||||
var IMPORT_REGEX = /^@import \"(.*?)\";$/
|
||||
var bootstrapLessLines = __less['bootstrap.less'].split('\n')
|
||||
var lessLines = __less[lessFilename].split('\n')
|
||||
|
||||
for (var i = 0, imports = []; i < bootstrapLessLines.length; i++) {
|
||||
var match = IMPORT_REGEX.exec(bootstrapLessLines[i])
|
||||
for (var i = 0, imports = []; i < lessLines.length; i++) {
|
||||
var match = IMPORT_REGEX.exec(lessLines[i])
|
||||
if (match) imports.push(match[1])
|
||||
}
|
||||
|
||||
return imports
|
||||
}
|
||||
|
||||
function generateLESS(lessFilename, lessFileIncludes, vars) {
|
||||
var lessSource = __less[lessFilename]
|
||||
|
||||
$.each(includedLessFilenames(lessFilename), function(index, filename) {
|
||||
var fileInclude = lessFileIncludes[filename]
|
||||
|
||||
// Files not explicitly unchecked are compiled into the final stylesheet.
|
||||
// Core stylesheets like 'normalize.less' are not included in the form
|
||||
// since disabling them would wreck everything, and so their 'fileInclude'
|
||||
// will be 'undefined'.
|
||||
if (fileInclude || (fileInclude == null)) lessSource += __less[filename]
|
||||
|
||||
// Custom variables are added after Bootstrap variables so the custom
|
||||
// ones take precedence.
|
||||
if (('variables.less' === filename) && vars) lessSource += generateCustomCSS(vars)
|
||||
})
|
||||
|
||||
lessSource = lessSource.replace(/@import[^\n]*/gi, '') //strip any imports
|
||||
return lessSource
|
||||
}
|
||||
|
||||
function compileLESS(lessSource, baseFilename, intoResult) {
|
||||
var parser = new less.Parser({
|
||||
paths: ['variables.less', 'mixins.less'],
|
||||
optimization: 0,
|
||||
filename: baseFilename + '.css'
|
||||
}).parse(lessSource, function (err, tree) {
|
||||
if (err) {
|
||||
return showError('<strong>Ruh roh!</strong> Could not parse less files.', err)
|
||||
}
|
||||
intoResult[baseFilename + '.css'] = cw + tree.toCSS()
|
||||
intoResult[baseFilename + '.min.css'] = cw + tree.toCSS({ compress: true })
|
||||
})
|
||||
}
|
||||
|
||||
function generateCSS() {
|
||||
var oneChecked = false
|
||||
var lessFileIncludes = {}
|
||||
@@ -202,43 +237,18 @@ window.onload = function () { // wait for load in a dumb way because B-0
|
||||
|
||||
var result = {}
|
||||
var vars = {}
|
||||
var css = ''
|
||||
|
||||
$('#less-variables-section input')
|
||||
.each(function () {
|
||||
$(this).val() && (vars[$(this).prev().text()] = $(this).val())
|
||||
})
|
||||
|
||||
$.each(bootstrapLessFilenames(), function(index, filename) {
|
||||
var fileInclude = lessFileIncludes[filename]
|
||||
|
||||
// Files not explicitly unchecked are compiled into the final stylesheet.
|
||||
// Core stylesheets like 'normalize.less' are not included in the form
|
||||
// since disabling them would wreck everything, and so their 'fileInclude'
|
||||
// will be 'undefined'.
|
||||
if (fileInclude || (fileInclude == null)) css += __less[filename]
|
||||
|
||||
// Custom variables are added after Bootstrap variables so the custom
|
||||
// ones take precedence.
|
||||
if (('variables.less' === filename) && vars) css += generateCustomCSS(vars)
|
||||
})
|
||||
|
||||
css = css.replace(/@import[^\n]*/gi, '') //strip any imports
|
||||
var bsLessSource = generateLESS('bootstrap.less', lessFileIncludes, vars)
|
||||
var themeLessSource = generateLESS('theme.less', lessFileIncludes, vars)
|
||||
|
||||
try {
|
||||
var parser = new less.Parser({
|
||||
paths: ['variables.less', 'mixins.less'],
|
||||
optimization: 0,
|
||||
filename: 'bootstrap.css'
|
||||
}).parse(css, function (err, tree) {
|
||||
if (err) {
|
||||
return showError('<strong>Ruh roh!</strong> Could not parse less files.', err)
|
||||
}
|
||||
result = {
|
||||
'bootstrap.css' : cw + tree.toCSS(),
|
||||
'bootstrap.min.css' : cw + tree.toCSS({ compress: true })
|
||||
}
|
||||
})
|
||||
compileLESS(bsLessSource, 'bootstrap', result)
|
||||
compileLESS(themeLessSource, 'bootstrap-theme', result)
|
||||
} catch (err) {
|
||||
return showError('<strong>Ruh roh!</strong> Could not parse less files.', err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// IT'S JUST JUNK FOR OUR DOCS!
|
||||
// ++++++++++++++++++++++++++++++++++++++++++
|
||||
/*!
|
||||
* Copyright 2013 Twitter, Inc.
|
||||
* Copyright 2011-2014 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
|
||||
* details, see http://creativecommons.org/licenses/by/3.0/.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2616,17 +2616,17 @@ body { padding-bottom: 70px; }
|
||||
<div class="col-sm-6">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item list-group-item-success">Dapibus ac facilisis in</li>
|
||||
<li class="list-group-item list-group-item-info">Cras sit amet nibh libero</li>
|
||||
<li class="list-group-item list-group-item-warning">Porta ac consectetur ac</li>
|
||||
<li class="list-group-item list-group-item-danger">Vestibulum at eros</li>
|
||||
<li class="list-group-item list-group-item-info">Cras sit amet nibh libero</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item list-group-item-success">Dapibus ac facilisis in</a>
|
||||
<a href="#" class="list-group-item list-group-item-info">Cras sit amet nibh libero</a>
|
||||
<a href="#" class="list-group-item list-group-item-warning">Porta ac consectetur ac</a>
|
||||
<a href="#" class="list-group-item list-group-item-danger">Vestibulum at eros</a>
|
||||
<a href="#" class="list-group-item list-group-item-info">Cras sit amet nibh libero</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2634,15 +2634,15 @@ body { padding-bottom: 70px; }
|
||||
{% highlight html %}
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item list-group-item-success">Dapibus ac facilisis in</li>
|
||||
<li class="list-group-item list-group-item-info">Cras sit amet nibh libero</li>
|
||||
<li class="list-group-item list-group-item-warning">Porta ac consectetur ac</li>
|
||||
<li class="list-group-item list-group-item-danger">Vestibulum at eros</li>
|
||||
<li class="list-group-item list-group-item-info">Cras sit amet nibh libero</li>
|
||||
</ul>
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item list-group-item-success">Dapibus ac facilisis in</a>
|
||||
<a href="#" class="list-group-item list-group-item-info">Cras sit amet nibh libero</a>
|
||||
<a href="#" class="list-group-item list-group-item-warning">Porta ac consectetur ac</a>
|
||||
<a href="#" class="list-group-item list-group-item-danger">Vestibulum at eros</a>
|
||||
<a href="#" class="list-group-item list-group-item-info">Cras sit amet nibh libero</a>
|
||||
</div>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
+13
-13
@@ -1312,6 +1312,12 @@ For example, <code><section></code> should be wrapped as inline.
|
||||
</td>
|
||||
<td>Indicates a successful or positive action</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>.info</code>
|
||||
</td>
|
||||
<td>Indicates a neutral informative change or action</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>.warning</code>
|
||||
@@ -1324,12 +1330,6 @@ For example, <code><section></code> should be wrapped as inline.
|
||||
</td>
|
||||
<td>Indicates a dangerous or potentially negative action</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>.info</code>
|
||||
</td>
|
||||
<td>Indicates a neutral informative change or action</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1368,7 +1368,7 @@ For example, <code><section></code> should be wrapped as inline.
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="warning">
|
||||
<tr class="info">
|
||||
<td>5</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
@@ -1380,7 +1380,7 @@ For example, <code><section></code> should be wrapped as inline.
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="danger">
|
||||
<tr class="warning">
|
||||
<td>7</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
@@ -1392,7 +1392,7 @@ For example, <code><section></code> should be wrapped as inline.
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="info">
|
||||
<tr class="danger">
|
||||
<td>9</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
@@ -2854,17 +2854,17 @@ For example, <code><section></code> should be wrapped as inline.
|
||||
<div class="color-swatches">
|
||||
<div class="color-swatch brand-primary"></div>
|
||||
<div class="color-swatch brand-success"></div>
|
||||
<div class="color-swatch brand-info"></div>
|
||||
<div class="color-swatch brand-warning"></div>
|
||||
<div class="color-swatch brand-danger"></div>
|
||||
<div class="color-swatch brand-info"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% highlight css %}
|
||||
@brand-primary: #428bca;
|
||||
@brand-success: #5cb85c;
|
||||
@brand-info: #5bc0de;
|
||||
@brand-warning: #f0ad4e;
|
||||
@brand-danger: #d9534f;
|
||||
@brand-info: #5bc0de;
|
||||
{% endhighlight %}
|
||||
|
||||
<p>Use any of these color variables as they are or reassign them to more meaningful variables for your project.</p>
|
||||
@@ -2989,7 +2989,7 @@ a {
|
||||
{% endhighlight %}
|
||||
|
||||
<h3 id="less-mixins-rounded-corners">Rounded corners</h3>
|
||||
<p>Today all modern browsers support the non-prefixed <code>border-radius</code> property. As such, there is no <code>.border-radius()</code> mixin, but Preboot does include shortcuts for quickly rounding two corners on a particular side of an object.</p>
|
||||
<p>Today all modern browsers support the non-prefixed <code>border-radius</code> property. As such, there is no <code>.border-radius()</code> mixin, but Bootstrap does include shortcuts for quickly rounding two corners on a particular side of an object.</p>
|
||||
{% highlight css %}
|
||||
.border-top-radius(@radius) {
|
||||
border-top-right-radius: @radius;
|
||||
@@ -3284,7 +3284,7 @@ a {
|
||||
{% endhighlight %}
|
||||
|
||||
<h3 id="less-mixins-retina-images">Retina images</h3>
|
||||
<p>Specify two image paths and the @1x image dimensions, and Preboot will provide an @2x media query. <strong>If you have many images to serve, consider writing your retina image CSS manually in a single media query.</strong></p>
|
||||
<p>Specify two image paths and the @1x image dimensions, and Bootstrap will provide an @2x media query. <strong>If you have many images to serve, consider writing your retina image CSS manually in a single media query.</strong></p>
|
||||
{% highlight css %}
|
||||
.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
|
||||
background-image: url("@{file-1x}");
|
||||
|
||||
+1
-1364
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
// 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
|
||||
each subsection in section.subsections
|
||||
if subsection.heading
|
||||
h3(id=subsection.id)= subsection.heading
|
||||
div.row
|
||||
each variable in subsection.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.
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
@@ -53,7 +53,7 @@
|
||||
|
||||
<div class="blog-post">
|
||||
<h2 class="blog-post-title">Sample blog post</h2>
|
||||
<p class="blog-post-meta">December 1, 2013 by <a href="#">Mark</a></p>
|
||||
<p class="blog-post-meta">January 1, 2014 by <a href="#">Mark</a></p>
|
||||
|
||||
<p>This blog post shows a few different types of content that's supported and styled with Bootstrap. Basic typography, images, and code are all supported.</p>
|
||||
<hr>
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
<div class="blog-post">
|
||||
<h2 class="blog-post-title">Another blog post</h2>
|
||||
<p class="blog-post-meta">November 23, 2013 by <a href="#">Jacob</a></p>
|
||||
<p class="blog-post-meta">December 23, 2013 by <a href="#">Jacob</a></p>
|
||||
|
||||
<p>Cum sociis natoque penatibus et magnis <a href="#">dis parturient montes</a>, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
|
||||
<blockquote>
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
<div class="blog-post">
|
||||
<h2 class="blog-post-title">New feature</h2>
|
||||
<p class="blog-post-meta">November 14, 2013 by <a href="#">Chris</a></p>
|
||||
<p class="blog-post-meta">December 14, 2013 by <a href="#">Chris</a></p>
|
||||
|
||||
<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
|
||||
<ul>
|
||||
@@ -125,6 +125,7 @@
|
||||
<div class="sidebar-module">
|
||||
<h4>Archives</h4>
|
||||
<ol class="list-unstyled">
|
||||
<li><a href="#">January 2014</a></li>
|
||||
<li><a href="#">December 2013</a></li>
|
||||
<li><a href="#">November 2013</a></li>
|
||||
<li><a href="#">October 2013</a></li>
|
||||
@@ -136,7 +137,6 @@
|
||||
<li><a href="#">April 2013</a></li>
|
||||
<li><a href="#">March 2013</a></li>
|
||||
<li><a href="#">February 2013</a></li>
|
||||
<li><a href="#">January 2013</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="sidebar-module">
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p class="pull-right"><a href="#">Back to top</a></p>
|
||||
<p>© 2013 Company, Inc. · <a href="#">Privacy</a> · <a href="#">Terms</a></p>
|
||||
<p>© 2014 Company, Inc. · <a href="#">Privacy</a> · <a href="#">Terms</a></p>
|
||||
</footer>
|
||||
|
||||
</div><!-- /.container -->
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>© Company 2013</p>
|
||||
<p>© Company 2014</p>
|
||||
</div>
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>© Company 2013</p>
|
||||
<p>© Company 2014</p>
|
||||
</footer>
|
||||
</div> <!-- /container -->
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<!-- Site footer -->
|
||||
<div class="footer">
|
||||
<p>© Company 2013</p>
|
||||
<p>© Company 2014</p>
|
||||
</div>
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>© Company 2013</p>
|
||||
<p>© Company 2014</p>
|
||||
</footer>
|
||||
|
||||
</div><!--/.container-->
|
||||
|
||||
@@ -446,6 +446,10 @@ bootstrap/
|
||||
<td><code>.input-large</code></td>
|
||||
<td><code>.input-lg</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>.input-block-level</code></td>
|
||||
<td><code>.form-control</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>.control-group</code></td>
|
||||
<td><code>.form-group</code></td>
|
||||
@@ -673,6 +677,11 @@ bootstrap/
|
||||
<td><code>.control-group.info</code></td>
|
||||
<td class="text-muted">N/A</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Block level from input</td>
|
||||
<td><code>.input-block-level</code></td>
|
||||
<td>No direct equivalent, but <a href="../css/#forms-controls">forms controls</a> are similar.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fluid container</td>
|
||||
<td><code>.container-fluid</code></td>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/* jshint node: true */
|
||||
|
||||
var fs = require('fs')
|
||||
|
||||
module.exports = function generateGlyphiconsData() {
|
||||
// Pass encoding, utf8, so `readFileSync` will return a string instead of a
|
||||
// buffer
|
||||
var glyphiconsFile = fs.readFileSync('less/glyphicons.less', 'utf8')
|
||||
var glpyhiconsLines = glyphiconsFile.split('\n')
|
||||
|
||||
// Use any line that starts with ".glyphicon-" and capture the class name
|
||||
var iconClassName = /^\.(glyphicon-[^\s]+)/
|
||||
var glyphiconsData = '# This file is generated via Grunt task. **Do not edit directly.** \n' +
|
||||
'# See the \'build-glyphicons-data\' task in Gruntfile.js.\n\n';
|
||||
for (var i = 0, len = glpyhiconsLines.length; i < len; i++) {
|
||||
var match = glpyhiconsLines[i].match(iconClassName)
|
||||
|
||||
if (match != null) {
|
||||
glyphiconsData += '- ' + match[1] + '\n'
|
||||
}
|
||||
}
|
||||
|
||||
// Create the `_data` directory if it doesn't already exist
|
||||
if (!fs.existsSync('docs/_data')) fs.mkdirSync('docs/_data')
|
||||
|
||||
fs.writeFileSync('docs/_data/glyphicons.yml', glyphiconsData)
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
/* 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 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;
|
||||
@@ -0,0 +1,22 @@
|
||||
/* jshint node: true */
|
||||
|
||||
var btoa = require('btoa') // jshint ignore:line
|
||||
var fs = require('fs')
|
||||
|
||||
function getFiles(type) {
|
||||
var files = {}
|
||||
fs.readdirSync(type)
|
||||
.filter(function (path) {
|
||||
return type == 'fonts' ? true : new RegExp('\\.' + type + '$').test(path)
|
||||
})
|
||||
.forEach(function (path) {
|
||||
var fullPath = type + '/' + path
|
||||
return files[path] = (type == 'fonts' ? btoa(fs.readFileSync(fullPath)) : fs.readFileSync(fullPath, 'utf8'))
|
||||
})
|
||||
return 'var __' + type + ' = ' + JSON.stringify(files) + '\n'
|
||||
}
|
||||
|
||||
module.exports = function generateRawFilesJs() {
|
||||
var files = getFiles('js') + getFiles('less') + getFiles('fonts')
|
||||
fs.writeFileSync('docs/assets/js/raw-files.js', files)
|
||||
}
|
||||
Reference in New Issue
Block a user