1 | var extend = require('deep-extend'); |
||
2 | var curl = require('curl'); // 0.1.4 |
||
3 | var queryString = require('query-string'); // 4.3.4 |
||
4 | var fm = require('front-matter'); |
||
5 | var fs = require('fs-extra'); |
||
6 | var glob = require('glob'); |
||
7 | var path = require('path'); |
||
8 | var chalk = require('chalk'); |
||
9 | var through = require('through2'); |
||
10 | var slash = require('slash'); |
||
11 | var jsonfile = require('jsonfile'); |
||
12 | var Panini = require('panini'); |
||
13 | var superCollider = require('supercollider'); |
||
14 | var marked = require('marked'); |
||
15 | |||
16 | // import Foundation Docs handlebar helpers |
||
17 | require('./vendor/handlebars'); |
||
18 | |||
19 | //import Patternlibrary classes |
||
20 | var PatternlibraryConfig = require('./patternlibrary/config'); |
||
21 | |||
22 | var PatternlibraryFileStream = require('./patternlibrary/filestream'); |
||
23 | var PatternlibraryDocParser = require('./patternlibrary/doc-parser'); |
||
24 | var PatternlibraryDocRenderer = require('./patternlibrary/doc-renderer'); |
||
25 | |||
26 | var PatternlibraryMiddleware = require('./patternlibrary/middleware'); |
||
27 | |||
28 | |||
29 | /** @var string patternlibrary version */ |
||
30 | const PATTERNLIBRARY_VERSION = require('../package.json').version; // '0.0.1'; |
||
31 | |||
32 | /** |
||
33 | * Patternlibrary Generator |
||
34 | * |
||
35 | * @package Patternlibrary |
||
36 | * @namespace Patternlibrary |
||
37 | * @author Björn Bartels <[email protected]> |
||
38 | */ |
||
39 | class Patternlibrary { |
||
40 | |||
41 | /** |
||
42 | * Initializes an instance of Patternlibrary. |
||
43 | * @constructor |
||
44 | * @param {object} options - Configuration options to use. |
||
45 | */ |
||
46 | constructor ( options ) { |
||
47 | |||
48 | /** @var string */ |
||
49 | this.patternlibrary_version = PATTERNLIBRARY_VERSION; |
||
50 | |||
51 | /** @var object */ |
||
52 | this.options = extend(this.defaults, options); |
||
53 | |||
54 | if (!this.options.patterns) { |
||
55 | throw new Error('Patternlibrary error: you must specify the directories for patterns.'); |
||
56 | } |
||
57 | |||
58 | if (!this.options.root) { |
||
59 | throw new Error('Patternlibrary error: you must specify a root directory.') |
||
60 | } |
||
61 | if (!this.options.layouts) { |
||
62 | throw new Error('Patternlibrary error: you must specify a layouts directory.') |
||
63 | } |
||
64 | if (!this.options.partials) { |
||
65 | throw new Error('Patternlibrary error: you must specify a partials directory.') |
||
66 | } |
||
67 | |||
68 | /** @var object */ |
||
69 | this.layouts = {}; |
||
70 | |||
71 | /** @var object */ |
||
72 | this.data = {}; |
||
73 | |||
74 | this._init(); |
||
75 | |||
76 | } |
||
77 | |||
78 | /** |
||
79 | * initialize pattern-library object |
||
80 | */ |
||
81 | _init ( ) { |
||
82 | |||
83 | this.log('setup pattern-library'); |
||
84 | |||
85 | /** @var PatternlibraryDocParser */ |
||
86 | this.DocParser = null; |
||
87 | |||
88 | /** @var PatternlibraryRenderer */ |
||
89 | this.DocRenderer = null; |
||
90 | |||
91 | /** @var PatternlibraryMiddleware */ |
||
92 | this.Middleware = null; |
||
93 | |||
94 | /** @var PatternlibraryFileStream */ |
||
95 | this.FileStream = null; |
||
96 | |||
97 | |||
98 | /** @var PatternlibraryConfig */ |
||
99 | this.Config = new PatternlibraryConfig(this.options); |
||
100 | |||
101 | |||
102 | this._initDestination(); |
||
103 | |||
104 | this._initPanini(); |
||
105 | |||
106 | /** @var Handlebars */ |
||
107 | this.Handlebars = this.Panini.Handlebars; |
||
108 | |||
109 | this._initSupercollider(); |
||
110 | |||
111 | } |
||
112 | |||
113 | |||
114 | |||
115 | |||
116 | /** |
||
117 | * retrieve middleware instance |
||
118 | * |
||
119 | * @param boolean reset force to initialize new middleware instance |
||
120 | * @return PatternlibraryMiddleware |
||
121 | */ |
||
122 | getMiddleware ( reset ) { |
||
123 | |||
124 | if ( reset || (this.Middleware === null) ) { |
||
125 | this.log('initialize middleware hook'); |
||
126 | this.Middleware = new PatternlibraryMiddleware( |
||
127 | this.Config.get('plugins').middleware |
||
128 | ); |
||
129 | this.Middleware.bind(this); |
||
130 | } |
||
131 | return (this.Middleware); |
||
132 | |||
133 | } |
||
134 | |||
135 | |||
136 | /** |
||
137 | * reset middleware instance |
||
138 | * |
||
139 | * @return Patternlibrary |
||
140 | */ |
||
141 | resetMiddleware ( ) { |
||
142 | |||
143 | this.Middleware = null; |
||
144 | this.getMiddleware( true ); |
||
145 | return (this); |
||
146 | |||
147 | } |
||
148 | |||
149 | |||
150 | |||
151 | /** |
||
152 | * retrieve (vinyl/gulp) file-stream instance |
||
153 | * |
||
154 | * @param boolean reset force to initialize new file-stream instance |
||
155 | * @return PatternlibraryFileStream |
||
156 | */ |
||
157 | getFileStream ( reset ) { |
||
158 | |||
159 | if ( reset || (this.FileStream === null) ) { |
||
160 | this.log('initialize file-stream hook'); |
||
161 | this.FileStream = new PatternlibraryFileStream( |
||
162 | this.Config.get('plugins').filestream |
||
163 | ); |
||
164 | this.FileStream.bind(this); |
||
165 | } |
||
166 | return (this.FileStream); |
||
167 | |||
168 | } |
||
169 | |||
170 | |||
171 | /** |
||
172 | * reset file-stream instance |
||
173 | * |
||
174 | * @return Patternlibrary |
||
175 | */ |
||
176 | resetFileStream ( ) { |
||
177 | |||
178 | this.FileStream = null; |
||
179 | this.getFileStream( true ); |
||
180 | return (this); |
||
181 | |||
182 | } |
||
183 | |||
184 | |||
185 | |||
186 | /** |
||
187 | * retrieve doc-parser instance |
||
188 | * |
||
189 | * @param boolean reset force to initialize new file-stream instance |
||
190 | * @return PatternlibraryDocParser |
||
191 | */ |
||
192 | getDocParser ( reset ) { |
||
193 | |||
194 | if ( reset || (this.DocParser === null) ) { |
||
195 | this.log('initialize documentaion info parser'); |
||
196 | this.DocParser = new PatternlibraryDocParser( |
||
197 | this.Config.get('plugins').docparser |
||
198 | ); |
||
199 | this.DocParser.bind(this); |
||
200 | } |
||
201 | return (this.DocParser); |
||
202 | |||
203 | } |
||
204 | |||
205 | |||
206 | /** |
||
207 | * reset doc-parser instance |
||
208 | * |
||
209 | * @return Patternlibrary |
||
210 | */ |
||
211 | resetDocParser ( ) { |
||
212 | |||
213 | this.DocParser = null; |
||
214 | this.getDocParser( true ); |
||
215 | return (this); |
||
216 | |||
217 | } |
||
218 | |||
219 | |||
220 | |||
221 | /** |
||
222 | * retrieve doc-renderer instance |
||
223 | * |
||
224 | * @param boolean reset force to initialize new file-stream instance |
||
225 | * @return PatternlibraryDocRenderer |
||
226 | */ |
||
227 | getDocRenderer ( reset ) { |
||
228 | |||
229 | if ( reset || (this.DocRenderer === null) ) { |
||
230 | this.log('initialize documentation pages generator'); |
||
231 | this.DocRenderer = new PatternlibraryDocRenderer( |
||
232 | this.Config.get('plugins').docrenderer |
||
233 | ); |
||
234 | this.DocRenderer.bind(this); |
||
235 | } |
||
236 | return (this.DocRenderer); |
||
237 | |||
238 | } |
||
239 | |||
240 | |||
241 | /** |
||
242 | * reset doc-renderer instance |
||
243 | * |
||
244 | * @return Patternlibrary |
||
245 | */ |
||
246 | resetDocRenderer ( ) { |
||
247 | |||
248 | this.DocRenderer = null; |
||
249 | this.getDocRenderer( true ); |
||
250 | return (this); |
||
251 | |||
252 | } |
||
253 | |||
254 | |||
255 | |||
256 | |||
257 | |||
258 | /** |
||
259 | * generate the whole Patternlibrary data, pages and stuff... |
||
260 | * |
||
261 | * @return Patternlibrary |
||
262 | */ |
||
263 | run ( ) { |
||
264 | |||
265 | try { |
||
266 | // ... do stuff ^^ |
||
267 | |||
268 | // -> parse patterns |
||
269 | this.getDocParser().parse(); |
||
270 | |||
271 | // -> generate docs |
||
272 | this.getDocRenderer().renderDocs(); |
||
273 | |||
274 | // -> write data files |
||
275 | |||
276 | // -> generate index pages |
||
277 | |||
278 | // ...?! |
||
279 | } catch (err) { |
||
280 | this.warn(err); |
||
281 | this.debug(err); |
||
282 | } |
||
283 | return (this); |
||
284 | } |
||
285 | |||
286 | |||
287 | |||
288 | |||
289 | |||
290 | |||
291 | /** |
||
292 | * output warn message to console |
||
293 | * |
||
294 | * @return Patternlibrary |
||
295 | */ |
||
296 | warn ( msg, err ) { |
||
297 | var strings = { |
||
298 | time : chalk.yellow( (new Date()).toLocaleTimeString() ), |
||
299 | message : chalk.yellow( msg ) |
||
300 | }; |
||
301 | console.log( |
||
302 | '['+(strings.time)+'] Patternlibrary: ' + (strings.message) // + "\n" |
||
303 | ); |
||
304 | if (err) this.debug(err); |
||
305 | return (this); |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * output log message to console if verbose option is set to `true` |
||
310 | * |
||
311 | * @return Patternlibrary |
||
312 | */ |
||
313 | log ( msg ) { |
||
314 | if (this.options.verbose === true) { |
||
315 | var strings = { |
||
316 | time : chalk.grey( (new Date()).toLocaleTimeString() ), |
||
317 | message : chalk.cyan( msg ) |
||
318 | }; |
||
319 | console.log( |
||
320 | '['+(strings.time)+'] Patternlibrary: ' + (strings.message) // + "\n" |
||
321 | ); |
||
322 | } |
||
323 | return (this); |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * output debug info to console if verbose and debug options are set to `true` |
||
328 | * |
||
329 | * @return Patternlibrary |
||
330 | */ |
||
331 | debug ( ) { |
||
332 | if (this.options.verbose === true) { |
||
333 | var strings = { |
||
334 | time : chalk.grey( (new Date()).toLocaleTimeString() ), |
||
335 | title : chalk.yellow( 'Patternlibrary Debug:' ) |
||
336 | }; |
||
337 | console.log( |
||
338 | '['+(strings.time)+'] '+(strings.title)+' '+"\n", |
||
339 | chalk.yellow(' >>> =================================================== <<< ') // +"\n" |
||
340 | ); |
||
341 | for (var arg of arguments) { |
||
342 | if (arg) console.log(arg); |
||
343 | } |
||
344 | console.log( |
||
345 | chalk.yellow(' >>> =================================================== <<< ') // +"\n" |
||
346 | ); |
||
347 | } |
||
348 | return (this); |
||
349 | } |
||
350 | |||
351 | |||
352 | /** |
||
353 | * increase usage on a given pattern by a given consumer |
||
354 | * |
||
355 | * @param string patternname |
||
356 | * @param object consumer |
||
357 | */ |
||
358 | patternUsage ( patternname, consumer ) { |
||
359 | |||
360 | if ( typeof this.data[patternname] != 'undefined') { |
||
361 | if ( typeof this.data[patternname].usage == 'undefined') { |
||
362 | this.data[patternname].usage = { |
||
363 | count: 0, |
||
364 | consumers: {} |
||
365 | }; |
||
366 | |||
367 | // increase counter |
||
368 | this.data[patternname].usage.count = this.data[patternname].usage.count + 1; |
||
369 | |||
370 | if (consumer && consumer.pattern) { |
||
371 | // add consumer, increase consumer counter |
||
372 | var consumerName = consumer.pattern.name; |
||
373 | if (!this.data[patternname].usage.consumers[consumerName]) { |
||
374 | this.data[patternname].usage.consumers[consumerName] = 1; |
||
375 | } else { |
||
376 | this.data[patternname].usage.consumers[consumerName] = |
||
377 | this.data[patternname].usage.consumers[consumerName] + 1; |
||
378 | } |
||
379 | } |
||
380 | } |
||
381 | } |
||
382 | |||
383 | } |
||
384 | |||
385 | /** |
||
386 | * updates the pattern-library JSON data-file |
||
387 | */ |
||
388 | updateDataFile ( ) { |
||
389 | var patterns = this.getPatterns(); |
||
390 | var categories = this.getCategories(); |
||
391 | var tree = this.Supercollider.tree; |
||
392 | |||
393 | // complete library data |
||
394 | var file = this.options.dest+'/patternlibrary.json'; |
||
395 | jsonfile.writeFileSync(file, { |
||
396 | patterns : patterns, |
||
397 | categories: categories, |
||
398 | tree : tree, |
||
399 | }, {spaces: 4, flag: 'w'}); |
||
400 | |||
401 | // search data |
||
402 | this.Supercollider.options.pageRoot = this.Config.get('root'); |
||
403 | this.Supercollider.buildSearch(this.options.dest+'/search.json', function() { |
||
404 | // file written... |
||
405 | }); |
||
406 | |||
407 | |||
408 | // categorie data |
||
409 | var file = this.options.dest+'/patterns.json'; |
||
410 | jsonfile.writeFileSync(file, patterns, {spaces: 4, flag: 'w'}); |
||
411 | |||
412 | // categorie data |
||
413 | var file = this.options.dest+'/categories.json'; |
||
414 | jsonfile.writeFileSync(file, categories, {spaces: 4, flag: 'w'}); |
||
415 | |||
416 | // categorie data |
||
417 | var file = this.options.dest+'/tree.json'; |
||
418 | jsonfile.writeFileSync(file, tree, {spaces: 4, flag: 'w'}); |
||
419 | |||
420 | } |
||
421 | |||
422 | |||
423 | |||
424 | /** |
||
425 | * refresh/reload pattern-library data |
||
426 | */ |
||
427 | refresh ( ) { |
||
428 | |||
429 | return this.run(); |
||
430 | |||
431 | } |
||
432 | |||
433 | |||
434 | |||
435 | /** |
||
436 | * retrieve current pattern-library data |
||
437 | */ |
||
438 | getPatterns ( type_or_category ) { |
||
439 | if (type_or_category) { |
||
440 | var patterns = {}; |
||
441 | for (var patternkey in this.data) { |
||
442 | var pattern = this.data[patternkey]; |
||
443 | if ( |
||
444 | ( String(patternkey).indexOf(type_or_category) != -1 ) || |
||
445 | ( pattern.pattern.categories && ( pattern.pattern.categories.indexOf(type_or_category) != -1 ) ) |
||
446 | ) { |
||
447 | patterns[patternkey] = pattern; |
||
448 | } |
||
449 | } |
||
450 | return patterns; |
||
451 | } |
||
452 | |||
453 | return this.data; |
||
454 | |||
455 | } |
||
456 | |||
457 | |||
458 | |||
459 | |||
460 | /** |
||
461 | * retrieve current list of pattern categories |
||
462 | */ |
||
463 | getCategories ( ) { |
||
464 | var patterns = this.getPatterns(); |
||
465 | |||
466 | function isCatInList ( arr, obj, idx ) { |
||
467 | for (var i in arr) { |
||
468 | if ( arr[i][idx] && obj[idx] && (arr[i][idx] == obj[idx]) ) { |
||
469 | return (true); |
||
470 | } |
||
471 | } |
||
472 | return false; |
||
473 | } |
||
474 | function sortByKey(array, key) { |
||
475 | return array.sort(function(a, b) { |
||
476 | var x = a[key]; var y = b[key]; |
||
477 | return ((x < y) ? -1 : ((x > y) ? 1 : 0)); |
||
478 | }); |
||
479 | } |
||
480 | |||
481 | // categories data |
||
482 | var categories = []; |
||
483 | for (var pattern in patterns) { |
||
484 | var patterncategories = |
||
485 | !Array.isArray(patterns[pattern].pattern.categories) ? |
||
486 | [patterns[pattern].pattern.categories] : |
||
487 | patterns[pattern].pattern.categories; |
||
488 | for (var i in patterncategories) { |
||
489 | var cat = { |
||
490 | name: String(patterncategories[i]), |
||
491 | slug: String(patterncategories[i]) |
||
492 | }; |
||
493 | if ( !isCatInList( categories, cat, 'slug' ) ) { |
||
494 | var catPatterns = this.getPatterns(cat.slug); |
||
495 | cat.patterns = catPatterns; |
||
496 | cat.patternsCount = ((b) => { |
||
497 | var c = 0; for (var a in b) { c++; }; return c; |
||
498 | })(catPatterns); |
||
499 | categories.push(cat); |
||
500 | } |
||
501 | } |
||
502 | } |
||
503 | |||
504 | categories = sortByKey(categories, 'slug'); |
||
505 | return (categories); |
||
506 | } |
||
507 | |||
508 | |||
509 | |||
510 | |||
511 | |||
512 | // |
||
513 | // helpers |
||
514 | // |
||
515 | |||
516 | /** |
||
517 | * recursivly read a list of files from a given directory |
||
518 | * according to a given file-path pattern |
||
519 | * |
||
520 | * scans relative to project root |
||
521 | * |
||
522 | * @param string|[string] dir |
||
523 | * @param string pattern |
||
524 | * @return [string] |
||
525 | */ |
||
526 | _readdir ( dir, pattern ) { |
||
527 | |||
528 | var files = []; |
||
529 | |||
530 | dir = !Array.isArray(dir) ? [dir] : dir; |
||
531 | |||
532 | for (var i in dir) { |
||
533 | files = files.concat( |
||
534 | glob.sync( path.join( process.cwd(), dir[i], pattern ) ) |
||
535 | ); |
||
536 | } |
||
537 | |||
538 | return files; |
||
539 | |||
540 | } |
||
541 | |||
542 | /** |
||
543 | * initialize destination directory |
||
544 | */ |
||
545 | _initDestination ( ) { |
||
546 | try { |
||
547 | fs.ensureDirSync(this.options.dest); |
||
548 | } catch (err) { |
||
549 | if (err.code !== 'EEXIST') throw err |
||
550 | } |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * initialize 'Panini' object |
||
555 | */ |
||
556 | _initPanini ( ) { |
||
557 | |||
558 | if (!this.Panini) { |
||
559 | |||
560 | let paniniOptions = {}; |
||
561 | |||
562 | paniniOptions.root = this.options.root; |
||
563 | paniniOptions.layouts = this.options.layouts; |
||
564 | paniniOptions.partials = this.options.partials; |
||
565 | paniniOptions.data = this.options.data || null; |
||
566 | paniniOptions.helpers = this.options.helpers || null; |
||
567 | |||
568 | this.Panini = new Panini.Panini(paniniOptions); |
||
569 | this.Panini.loadBuiltinHelpers(); |
||
570 | |||
571 | // import Foundation Docs handlebar helpers |
||
572 | this.Panini.Handlebars = require('./vendor/handlebars'); |
||
573 | |||
574 | this._registerPatternHelpers(); |
||
575 | |||
576 | |||
577 | // detect layouts, pages, data, etc... |
||
578 | this.Panini.refresh(); |
||
579 | |||
580 | } |
||
581 | } |
||
582 | |||
583 | /** |
||
584 | * register new Panini/Handlebars helpers |
||
585 | */ |
||
586 | _registerPatternHelpers ( ) { |
||
587 | |||
588 | // Capitalizes the first letter of a string |
||
589 | this.Panini.Handlebars.registerHelper('toUpper', function(str) { |
||
590 | return str[0].toUpperCase() + str.slice(1); |
||
591 | }); |
||
592 | |||
593 | // Formats a mixin using a SassDoc mixin object to look like this: |
||
594 | // @include mixinName($param, $param) { } |
||
595 | this.Panini.Handlebars.registerHelper('writeMixin', function(mixin) { |
||
596 | var name = mixin['context']['name']; |
||
597 | var params = mixin['parameter']; |
||
598 | |||
599 | var str = '@include '; |
||
600 | str += name + '('; |
||
601 | for (var i in params) { |
||
602 | str += '$' + params[i]['name'] + ', '; |
||
603 | } |
||
604 | if (params) str = str.slice(0, -2); |
||
605 | str += ') { }'; |
||
606 | |||
607 | return str; |
||
608 | }); |
||
609 | |||
610 | // Formats a function using a SassDoc function object to look like this: |
||
611 | // function($param, $param) |
||
612 | this.Panini.Handlebars.registerHelper('writeFunction', function(func) { |
||
613 | var name = func['context']['name']; |
||
614 | var params = func['parameter']; |
||
615 | |||
616 | var str = ''; |
||
617 | str += name + '('; |
||
618 | for (var i in params) { |
||
619 | str += '$' + params[i]['name'] + ', '; |
||
620 | } |
||
621 | if (params) str = str.slice(0, -2); |
||
622 | str += ')'; |
||
623 | |||
624 | return str; |
||
625 | }); |
||
626 | |||
627 | // Converts a Markdown string to HTML |
||
628 | this.Panini.Handlebars.registerHelper('md', function(text) { |
||
629 | return marked(text); |
||
630 | }); |
||
631 | |||
632 | var relPath = path.relative( process.cwd(), path.join(__dirname, '') ); |
||
633 | // register 'local' helper stuff |
||
634 | this.Panini.loadLayouts([path.join(relPath, '../layouts/'), '../layouts/','layouts', |
||
635 | (this.options.layouts || 'layouts') |
||
636 | ]); |
||
637 | this.Panini.loadHelpers([path.join(relPath, '../helpers/'), '../helpers/', 'helpers', |
||
638 | (this.options.helpers || 'helpers') |
||
639 | ]); |
||
640 | |||
641 | // special partial helper |
||
642 | this.Panini.Handlebars.registerHelper('PL', require( path.join('../helpers/patternlibrary') )); |
||
643 | } |
||
644 | |||
645 | /** |
||
646 | * initialize 'Panini' object |
||
647 | */ |
||
648 | _initSupercollider ( ) { |
||
649 | |||
650 | if (!this.Supercollider) { |
||
651 | var $this = this; |
||
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
652 | |||
653 | this.Supercollider = new require('supercollider'); |
||
654 | this.Supercollider.$PL = this; // Patternlibrary reference to Supercollider |
||
655 | this.Supercollider.init = require('./supercollider/supercollider_init_path_awareness'); |
||
656 | this.Supercollider.parse = require('./supercollider/supercollider_parse_extended'); |
||
657 | this.Supercollider |
||
658 | //.adapter('sass') |
||
659 | .adapter('js') |
||
660 | ; |
||
661 | this.Supercollider.adapter('sass', require('./supercollider/adapters/sass.js')); |
||
662 | this.Supercollider.adapter('source', require('./supercollider/adapters/sourcecode.js')); |
||
663 | this.Supercollider.adapter('example', require('./supercollider/adapters/sourceexample.js')); |
||
664 | this.Supercollider.adapter('specs', require('./supercollider/adapters/patternspecs.js')); |
||
665 | this.Supercollider.adapter('changelog', require('./supercollider/adapters/changelog.js')); |
||
666 | this.Supercollider.adapter('gitinfo', require('./supercollider/adapters/gitinfo.js')); |
||
667 | this.Supercollider.adapter('tests', require('./supercollider/adapters/testresults.js')); |
||
668 | |||
669 | |||
670 | } |
||
671 | } |
||
672 | |||
673 | /** |
||
674 | * determine the relative path between 2 given paths |
||
675 | * |
||
676 | * @param string page |
||
677 | * @param string root |
||
678 | * @return string |
||
679 | */ |
||
680 | _relativeRoot ( page, root ) { |
||
681 | var pagePath = path.dirname(page); |
||
682 | var rootPath = path.join(process.cwd(), root); |
||
683 | |||
684 | var relativePath = path.relative(pagePath, rootPath); |
||
685 | |||
686 | if (relativePath.length > 0) { |
||
687 | relativePath += '/'; |
||
688 | } |
||
689 | |||
690 | // On Windows, paths are separated with a "\" |
||
691 | // However, web browsers use "/" no matter the platform |
||
692 | return slash(relativePath); |
||
693 | } |
||
694 | } |
||
695 | |||
696 | /** |
||
697 | * pattern-library default options |
||
698 | */ |
||
699 | Patternlibrary.prototype.defaults = require('./config/default.js'); |
||
700 | |||
701 | /** |
||
702 | * export pattern-library object |
||
703 | */ |
||
704 | module.exports = Patternlibrary; |