make it possible to hide chapter word count and duration

This commit is contained in:
daniel-j 2018-07-31 10:27:49 +02:00
parent 9a458b558c
commit b0d7247680
6 changed files with 65 additions and 49 deletions

View file

@ -53,24 +53,26 @@ By default the EPUB will be saved in the current working directory with the file
Options: Options:
-V, --version output the version number -V, --version output the version number
-d, --dir <path> Directory to store ebook in. Is prepended to filename -d, --dir <path> Directory to store ebook in. Is prepended to filename
-t, --title <value> Set the title of the story -t, --title <value> Set the title of the story
-a, --author <value> Set the author of the story -a, --author <value> Set the author of the story
-T, --typogrify Enable typographic fixes (smart quotes, dashes, ellipsis, ordinal) -T, --typogrify Enable typographic fixes (smart quotes, dashes, ellipsis, ordinal)
-c, --no-comments-link Don't add link to online comments -c, --no-comments-link Don't add link to online comments
-H, --no-headings Don't add headings to chapters -H, --no-headings Don't add headings to chapters (includes chapter title, duration and word count)
-b, --no-bars Don't add chapter bars to show reading progress -W, --no-chapter-word-count Don't add word count to chapter headings
-r, --no-reading-ease Don't calculate Flesch reading ease -D, --no-chapter-duration Don't add time to read to chapter headings
-e, --no-external Don't embed external resources, such as images (breaks EPUB spec) -b, --no-bars Don't add chapter bars to show reading progress
-n, --no-notes Don't include author notes -r, --no-reading-ease Don't calculate Flesch reading ease
-i, --notes-index Create an index with all author notes at the end of the ebook -e, --no-external Don't embed external resources, such as images (breaks EPUB spec)
-p, --paragraphs <style> Select a paragraph style <spaced|indented|indentedall|both> (default: spaced) -n, --no-notes Don't include author notes
-k, --kepubify Add extra <span> elements for Kobo EPUB (KEPUB) format -i, --notes-index Create an index with all author notes at the end of the ebook
-j, --join-subjects Join dc:subjects to a single value -p, --paragraphs <style> Select a paragraph style <spaced|indented|indentedall|both> (default: spaced)
-w, --wpm <number> Words per minute. Set to 0 to disable reading time estimations (default: 200) -k, --kepubify Add extra <span> elements for Kobo EPUB (KEPUB) format
-C, --cover <url> Set cover image url -j, --join-subjects Join dc:subjects to a single value
-h, --help output usage information -w, --wpm <number> Words per minute. Set to 0 to disable reading time estimations (default: 200)
-C, --cover <url> Set cover image url
-h, --help output usage information
``` ```
Examples Examples

View file

