-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.js
More file actions
137 lines (109 loc) · 4.29 KB
/
parser.js
File metadata and controls
137 lines (109 loc) · 4.29 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
const fs = require('fs');
const util = require('util');
const minimist = require('minimist');
const { mdToPdf } = require('md-to-pdf');
// Promisify core API's
const writeFile = util.promisify(fs.writeFile);
const readFile = util.promisify(fs.readFile);
const arguments = minimist(process.argv.slice(2))['_'];
let format = minimist(process.argv.slice(2))['format'];
// If the command is parse but no file has been provided
if (arguments.length === 0 || (arguments[0] === 'parse' && arguments.length <= 1)) {
console.error('You didn\'t provide all the required parameters.\r\n');
}
// Display the help message
if (arguments.length === 0 || (arguments[0] === 'parse' && arguments.length <= 1) || arguments[0] === 'help') {
console.log(`A simple Kindle notes parser to Markdown.
Usage: parser.js <command> <option> </option><clipping path>
Commands:
help Show the help message
parse Perform the file parsing
Options:
--format=pdf Generate PDF files instead of MarkDown
`);
return;
}
const filePath = arguments[arguments.length - 1];
const fileFolder = filePath.slice(0, filePath.lastIndexOf('/'));
const parseNotes = (fileContent) => {
let remainingFileContent = fileContent;
let notes = [];
let parsedNotes = {};
// Parse the file to split the notes in single instances
do {
const separatorPosition = remainingFileContent.indexOf('==========');
notes.push(remainingFileContent.substr(0, separatorPosition));
remainingFileContent = remainingFileContent.substr(separatorPosition + 12);
} while (remainingFileContent !== '');
// Parse the single notes to identify the properties
notes.forEach(note => {
let remainingNote = note;
let noteChunks = [];
do {
const separatorPosition = remainingNote.indexOf('\r\n');
noteChunks.push(remainingNote.substr(0, separatorPosition));
remainingNote = remainingNote.substr(separatorPosition + 2);
} while (remainingNote !== '');
const titleAndAuthor = noteChunks[0];
const author = titleAndAuthor.slice(titleAndAuthor.lastIndexOf('(') + 1, titleAndAuthor.length - 1);
const title = titleAndAuthor.slice(0, titleAndAuthor.lastIndexOf('(') - 1);
const extraInfo = noteChunks[1].substr(3);
const position = /(\d+-?(\d+)) \|/.exec(extraInfo)[1];
const date = extraInfo.substr(extraInfo.indexOf('|') + 2);
const noteText = noteChunks[3];
if (parsedNotes[title + author] === undefined) {
parsedNotes[title + author] = [];
}
parsedNotes[title + author].push({
title,
author,
position,
date,
noteText
});
});
return parsedNotes;
}
const writeBookNotes = async (bookNotes) => {
let fileContent = '';
// For each note create a section inside the book file
bookNotes.forEach(note => {
if (note.noteText === '') {
return;
}
fileContent += '### ' + note.date + ' (Location ' + note.position + ')\r\n';
fileContent += note.noteText + '\r\n\r\n';
})
// If empty avoid writing the file
if (fileContent === '') {
return;
}
fileContent = '# ' + bookNotes[0].title + ' - ' + bookNotes[0].author + '\r\n' + fileContent;
const filePath = fileFolder + '/Kindle Notes Export/' + bookNotes[0].title + ' - ' + bookNotes[0].author;
switch (format) {
case 'pdf':
const pdf = await mdToPdf({ content: fileContent }).catch(console.error);
if (pdf) {
fs.writeFileSync(`${filePath}.pdf`, pdf.content);
}
break;
default:
fs.writeFileSync(`${filePath}.md`, fileContent);
}
}
return readFile(filePath, 'utf8').then(mainFileData => {
// Parse notes and show warning if file is empty or no notes are inside
let notes = parseNotes(mainFileData);
if (!Object.keys(notes).length) {
console.warn('Notes file empty. Exiting...')
return;
}
// Create an export folder
// @TODO Dynamic
if (!fs.existsSync(fileFolder + '/Kindle Notes Export')){
fs.mkdirSync(fileFolder + '/Kindle Notes Export');
}
Object.values(notes).forEach(note => {
writeBookNotes(note);
})
});