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
138
|
var _ = require('lodash');
var Ignore = require('ignore');
var Promise = require('../utils/promise');
var PluginsManager = require('../plugins');
/*
Output is like a stream interface for a parsed book
to output "something".
The process is mostly on the behavior of "onPage" and "onAsset"
*/
function Output(book, type) {
_.bindAll(this);
this.book = book;
this.log = this.book.log;
this.type = type;
this.plugins = new PluginsManager(book);
// Files to ignore in output
this.ignore = Ignore();
this.ignore.addPattern(_.compact([
'.gitignore',
'.ignore',
'.bookignore',
// The configuration file should not be copied in the output
this.book.config.path,
// Structure file to ignore
this.book.summary.path,
this.book.langs.path
]));
}
// Start the generation, for a parsed book
Output.prototype.generate = function() {
var that = this;
var isMultilingual = this.book.isMultilingual();
return Promise()
// Load all plugins
.then(function() {
that.log.info.ln('Loading and preparing plugins');
var plugins = _.pluck(that.book.config.get('plugins'), 'name');
return that.plugins.load(plugins);
})
// Initialize the generation
.then(function() {
return that.prepare();
})
// Process all files
.then(function() {
return that.book.fs.listAllFiles(that.book.root);
})
// We want to process assets first, then pages
// Since pages can have logic based on existance of assets
.then(function(files) {
// Split into pages/assets
var byTypes = _.chain(files)
.filter(that.ignore.createFilter())
// Ignore file present in a language book
.filter(function(filename) {
return !(isMultilingual && that.book.isInLanguageBook(filename));
})
.groupBy(function(filename) {
return (that.book.hasPage(filename)? 'page' : 'asset');
})
.value();
return Promise.serie(byTypes.asset, function(filename) {
return that.onAsset(filename);
})
.then(function() {
return Promise.serie(byTypes.page, function(filename) {
return that.onPage(that.book.getPage(filename));
});
});
})
// Finish the generation
.then(function() {
return that.finish();
});
};
// Prepare the generation
Output.prototype.prepare = function() {
};
// Write a page (parsable file), ex: markdown, etc
Output.prototype.onPage = function(page) {
return page.parse(this);
};
// Copy an asset file (non-parsable), ex: images, etc
Output.prototype.onAsset = function(filename) {
};
// Resolve an HTML link
Output.prototype.onRelativeLink = function(currentPage, href) {
var to = this.book.getPage(href);
if (to) return to.outputPath();
return href;
};
// Output a SVG buffer as a file
Output.prototype.onOutputSVG = function(page, svg) {
return null;
};
// Output an image as a file
// Normalize the relative link
Output.prototype.onOutputImage = function(page, imgFile) {
return page.relative(imgFile);
};
// Finish the generation
Output.prototype.finish = function() {
};
module.exports = Output;
|