Source: apc-static/task/worker/generate_styleguide_less.js

/**
 * Generate a fonts less file from available font files.
 * @function task.worker.generateStyleguideLess
 * @param {object} config - Work configuration.
 * @param {string} config.dest - Destination directory.
 * @param {function} callback - Callback when done.
 * @author Taka Okunishi
 *
 */

var path = require('path'),
    fs = require('fs'),
    debug = require('./_debug'),
    lib = require('../../lib'),
    file = lib.file,
    math = lib.math,
    string = lib.string,
    capitalize = string.capitalize,
    naturalNumbers = math.naturalNumbers,
    expandGlob = file.expandGlob,
    loadHbsTmpl = file.loadHbsTmpl,
    _ensureThemeDataGuideIndex = require('./_ensure_theme_data_guide_index'),
    _themeNameForIndex = require('./_theme_name_for_index'),
    _colorThemesData = require('./_color_themes_data'),
    _schemeColors = require('./_scheme_colors'),
    writeReadonlyFile = file.writeReadonlyFile,
    _flattenThemesData = require('./_flatten_themes_data.js');

exports = module.exports = function (config, callback) {
    var dest = path.resolve(config.dest);
    exports._loadDocLessTmpl(function (err, lessTmpl) {
        if (err) {
            callback(err);
            return;
        }
        exports._importsData(config.imports || [], dest, function (err, imports) {
            if (err) {
                callback(err);
                return;
            }
            var content = {
                imports: imports,
                colors: exports._colorData(),
                img: require('../data/img-themes-data')
            };
            var themesData = require(config.themesDataFile || '../data/style-themes-data');
            themesData = _ensureThemeDataGuideIndex(themesData);
            Object.keys(themesData).forEach(function (key) {
                var data = themesData[key];
                content[key] = _flattenThemesData(data.choices);
            });
            content._themesDataGuide = Object.keys(themesData).map(function (key) {
                return {
                    name: key,
                    Name: capitalize(key),
                    guideIndex: themesData[key].guideIndex,
                    data:content[key]
                }
            });
            writeReadonlyFile(dest, lessTmpl(content), function (err) {
                if (!err) {
                    debug.didCreateFile(dest);
                }
                callback(err);
            });
        });
    });
};

exports._importsData = function (data, dest, callback) {
    expandGlob(data, function (err, data) {
        if (err) {
            callback(err);
            return;
        }
        var result = [].concat(data)
            .filter(function (importPath) {
                return !!importPath
            })
            .map(function (importPath) {
                var resolved = path.relative(
                    path.dirname(dest),
                    path.resolve(importPath)
                );
                if (!resolved.match(/^\//)) resolved = './' + resolved;
                return  resolved;
            });
        callback(null, result);
    });
};

exports._colorData = function () {
    return _colorThemesData().map(function (data) {
        var scheme = data.scheme,
            variation = data.variation,
            hue = data.hue,
            themeName = data.themeName;
        return {
            variation: variation,
            scheme: scheme,
            themeName: themeName,
            schemeColors: _schemeColors(hue, scheme, variation)
        }
    });
};


/**
 * Load the doc less templates.
 * @param callback
 * @private
 */
exports._loadDocLessTmpl = function (callback) {
    var filename = path.resolve(__dirname, '../../tmpl/_doc/styleguide.less.hbs');
    loadHbsTmpl(filename, callback);
};