-
Notifications
You must be signed in to change notification settings - Fork 2
/
builder.js
137 lines (122 loc) · 4.83 KB
/
builder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
'use strict';
/**
* This module is used to load the base KSS builder class needed by this builder
* and to define any custom CLI options or extend any base class methods.
*
* Note: this module is optional. If a builder does not export a KssBuilderBase
* sub-class as a module, then kss-node will assume the builder wants to use
* the KssBuilderBaseHandlebars class.
*
* This file's name should follow standard node.js require() conventions. It
* should either be named index.js or have its name set in the "main" property
* of the builder's package.json. See
* http://nodejs.org/api/modules.html#modules_folders_as_modules
*
* @module kss/builder/handlebars
*/
// We want to extend kss-node's Handlebars builder so we can add options that
// are used in our templates.
let KssBuilderBaseHandlebars;
try {
// In order for a builder to be "kss clone"-able, it must use the
// require('kss/builder/path') syntax.
KssBuilderBaseHandlebars = require('kss/builder/base/handlebars');
} catch (e) {
// The above require() line will always work.
//
// Unless you are one of the developers of kss-node and are using a git clone
// of kss-node where this code will not be inside a "node_modules/kss" folder
// which would allow node.js to find it with require('kss/anything'), forcing
// you to write a long-winded comment and catch the error and try again using
// a relative path.
KssBuilderBaseHandlebars = require('../base/handlebars');
}
/**
* A kss-node builder that takes input files and builds a style guide using
* Handlebars templates.
*/
class KssBuilderHandlebars extends KssBuilderBaseHandlebars {
/**
* Create a builder object.
*/
constructor() {
// First call the constructor of KssBuilderBaseHandlebars.
super();
// Then tell kss which Yargs-like options this builder adds.
this.addOptionDefinitions({
title: {
group: 'Style guide:',
string: true,
multiple: false,
describe: 'Title of the style guide',
default: 'KSS Style Guide'
}
});
}
/**
* Allow the builder to preform pre-build tasks or modify the KssStyleGuide
* object.
*
* The method can be set by any KssBuilderBase sub-class to do any custom
* tasks after the KssStyleGuide object is created and before the HTML style
* guide is built.
*
* The builder could also take this opportunity to do tasks like special
* handling of "custom" properties or running Sass or Bower tasks.
*
* The parent class sets up access for this builder to an object containing
* the options of the requested build (as `this.options`), and the global
* Handlebars object (as `this.Handlebars`).
*
* @param {KssStyleGuide} styleGuide The KSS style guide in object format.
* @returns {Promise.<KssStyleGuide>} A `Promise` object resolving to a
* `KssStyleGuide` object.
*/
prepare(styleGuide) {
// First call the prepare() of the parent KssBuilderBaseHandlebars class.
// Since it returns a Promise, we do our prep work in a then().
return super.prepare(styleGuide).then(styleGuide => {
// Load this builder's extra Handlebars helpers.
// Allow a builder user to override the {{section [reference]}} helper
// with the --extend setting. Since a user's handlebars helpers are
// loaded first, we need to check if this helper already exists.
if (!this.Handlebars.helpers['section']) {
/**
* Returns a single section, found by its reference
* @param {String} reference The reference to search for.
*/
this.Handlebars.registerHelper('section', function(reference, options) {
let section = options.data.root.styleGuide.sections(reference);
return section.toJSON ? options.fn(section.toJSON()) : options.inverse('');
});
}
// Allow a builder user to override the {{eachSection [query]}} helper
// with the --extend setting.
if (!this.Handlebars.helpers['eachSection']) {
/**
* Loop over a section query. If a number is supplied, will convert into
* a query for all children and descendants of that reference.
* @param {Mixed} query The section query
*/
this.Handlebars.registerHelper('eachSection', function(query, options) {
let styleGuide = options.data.root.styleGuide;
if (!query.match(/\bx\b|\*/g)) {
query = query + '.*';
}
let sections = styleGuide.sections(query);
if (!sections.length) {
return options.inverse('');
}
let l = sections.length;
let buffer = '';
for (let i = 0; i < l; i += 1) {
buffer += options.fn(sections[i].toJSON());
}
return buffer;
});
}
return Promise.resolve(styleGuide);
});
}
}
module.exports = KssBuilderHandlebars;