@ -1,6 +1,6 @@
{ {
"name": "fimfic2epub", "name": "fimfic2epub",
"version": "1.7.33", "version": "1.7.34",
"description": "Tool to generate improved EPUB ebooks from Fimfiction stories", "description": "Tool to generate improved EPUB ebooks from Fimfiction stories",
"author": "djazz", "author": "djazz",
"license": "MIT", "license": "MIT",
@ -22,16 +22,16 @@
"LICENSE" "LICENSE"
], ],
"dependencies": { "dependencies": {
"commander": "^2.15.1", "commander": "^2.16.0",
"crc-32": "^1.2.0", "crc-32": "^1.2.0",
"detect-node": "^2.0.3", "detect-node": "^2.0.3",
"elementtree": "^0.1.7", "elementtree": "^0.1.7",
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
"file-type": "^8.0.0", "file-type": "^8.1.0",
"fonteditor-core": "^1.0.2", "fonteditor-core": "^1.0.5",
"html-entities": "^1.2.1", "html-entities": "^1.2.1",
"html-to-text": "^4.0.0", "html-to-text": "^4.0.0",
"image-size": "^0.6.2", "image-size": "^0.6.3",
"is-svg": "^3.0.0", "is-svg": "^3.0.0",
"jszip": "^3.1.5", "jszip": "^3.1.5",
"match-words": "^1.0.0", "match-words": "^1.0.0",
@ -39,23 +39,23 @@
"mithril-node-render": "^2.3.0", "mithril-node-render": "^2.3.0",
"node-png": "^0.4.3", "node-png": "^0.4.3",
"pretty-data": "^0.40.0", "pretty-data": "^0.40.0",
"request": "^2.86.0", "request": "^2.87.0",
"sanitize-filename": "^1.6.1", "sanitize-filename": "^1.6.1",
"syllable": "^3.0.0", "syllable": "^3.0.0",
"twemoji": "^2.5.1", "twemoji": "^11.0.0",
"typogr": "^0.6.7", "typogr": "^0.6.8",
"url-regex": "^4.1.1", "url-regex": "^4.1.1",
"zero-fill": "^2.2.3" "zero-fill": "^2.2.3"
}, },
"devDependencies": { "devDependencies": {
"autosize": "^4.0.2", "autosize": "^4.0.2",
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-loader": "^7.1.4", "babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
"babel-register": "^6.26.0", "babel-register": "^6.26.0",
"binary-loader": "0.0.1", "binary-loader": "0.0.1",
"del": "^3.0.0", "del": "^3.0.0",
"eslint": "^4.19.1", "eslint": "^5.2.0",
"eslint-plugin-standard": "^3.1.0", "eslint-plugin-standard": "^3.1.0",
"exports-loader": "^0.7.0", "exports-loader": "^0.7.0",
"file-saver": "^1.3.8", "file-saver": "^1.3.8",
@ -65,21 +65,21 @@
"gulp-change": "^1.0.0", "gulp-change": "^1.0.0",
"gulp-chmod": "^2.0.0", "gulp-chmod": "^2.0.0",
"gulp-filter": "^5.1.0", "gulp-filter": "^5.1.0",
"gulp-json-editor": "^2.3.0", "gulp-json-editor": "^2.4.2",
"gulp-rename": "^1.2.3", "gulp-rename": "^1.4.0",
"gulp-standard": "^11.0.0", "gulp-standard": "^11.0.0",
"gulp-util": "^3.0.8", "gulp-util": "^3.0.8",
"gulp-watch": "^5.0.0", "gulp-watch": "^5.0.1",
"gulp-zip": "^4.1.0", "gulp-zip": "^4.2.0",
"lazypipe": "^1.0.1", "lazypipe": "^1.0.1",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"regenerator-runtime": "^0.11.1", "regenerator-runtime": "^0.12.0",
"removeNPMAbsolutePaths": "^1.0.4", "removeNPMAbsolutePaths": "^1.0.4",
"run-sequence": "^2.2.1", "run-sequence": "^2.2.1",
"standard": "^11.0.1", "standard": "^11.0.1",
"stylus": "^0.54.5", "stylus": "^0.54.5",
"stylus-loader": "^3.0.2", "stylus-loader": "^3.0.2",
"webpack": "^4.8.3", "webpack": "^4.16.3",
"webpack-node-externals": "^1.7.2" "webpack-node-externals": "^1.7.2"
}, },
"standard": { "standard": {

View file

@ -95,7 +95,9 @@ class FimFic2Epub extends EventEmitter {
addCommentsLink: true, addCommentsLink: true,
includeAuthorNotes: true, includeAuthorNotes: true,
useAuthorNotesIndex: false, useAuthorNotesIndex: false,
addChapterHeadings: true, showChapterHeadings: true,
showChapterWordCount: true,
showChapterDuration: true,
includeExternal: true, includeExternal: true,
paragraphStyle: 'spaced', paragraphStyle: 'spaced',
kepubify: false, kepubify: false,
@ -401,7 +403,9 @@ class FimFic2Epub extends EventEmitter {
chain = chain.then(template.createChapter.bind(null, this, { chain = chain.then(template.createChapter.bind(null, this, {
title: ch.title, title: ch.title,
addHeadings: this.options.addChapterHeadings, showHeadings: this.options.showChapterHeadings,
showWordCount: this.options.showChapterWordCount,
showDuration: this.options.showChapterDuration,
link: this.options.addCommentsLink ? ch.link : null, link: this.options.addCommentsLink ? ch.link : null,
linkNotes: this.options.includeAuthorNotes && this.options.useAuthorNotesIndex && chapter.notes ? 'note_' + zeroFill(3, i + 1) + '.xhtml' : null, linkNotes: this.options.includeAuthorNotes && this.options.useAuthorNotesIndex && chapter.notes ? 'note_' + zeroFill(3, i + 1) + '.xhtml' : null,
content: content, content: content,
@ -418,7 +422,7 @@ class FimFic2Epub extends EventEmitter {
if (this.options.includeAuthorNotes && this.options.useAuthorNotesIndex && chapter.notes) { if (this.options.includeAuthorNotes && this.options.useAuthorNotesIndex && chapter.notes) {
chain = chain.then(template.createChapter.bind(null, this, { chain = chain.then(template.createChapter.bind(null, this, {
title: 'Author\'s Note: ' + ch.title, title: 'Author\'s Note: ' + ch.title,
addHeadings: true, showHeadings: true,
content: chapter.notes, content: chapter.notes,
index: i index: i
}, true)).then((html) => { }, true)).then((html) => {

View file

@ -8,7 +8,9 @@ const args = require('commander')
.option('-a, --author <value>', 'Set the author of the story') .option('-a, --author <value>', 'Set the author of the story')
.option('-T, --typogrify', 'Enable typographic fixes (smart quotes, dashes, ellipsis, ordinal)') .option('-T, --typogrify', 'Enable typographic fixes (smart quotes, dashes, ellipsis, ordinal)')
.option('-c, --no-comments-link', 'Don\'t add link to online comments') .option('-c, --no-comments-link', 'Don\'t add link to online comments')
.option('-H, --no-headings', 'Don\'t add headings to chapters') .option('-H, --no-headings', 'Don\'t add headings to chapters (includes chapter title, duration and word count)')
.option('-W, --no-chapter-word-count', 'Don\'t add word count to chapter headings')
.option('-D, --no-chapter-duration', 'Don\'t add time to read to chapter headings')
.option('-b, --no-bars', 'Don\'t add chapter bars to show reading progress') .option('-b, --no-bars', 'Don\'t add chapter bars to show reading progress')
.option('-r, --no-reading-ease', 'Don\'t calculate Flesch reading ease') .option('-r, --no-reading-ease', 'Don\'t calculate Flesch reading ease')
.option('-e, --no-external', 'Don\'t embed external resources, such as images (breaks EPUB spec)') .option('-e, --no-external', 'Don\'t embed external resources, such as images (breaks EPUB spec)')
@ -33,7 +35,7 @@ if (outputStdout) {
console.log('Outputting to stdout') console.log('Outputting to stdout')
} }
// use a mock DOM so we can run mithril on the server // use a mock DOM so we can run mithril in nodejs
require('mithril/test-utils/browserMock')(global) require('mithril/test-utils/browserMock')(global)
const htmlToText = require('./utils').htmlToText const htmlToText = require('./utils').htmlToText
@ -48,7 +50,9 @@ const ffc = new FimFic2Epub(STORY_ID, {
addCommentsLink: !!args.commentsLink, addCommentsLink: !!args.commentsLink,
includeAuthorNotes: !!args.notes, includeAuthorNotes: !!args.notes,
useAuthorNotesIndex: !!args.notesIndex, useAuthorNotesIndex: !!args.notesIndex,
addChapterHeadings: !!args.headings, showChapterHeadings: !!args.headings,
showChapterWordCount: !!args.chapterWordCount,
showChapterDuration: !!args.chapterDuration,
includeExternal: !!args.external, includeExternal: !!args.external,
paragraphStyle: args.paragraphs, paragraphStyle: args.paragraphs,
kepubify: !!args.kepubify, kepubify: !!args.kepubify,

View file

@ -133,7 +133,9 @@ let dialog = {
this.addCommentsLink = prop(ffc.options.addCommentsLink) this.addCommentsLink = prop(ffc.options.addCommentsLink)
this.includeAuthorNotes = prop(ffc.options.includeAuthorNotes) this.includeAuthorNotes = prop(ffc.options.includeAuthorNotes)
this.useAuthorNotesIndex = prop(ffc.options.useAuthorNotesIndex) this.useAuthorNotesIndex = prop(ffc.options.useAuthorNotesIndex)
this.addChapterHeadings = prop(ffc.options.addChapterHeadings) this.showChapterHeadings = prop(ffc.options.showChapterHeadings)
this.showChapterWordCount = prop(ffc.options.showChapterWordCount)
this.showChapterDuration = prop(ffc.options.showChapterDuration)
this.includeExternal = prop(ffc.options.includeExternal) this.includeExternal = prop(ffc.options.includeExternal)
this.kepubify = prop(ffc.options.kepubify) this.kepubify = prop(ffc.options.kepubify)
this.joinSubjects = prop(ffc.options.joinSubjects) this.joinSubjects = prop(ffc.options.joinSubjects)
@ -253,9 +255,11 @@ let dialog = {
['indentedall', 'Indent all paragraphs including the first (Modified Traditional)'] ['indentedall', 'Indent all paragraphs including the first (Modified Traditional)']
], ctrl.paragraphStyle())) ], ctrl.paragraphStyle()))
)), )),
m('tr', m('td.label', ''), m('td', {colspan: 2}, m('tr', m('td.label', {style: 'vertical-align: top;'}, 'Options'), m('td', {colspan: 2},
m(checkbox, {checked: ctrl.typogrify(), onchange: m.withAttr('checked', ctrl.typogrify)}, 'Apply typographic fixes (smart quotes, dashes etc.)'), m(checkbox, {checked: ctrl.typogrify(), onchange: m.withAttr('checked', ctrl.typogrify)}, 'Apply typographic fixes (smart quotes, dashes etc.)'),
m(checkbox, {checked: ctrl.addChapterHeadings(), onchange: m.withAttr('checked', ctrl.addChapterHeadings)}, 'Add chapter headings, with chapter word count and time to read'), m(checkbox, {checked: ctrl.showChapterHeadings(), onchange: m.withAttr('checked', ctrl.showChapterHeadings)}, 'Add chapter headings'),
m(checkbox, {checked: ctrl.showChapterWordCount(), onchange: m.withAttr('checked', ctrl.showChapterWordCount), disabled: !ctrl.showChapterHeadings()}, 'Include word count in chapter heading'),
m(checkbox, {checked: ctrl.showChapterDuration(), onchange: m.withAttr('checked', ctrl.showChapterDuration), disabled: !ctrl.showChapterHeadings()}, 'Include time to read in chapter heading'),
m(checkbox, {checked: ctrl.addCommentsLink(), onchange: m.withAttr('checked', ctrl.addCommentsLink)}, 'Add link to online comments (at the end of chapters)'), m(checkbox, {checked: ctrl.addCommentsLink(), onchange: m.withAttr('checked', ctrl.addCommentsLink)}, 'Add link to online comments (at the end of chapters)'),
m(checkbox, {checked: ctrl.includeAuthorNotes(), onchange: m.withAttr('checked', ctrl.includeAuthorNotes)}, 'Include author\'s notes'), m(checkbox, {checked: ctrl.includeAuthorNotes(), onchange: m.withAttr('checked', ctrl.includeAuthorNotes)}, 'Include author\'s notes'),
m(checkbox, {checked: ctrl.useAuthorNotesIndex(), onchange: m.withAttr('checked', ctrl.useAuthorNotesIndex), disabled: !ctrl.includeAuthorNotes()}, 'Put all notes at the end of the ebook'), m(checkbox, {checked: ctrl.useAuthorNotesIndex(), onchange: m.withAttr('checked', ctrl.useAuthorNotesIndex), disabled: !ctrl.includeAuthorNotes()}, 'Put all notes at the end of the ebook'),
@ -326,7 +330,9 @@ function createEpub (model) {
ffc.options.addCommentsLink = model.addCommentsLink() ffc.options.addCommentsLink = model.addCommentsLink()
ffc.options.includeAuthorNotes = model.includeAuthorNotes() ffc.options.includeAuthorNotes = model.includeAuthorNotes()
ffc.options.useAuthorNotesIndex = model.useAuthorNotesIndex() ffc.options.useAuthorNotesIndex = model.useAuthorNotesIndex()
ffc.options.addChapterHeadings = model.addChapterHeadings() ffc.options.showChapterHeadings = model.showChapterHeadings()
ffc.options.showChapterWordCount = model.showChapterWordCount()
ffc.options.showChapterDuration = model.showChapterDuration()
ffc.options.includeExternal = model.includeExternal() ffc.options.includeExternal = model.includeExternal()
ffc.options.paragraphStyle = model.paragraphStyle() ffc.options.paragraphStyle = model.paragraphStyle()
ffc.options.kepubify = model.kepubify() ffc.options.kepubify = model.kepubify()

View file

@ -66,7 +66,7 @@ function chapterBars (chapters, currentChapter = -1, highlightCurrent = false) {
} }
export function createChapter (ffc, ch, isNotesChapter) { export function createChapter (ffc, ch, isNotesChapter) {
let {content, notes, notesFirst, title, link, linkNotes, index, addHeadings} = ch let {content, notes, notesFirst, title, link, linkNotes, index, showHeadings, showDuration, showWordCount} = ch
let sections = [ let sections = [
m.trust(content || ''), m.trust(content || ''),
@ -91,10 +91,10 @@ export function createChapter (ffc, ch, isNotesChapter) {
m('title', title) m('title', title)
]), ]),
m('body', {'epub:type': 'bodymatter chapter'}, m('div', [ m('body', {'epub:type': 'bodymatter chapter'}, m('div', [
addHeadings ? m('.chapter-title', [ showHeadings ? m('.chapter-title', [
!isNotesChapter ? m('aside.info', !isNotesChapter && (showDuration || showWordCount) ? m('aside.info',
m('span.label', ffc.options.wordsPerMinute ? calcReadingTime(ffc, ffc.storyInfo.chapters[index].realWordCount) : ''), showDuration ? m('span.label', ffc.options.wordsPerMinute ? calcReadingTime(ffc, ffc.storyInfo.chapters[index].realWordCount) : '') : null,
m('span.label', ffc.storyInfo.chapters[index].realWordCount.toLocaleString('en-GB') + ' words') showWordCount ? m('span.label', ffc.storyInfo.chapters[index].realWordCount.toLocaleString('en-GB') + ' words') : null
) : null, ) : null,
m('header', m('h1', title)), m('header', m('h1', title)),
m('hr.old') m('hr.old')