summaryrefslogtreecommitdiffstats
path: root/lib/generate/plugin.js
blob: 27c1cc966d212095df9497a5f3cf33d0caace22c (plain)
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
var _ = require("lodash");
var Q = require("q");
var semver = require("semver");
var fs = require("./fs");

var pkg = require("../../package.json");

var Plugin = function(name) {
    this.name = name;
    this.packageInfos = {};
    this.infos = {};

    _.each([
        name,
        "gitbook-plugin-"+name,
        "gitbook-theme-"+name
    ], function(_name) {
        if (this.load(_name)) return false;
    }.bind(this));
};

// Load from a name
Plugin.prototype.load = function(name) {
    try {
        this.packageInfos = require(name+"/package.json");
        this.infos = require(name);
        this.name = name;

        return true;
    } catch (e) {
        return false;
    }
};

// Return resources
Plugin.prototype.getResources = function(resource) {
    if (!this.infos.book || !this.infos.book[resource]) {
        return [];
    }
    return this.infos.book[resource];
};

// Test if it's a valid plugin
Plugin.prototype.isValid = function() {
    return (
        this.packageInfos
        && this.packageInfos.name
        && this.packageInfos.engines
        && this.packageInfos.engines.gitbook
        && semver.satisfies(pkg.version, this.packageInfos.engines.gitbook)
    );
};

// Extract data from a list of plugin
Plugin.fromList = function(names) {
    var failed = [];

    // Load plugins
    var plugins = _.map(names, function(name) {
        var plugin = new Plugin(name);
        if (!plugin.isValid()) failed.push(name);
        return plugin;
    });

    if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(":")));

    // Get all resources
    var resources = _.chain([
        "js", "css"
    ])
    .map(function(resource) {
        return [
            resource,
            _.chain(plugins)
            .map(function(plugin) {
                return plugin.getResources(resource);
            })
            .flatten()
            .value()
        ];
    })
    .object()
    .value();

    return Q({
        'plugins': plugins,
        'resources': resources
    });
};


// Normalize a list of plugin name to use
Plugin.normalizeNames = function(names) {
    // Normalize list to an array
    names = _.isString(names) ? names.split(":") : (names || []);

    // List plugins to remove
    var toremove = _.chain(names)
    .filter(function(name) {
        return name.length > 0 && name[0] == "-";
    })
    .map(function(name) {
        return name.slice(1)
    })
    .value();

    // Merge with defaults
    names = _.chain(names)
    .concat(Plugin.defaults)
    .uniq()
    .value();

    // Remove plugins starting with 
    names = _.filter(names, function(name) {
        return !_.contains(toremove, name) && !(name.length > 0 && name[0] == "-");
    });

    return names;
};

// Default plugins
Plugin.defaults = [
    "mixpanel"
];

module.exports = Plugin;