Add word count, fixes #3. New synopsis layout

This commit is contained in:
daniel-j 2016-08-21 21:48:40 +02:00
parent 9ad70f66b1
commit caea25cd22
4 changed files with 116 additions and 39 deletions

View file

@ -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(() => {

View file

@ -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] {

View file

@ -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'}))
)

View file

@ -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;
}