-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathm2json.js
More file actions
108 lines (87 loc) · 2.85 KB
/
m2json.js
File metadata and controls
108 lines (87 loc) · 2.85 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
/* eslint-env node */
'use strict';
import { DateTime } from 'luxon';
import path from 'path';
import fs from 'fs';
import yaml from 'yaml-front-matter';
// Side effects:
// - Root node of JSON is files key mapping to a dictionary of files
// - .preview will be first WIDTH characters of the raw content
// (not translated), if width is not 0
// - .__content is removed (potentially too large)
// - if .date is detected, a formated date is added as .dateFormatted
const truncate = function(str, options) {
const { length = 80, separator = /\s/, omission = ' …' } = options;
if (str.length <= length) {
return str;
}
let truncated = str.slice(0, length);
if (separator) {
const lastIndex = truncated.search(separator);
if (lastIndex > 0) {
truncated = truncated.slice(0, lastIndex);
}
}
return truncated + omission;
};
const processFile = function(filename, width, content) {
const _basename = path.basename(filename, path.extname(filename));
const contents = fs.readFileSync(filename, {encoding: 'utf-8'});
const _metadata = yaml.loadFront(contents);
// If width is truthy (is defined and and is not 0).
if (width) {
// Max of WIDTH chars snapped to word boundaries, trim whitespace
const truncateOptions = {
length: width,
separator: /\s/,
omission: ' …',
};
_metadata.preview = truncate(_metadata['__content'].trim(),
truncateOptions);
}
// If the option is provided keep the entire content in field 'content'
if (typeof(content) != 'undefined') {
_metadata['content'] = _metadata['__content'];
}
delete _metadata['__content'];
// map user-entered date to a better one using DateTime's parser
if (_metadata.date) {
_metadata.iso8601Date = DateTime.fromJSDate(new Date(_metadata.date)).toISO();
}
_metadata.basename = _basename;
_metadata.path = filename;
return {
metadata: _metadata,
basename: _basename,
};
};
const getFiles = function(filename) {
if (fs.lstatSync(filename).isDirectory()) {
return fs.readdirSync(filename).filter((entry) => !entry.isDirectory);
} else {
return [filename];
}
};
export const parse = function(filenames, options) {
// http://i.qkme.me/3tmyv8.jpg
const parseAllTheFiles = {};
// http://i.imgur.com/EnXB9aA.jpg
const files = filenames
.map(getFiles)
.reduce((collection, filenames) => collection.concat(filenames), []);
files
.map((file) => processFile(file, options.width, options.content))
.forEach((data) => {
parseAllTheFiles[data.basename] = data.metadata;
});
const json = JSON.stringify(parseAllTheFiles, null, options.minify ? 0 : 2);
if (options.outfile) {
const file = fs.openSync(options.outfile, 'w+');
fs.writeSync(file, json + '\n');
fs.closeSync(file);
return;
} else {
return json;
}
};
export default { parse };