mirror of
https://github.com/daniel-j/fimfic2epub.git
synced 2024-06-02 10:34:32 +12:00
Add word count, fixes #3. New synopsis layout
This commit is contained in:
parent
9ad70f66b1
commit
caea25cd22
|
@ -130,7 +130,6 @@ module.exports = class FimFic2Epub {
|
|||
}
|
||||
|
||||
this.zip.file('OEBPS/toc.ncx', template.createNcx(this))
|
||||
this.zip.file('OEBPS/Text/nav.xhtml', template.createNav(this))
|
||||
|
||||
this.fetchTitlePage(resolve, reject)
|
||||
}).catch(reject)
|
||||
|
@ -251,6 +250,8 @@ module.exports = class FimFic2Epub {
|
|||
console.log('Fetching chapters...')
|
||||
|
||||
this.fetchChapters(() => {
|
||||
this.zip.file('OEBPS/Text/nav.xhtml', template.createNav(this))
|
||||
|
||||
console.log('Fetching remote files...')
|
||||
|
||||
this.fetchRemoteFiles(() => {
|
||||
|
|
|
@ -173,10 +173,36 @@ a.chaptercomments {
|
|||
}
|
||||
|
||||
#toc {
|
||||
h3 {
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
ol {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
// overflow: auto;
|
||||
|
||||
a, .floatbox {
|
||||
padding: 0.3em;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
.floatbox {
|
||||
float: right;
|
||||
}
|
||||
|
||||
span.date, span.wordcount {
|
||||
font-size: 0.8em;
|
||||
color: #888;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
|
|
|
@ -64,8 +64,8 @@ export function createChapter (ch, html, callback) {
|
|||
content.reverse()
|
||||
}
|
||||
|
||||
let chapterPage = '<!doctype html>' + render(
|
||||
m('html', {xmlns: NS.XHTML}, [
|
||||
let chapterPage = '<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE html>\n' + pretty.xml(render(
|
||||
m('html', {xmlns: NS.XHTML, 'xmlns:epub': NS.OPS}, [
|
||||
m('head', [
|
||||
m('meta', {charset: 'utf-8'}),
|
||||
m('link', {rel: 'stylesheet', type: 'text/css', href: '../Styles/style.css'}),
|
||||
|
@ -82,7 +82,7 @@ export function createChapter (ch, html, callback) {
|
|||
)
|
||||
])
|
||||
])
|
||||
)
|
||||
))
|
||||
|
||||
callback(chapterPage)
|
||||
})
|
||||
|
@ -203,7 +203,7 @@ export function createNcx (ffc) {
|
|||
|
||||
export function createNav (ffc) {
|
||||
let navDocument = '<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE html>\n' + pretty.xml(render(
|
||||
m('html', {xmlns: NS.XHTML, 'xmlns:epub': NS.OPS, lang: 'en', 'xml:lang': 'en'}, [
|
||||
m('html', {xmlns: NS.XHTML, 'xmlns:epub': NS.OPS}, [
|
||||
m('head', [
|
||||
m('meta', {charset: 'utf-8'}),
|
||||
m('link', {rel: 'stylesheet', type: 'text/css', href: '../Styles/style.css'}),
|
||||
|
@ -211,11 +211,15 @@ export function createNav (ffc) {
|
|||
]),
|
||||
m('body#navpage', [
|
||||
m('nav#toc', {'epub:type': 'toc'}, [
|
||||
m('h1', 'Contents'),
|
||||
m('h3', 'Contents'),
|
||||
m('ol', [
|
||||
m('li', {hidden: ''}, m('a', {href: 'cover.xhtml'}, 'Cover'))
|
||||
].concat(ffc.storyInfo.chapters.map((ch, num) =>
|
||||
m('li', m('a', {href: 'chapter_' + zeroFill(3, num + 1) + '.xhtml'}, ch.title))
|
||||
m('li', [
|
||||
m('a.leftalign', {href: 'chapter_' + zeroFill(3, num + 1) + '.xhtml'}, ch.title)
|
||||
// m('span.date', [m('b', ' · '), prettyDate(new Date(ch.date_modified * 1000)), m('span', {style: 'display: none'}, ' · ')]),
|
||||
// m('.floatbox', m('span.wordcount', ch.realWordCount.toLocaleString('en-GB')))
|
||||
])
|
||||
)))
|
||||
])
|
||||
])
|
||||
|
@ -254,17 +258,26 @@ export function createCoverPage (coverFilename, w, h) {
|
|||
return coverPage
|
||||
}
|
||||
|
||||
function dateBox (heading, date) {
|
||||
return m('.datebox', m('.wrap', [
|
||||
function infoBox (heading, data) {
|
||||
return m('.infobox', m('.wrap', [
|
||||
m('span.heading', heading),
|
||||
m('br'),
|
||||
m('span.date', prettyDate(date))
|
||||
m('span.data', data)
|
||||
]))
|
||||
}
|
||||
|
||||
function calcWordCount (chapters) {
|
||||
let count = 0
|
||||
for (let i = 0; i < chapters.length; i++) {
|
||||
let ch = chapters[i]
|
||||
count += ch.realWordCount
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
export function createTitlePage (ffc) {
|
||||
let titlePage = '<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE html>\n' + pretty.xml(render(
|
||||
m('html', {xmlns: NS.XHTML, 'xmlns:epub': NS.OPS, lang: 'en', 'xml:lang': 'en'}, [
|
||||
m('html', {xmlns: NS.XHTML, 'xmlns:epub': NS.OPS}, [
|
||||
m('head', [
|
||||
m('meta', {charset: 'utf-8'}),
|
||||
m('link', {rel: 'stylesheet', type: 'text/css', href: '../Styles/style.css'}),
|
||||
|
@ -277,23 +290,27 @@ export function createTitlePage (ffc) {
|
|||
m('.author', ['by ', m('b', ffc.storyInfo.author.name)])
|
||||
]),
|
||||
m('.readlink', m('a', {href: ffc.storyInfo.url}, 'Read on Fimfiction')),
|
||||
m('hr'),
|
||||
m('#categories', [
|
||||
// m('hr'),
|
||||
m('.categories', [
|
||||
m('div', {className: 'content-rating-' + ffc.storyInfo.content_rating_text.toLowerCase()}, ffc.storyInfo.content_rating_text.charAt(0).toUpperCase()),
|
||||
ffc.categories.map((tag) =>
|
||||
m('div', {className: tag.className}, tag.name)
|
||||
)
|
||||
]),
|
||||
m('hr'),
|
||||
// m('hr'),
|
||||
ffc.storyInfo.prequel ? [m('div', [
|
||||
'This story is a sequel to ',
|
||||
m('a', {href: ffc.storyInfo.prequel.url}, ffc.storyInfo.prequel.title)
|
||||
]), m('hr')] : null,
|
||||
m('#description', m.trust(ffc.storyInfo.description)),
|
||||
m('hr'),
|
||||
m('.extra_story_data', [
|
||||
ffc.storyInfo.publishDate && dateBox('First Published', new Date(ffc.storyInfo.publishDate * 1000)),
|
||||
dateBox('Last Modified', new Date(ffc.storyInfo.date_modified * 1000)),
|
||||
m('.bottom', [
|
||||
m('span', {className: 'completed-status-' + ffc.storyInfo.status.toLowerCase()}, ffc.storyInfo.status),
|
||||
ffc.storyInfo.publishDate && infoBox('First Published', prettyDate(new Date(ffc.storyInfo.publishDate * 1000))),
|
||||
infoBox('Last Modified', prettyDate(new Date(ffc.storyInfo.date_modified * 1000))),
|
||||
infoBox('Word Count', calcWordCount(ffc.storyInfo.chapters).toLocaleString('en-GB'))
|
||||
]),
|
||||
// m('hr'),
|
||||
m('.characters', [
|
||||
ffc.tags.map((t) =>
|
||||
m('span', {className: 'character_icon', title: t.name}, m('img', {src: t.image, className: 'character_icon'}))
|
||||
)
|
||||
|
|
|
@ -38,28 +38,31 @@
|
|||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
.extra_story_data {
|
||||
.categories {
|
||||
text-align: left;
|
||||
margin: 0.5em 0;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.characters {
|
||||
margin-top: 0.5em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
// Last Modified and First Published
|
||||
.datebox {
|
||||
textcolor(#222);
|
||||
padding-left: 10px;
|
||||
.infobox {
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: 0.5em;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
padding: 0 10px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 4px;
|
||||
border-radius: 3px;
|
||||
bgcolor(#fff);
|
||||
vertical-align: middle;
|
||||
border: 1px solid #999;
|
||||
margin: 0px 2px;
|
||||
margin-bottom: 6px;
|
||||
height: 2em;
|
||||
|
||||
.heading, .date {
|
||||
.heading, .data {
|
||||
font-family: sans-serif;
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
|
@ -74,15 +77,16 @@
|
|||
|
||||
.heading {
|
||||
font-weight: normal;
|
||||
textcolor(#444);
|
||||
color: #444;
|
||||
}
|
||||
}
|
||||
|
||||
// Character icon
|
||||
span.character_icon {
|
||||
vertical-align: middle;
|
||||
margin: 0 2px;
|
||||
padding: 3px;
|
||||
margin: 0;
|
||||
margin-right: 0.2em;
|
||||
padding: 0.2em;
|
||||
bgcolor(#fff);
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
|
@ -123,10 +127,39 @@ span.character_icon {
|
|||
box-shadow: 0px 1px 0px #e64938 inset;
|
||||
}
|
||||
|
||||
// Categories
|
||||
#categories {
|
||||
text-align: left;
|
||||
// Statuses
|
||||
.completed-status-complete, .completed-status-incomplete, .completed-status-hiatus, .completed-status-cancelled {
|
||||
margin-bottom: 0.5em;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
font-weight: normal;
|
||||
padding: 0.3em 0.6em;
|
||||
text-shadow: -1px -1px rgba(0,0,0,0.2);
|
||||
border: 1px solid rgba(0,0,0,0.15);
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
textcolor(#fff);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.completed-status-complete {
|
||||
bgcolor(#63bd40);
|
||||
}
|
||||
|
||||
.completed-status-incomplete {
|
||||
bgcolor(#F7A616);
|
||||
}
|
||||
|
||||
.completed-status-hiatus {
|
||||
bgcolor(#bd7b40);
|
||||
}
|
||||
|
||||
.completed-status-cancelled {
|
||||
bgcolor(#bc3131);
|
||||
}
|
||||
|
||||
// Categories
|
||||
.story_category {
|
||||
display: inline-block;
|
||||
padding: 0.5em;
|
||||
|
@ -135,7 +168,7 @@ span.character_icon {
|
|||
bgcolor(#eee);
|
||||
textcolor(#fff);
|
||||
border-radius: 4px;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 0.3em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue