Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add html and evernote formats #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea
node_modules
sass/.sass-cache
deploy-settings.js
deploy-settings.js
.DS_Store
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ Perhaps because of these changes the stream of national consciousness moves fast
In this Chautauqua I would like not to cut any new channels of consciousness but simply dig deeper into old ones that have become silted in with the debris of thoughts grown stale and platitudes too often repeated.
```

You might want to use locations for more controll over the output - see the next option.
You might want to use locations for more control over the output - see the next option.

#### `-s, --start <location>`

This options lets you specify the first highlight to display from. For example, given the above example output,
running `kindle-my-clippings -b 3 -l -s '211-12'` will return highlights starting from this particular location, skipping the first two.

This may be useful in a situation where you've generated a file with some highlights but want to add more to the same file after fihishing the book.
This may be useful in a situation where you've generated a file with some highlights but want to add more to the same file after finishing the book.

__Note__ the use of `-b` option which is mandatory to use with `-s` options.

Expand All @@ -66,14 +66,16 @@ Lets you specify a path to your clippings file or files. You can specify multipl

Writes output to the provided path.

#### `-f, --format <json|text>`
#### `-f, --format <json|text|html|evernote>`

Determines the output of clippings: `json` for a stringified collection of JSON objects, `text` for plain text.
Determines the output of clippings: `json` for a stringified collection of JSON objects, `html` for simple html, `text` for plain text, and `evernote` for .enex files. SEE NOTES ABOUT EVERNOTE MODE below
If the option is not specified, the default format is `text`.

#### Notes about Evernote mode
If `evernote` is selected, it will create a file for each book, named `<title>_<author>.enex`. If the notes for a book do not contain text (like if the notes are only bookmarks), the file for that book will not be created. The `-b, -o, -s` options are disabled if `evernote` is selected.

### Changelog

* 0.3.0 22.11.2015 CLI only. New API. Display title list and choose a title.

* Older API versions, supporting html output can be found here: [version 0.2.1](https://github.com/baniol/kindle-my-clippings/tree/0.2.1).

35 changes: 33 additions & 2 deletions bin/cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var minimist = require('minimist');
var fs = require('fs');

var clippings = require('../clippings');
var conversions = require('../lib/conversions')


var argv = minimist(process.argv.slice(2), {
alias: {h: 'help', i: 'input', o: 'output', f: 'format', l: 'location', s: 'start', b: 'book'}
Expand All @@ -17,7 +19,13 @@ var fileName = argv.input || 'My Clippings.txt';
var fileNameArray = fileName.split(',');

clippings.getTitles(fileNameArray, function (titles, collection) {
if (argv.book) {
if (argv.format && argv.format === 'evernote') {
titles.forEach(function (t, index) {
index++;
next(titles, collection, index);
});
}
else if (argv.book) {
next(titles, collection, argv.book);
}
else {
Expand All @@ -38,19 +46,42 @@ clippings.getTitles(fileNameArray, function (titles, collection) {
function next(titles, collection, bookNumber) {
var chosenTitle = titles[bookNumber - 1];
var book = clippings.getBook(collection, chosenTitle, argv.start);
var useEvernote = argv.format && argv.format === 'evernote'
var text;

if (argv.format && argv.format === 'json') {
text = JSON.stringify(book);
}
else if(argv.format && argv.format === 'html') {
text = conversions.convertToHtml(book)
}
else if(useEvernote){
text = conversions.convertToEvernote(book)
}
else {
text = chosenTitle + '\n============\n\n';
text += clippings.getText(book, argv.location);
}
if (argv.output) {
if (useEvernote) {
if(text === null){
console.log("No notes to print for " + book[0].title)
}
else {
var filename = evernoteFilename(book[0].title, book[0].author)
fs.writeFileSync(filename, text);
}
}
else if (argv.output) {
fs.writeFileSync(argv.output, text);
}
else {
process.stdout.write(text);
}
process.stdin.pause();
}

function evernoteFilename(title, author){
var newTitle = title.replace(/[^a-zA-Z0-9]/g,'').substring(0,20);
var newAuthor = author.replace(/[^a-zA-Z0-9]/g,'').substring(0,20);
return newTitle + "_" + newAuthor + ".enex";
}
20 changes: 10 additions & 10 deletions bin/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ USAGE: kindle-my-clippings {OPTIONS}

OPTIONS:

-i, --input Input file. If none provided, the default
is 'My Clippings.txt' in the current directory.
Multiple, coma separated files can be specified as the source, ex.:
`-i 'my_clippings_1.txt,my_clippings_2.txt'`.
-i, --input Input file. If none provided, the default
is 'My Clippings.txt' in the current directory.
Multiple, coma separated files can be specified as the source, ex.:
`-i 'my_clippings_1.txt,my_clippings_2.txt'`.

-o, --output [<file_name>] If present, writes output into the 'file_name' file.
Otherwise, prints the contents into the stdout.
-o, --output [<file_name>] If present, writes output into the 'file_name' file.
Otherwise, prints the contents into the stdout.

-f, --format [text|json] Output format: text or stringified JSON collection.
-f, --format [text|json|html|evernote] Output format: text, stringified JSON collection, HTML or evernote .enex file.

-l, --location If present, shows location in text format.
-l, --location If present, shows location in text format.

-s, --start [<location>] Displays records starting from a specified location.
-s, --start [<location>] Displays records starting from a specified location.

-b, --book [<number>] Returns a given book without displaying title list.
-b, --book [<number>] Returns a given book without displaying title list.
1 change: 1 addition & 0 deletions clippings.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ function makeArray(arr) {
var second = parseLines.secondLine(lines);
if (second) {
singleRecord.time = second.time;
singleRecord.timeInMs = second.timeInMs;
singleRecord.type = second.type;
singleRecord.location = second.location;
singleRecord.page = second.page;
Expand Down
63 changes: 63 additions & 0 deletions lib/conversions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
var dateFormat = require('dateformat')
var escapeHtml = require('escape-html');


module.exports.convertToHtml = convertToHtml;
module.exports.convertToEvernote = convertToEvernote;

function convertToHtml(json){
var header = "<html><body>"
var footer = "</body></html>"

var body = ""
body += "<h1>" + json[0].title + "</h1>"
body += "<h3>" + json[0].author + "</h3>"
json.forEach(function (item) {
var parsedDate = new Date(item.timeInMs)
timeFormatted = dateFormat(parsedDate, "mm/dd/yy, h:MM:ss TT");
body += "<p>" + item.location + ", " + timeFormatted + "</p>"
body += "<p>" + escapeHtml(item.text) + "</p>"
})
return header + body + footer
}

function convertToEvernote(json){
var hasContent = false
var currentTime = dateFormat(new Date(), "UTC:yyyymmdd'T'HHMMss'Z'")

var header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n \
<!DOCTYPE en-export SYSTEM \"http://xml.evernote.com/pub/evernote-export3.dtd\"> \n \
<en-export export-date=\"" + currentTime + "\" application=\"Evernote\" > \n \
<note> \n \
<title>" + json[0].title + "</title> \n \
<content><![CDATA[<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?> \n \
<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\"> \n \
<en-note>";
var footer = "</en-note>]]>\n \
</content><created>" + currentTime + "</created><updated>" + currentTime + "</updated> \
<tag>kindle notes</tag> \n \
<note-attributes><author>jake sparling</author></note-attributes></note> \
</en-export>"


var body= ""
body += "<div><b style=\"font-size: 24px;\">" + json[0].title + "</b><br/></div>"
body += "<div><span style=\"font-size: 18px;\">" + json[0].author + "</span><br/></div><br/><br/>"

json.forEach(function (item) {
var parsedDate = new Date(item.timeInMs)
timeFormatted = dateFormat(parsedDate, "mm/dd/yy, h:MM:ss TT");
body += "<div><font color=\"#767676\">" + item.location.replace("- ", "") + " | " + timeFormatted + "</font><p/></div>"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when parsing a pdf file the line throws exception - item.location is undefined. I've handled this situation in the getText function (clipping.js file)

if(item.type !== 'Bookmark'){
hasContent = true
body += "<blockquote style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><div>" + escapeHtml(item.text) + "</div></blockquote><p/>"
}
})

if(hasContent){
return header + body + footer
}
else {
return null
}
}
7 changes: 3 additions & 4 deletions lib/parselines.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ function secondLine(lines) {
strTime = strTime.replace('Greenwich Mean Time', 'GMT');
var m = new Date(strTime);
// @TODO alternative syntax
var timeFormatted = m.getTime();
timeFormatted = dateFormat(m, "dddd, mmmm dS, yyyy, h:MM:ss TT");
singleRecord.time = timeFormatted;
singleRecord.timeInMs = m.getTime();
singleRecord.time = dateFormat(m, "dddd, mmmm dS, yyyy, h:MM:ss TT");
}

// Examples of type and location
Expand Down Expand Up @@ -90,4 +89,4 @@ function trim(str) {
}
}
return str;
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"dependencies": {
"dateformat": "1.0.4-1.2.3",
"escape-html": "^1.0.3",
"minimist": "^1.2.0",
"underscore": "1.4.4"
},
Expand Down