-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgulpfile.js
More file actions
193 lines (166 loc) · 6.58 KB
/
gulpfile.js
File metadata and controls
193 lines (166 loc) · 6.58 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
var fs = require('fs');
var path = require('path');
var gulp = require('gulp');
var sass = require('gulp-sass');
var shell = require('gulp-shell');
var gutil = require('gulp-util');
var clean = require('gulp-clean');
var jsdom = require('jsdom');
var merge = require('merge-stream');
var rename = require('gulp-rename');
var isNumeric = require('isnumeric');
var cleanCSS = require('gulp-clean-css');
var gulpSequence = require('gulp-sequence')
/**
* The shell command that builds a set of *.md files into an *.html file.
*/
const PANDOC_COMMAND_ARR = [
// executable
'pandoc',
// This `undefined` item stands in place of the actual input filenames.
// The item will be replaced by an actual list of all files, starting
// from index.md and then containing all the modules in numeric order.
undefined,
// Output filename
'-o', 'out/index-<%= lang %>.html',
// Additional Metadata arguments
'--metadata', 'lang:<%= lang %>', // The language of the document
// More options
'-t', 'html5', // format used to write the output
'--smart', // smart quotes and hyphens
'--template', 'template.html', // HTML template to use
'--css', 'css/main.min.css', // CSS to link to from the output
'--highlight-style', 'tango', // highlighting syntax for code sections
];
/**
* The regular expression to validate modules with content
*/
const MODULE_REGEX = /^module(\d+).md$/;
/**
* Return an array with the input files in a given language directory,
* corresponding to the index.md and module*.md files, whereis any digit-only
* string. The array contains the index.md in the first position (if one such
* file exists) and the module*.md files sorted in numeric order after that.
*/
function getInputFiles(lang) {
// Get all the files in the directory. Then assign to each a numeric value
// for subsequent sorting purposes: `index.md` gets 0; `module*.md` gets the
// numeric value of the `*`. Then, keep the files with a numeric value;
// the rest are not valid for our purposes.
var files = fs
.readdirSync(lang)
.reduce((current, filename) => {
var value = false;
if (filename === 'index.md') {
value = 0;
}
else {
var match = MODULE_REGEX.exec(filename);
if (match !== null) {
value = parseInt(match[1])
}
}
// Only update the current array if a valid file has been found
if (value !== false) {
current.push({ filename, value });
}
return current;
}, []);
// Sort the files using their numeric value
files.sort((a, b) => a.value - b.value);
// Return the file names, joined with the name of the language directory
return files.map(item => path.join(lang, item.filename));
}
/**
* Return an array with the language directories of this project. A language
* directory is a directory whose name is a two letter word
*/
function findLanguages() {
return fs
.readdirSync('.')
.filter(item => item.length === 2 && fs.statSync(item).isDirectory());
}
/**
* Return a gulp pipeline that builds the index.html file from the *.md files
* of a given language directory, thus building the main site of a given
* localization.
*/
function buildIndex(lang) {
var command = PANDOC_COMMAND_ARR.slice();
var files = getInputFiles(lang);
// Replace the `undefined` in the command array with the actual array of
// input file names
var index = command.indexOf(undefined);
// This next cryptic line calls command.splice with a variable number
// of arguments, thus removing the `undefined` item from the array
// and replacing it with each item that is contained in `files`
Array.prototype.splice.apply(command, [index, 1].concat(files));
return gulp
.src(lang + '/*.md')
.pipe(
shell([ command.join(' ') ], {
templateData: { lang }
})
)
.on('end', () => {
jsdom.env({
file: 'out/index-' + lang + '.html',
scripts: ['http://code.jquery.com/jquery.js'],
done(err, window) {
var $ = window.$;
// Replace '???' inside <code> elements with
// <span class="blank">?</span>
$('code').html(function() {
// Note that this cannot be defined with ES6's arrow
// functions because `this` is undefined in those
// constructs, rendering the function unusable
return $(this)
.html()
.replace(/\?\?\?/g, '<span class="blank">?</span>');
});
// `print` is a builtin in python3 but a keyworkd in python2.
// Let's also make this change here
$('span.bu').each(function() {
// See above for why we're not using arrow functions
if ($(this).text() === 'print') {
$(this).removeClass('bu');
$(this).addClass('kw');
}
});
// Remove the extra jquery <script> element
$('script.jsdom').remove();
// Write the resulting file back into its output filename
var newSource = $('html')[0].outerHTML;
fs.writeFileSync(
'out/index-' + lang + '.html',
'<!DOCTYPE html>\n' + newSource
);
}
});
});
}
gulp.task('build', () => {
var tasks = findLanguages().map(buildIndex);
return merge(tasks);
});
gulp.task('sass', () => {
var options = {
outputStyle: 'compressed',
};
return gulp
.src('styles/sass/*.scss')
.pipe(sass(options).on('error', sass.logError))
.pipe(gulp.dest('out/css'));
});
gulp.task('minify-css', ['sass'], () => {
return gulp
.src(['out/css/*.css', '!out/css/main.min.css'])
.pipe(cleanCSS())
.pipe(rename('main.min.css'))
.pipe(gulp.dest('out/css'))
});
gulp.task('clean-css', ['sass'], () => {
return gulp
.src(['out/css/*.css', '!out/css/main.min.css'])
.pipe(clean());
});