优化epub解析;优化目录;
parent
1155252604
commit
f1fe597317
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "org.bytedo.epub",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "E-pub Reader",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1 +1 @@
|
|||
html{width:100%;height:100vh}body{display:flex;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app{position:relative;display:flex;width:100%;height:100%}.app .toc{width:260px;height:100%}.app .toc item{display:flex;align-items:center;height:36px;padding:0 12px;border-bottom:1px solid var(--color-plain-1);cursor:pointer}.app .toc item.lev-0{font-weight:bold}.app .toc item.lev-1{padding-left:24px;font-weight:bold}.app .toc item.lev-2{padding-left:36px}.app .toc item.lev-3{padding-left:48px}.app .toc item:hover{color:var(--color-blue-1)}.app .toc item.active{color:#fff;background:var(--color-blue-1)}.app .toc item:last-child{border-bottom:0}.app .chapter-box{flex:1;height:100%;border-left:1px solid var(--color-plain-2)}.app .chapter{display:flex;justify-content:center;padding:8px 24px}.app .chapter .detail{max-width:768px;line-height:1.5;font-size:14px}.app .chapter .detail a{text-decoration:underline;color:var(--color-teal-2)}.app .chapter .detail a:hover{color:var(--color-teal-1);text-decoration:none}.app .chapter .detail em,.app .chapter .detail del{color:var(--color-grey-2)}.app .chapter .detail strong,.app .chapter .detail strong em,.app .chapter .detail strong{color:var(--color-dark-3)}.app .chapter .detail a strong,.app .chapter .detail a em{color:inherit}.app .chapter .detail em,.app .chapter .detail strong,.app .chapter .detail del{padding:0 2px}.app .chapter .detail img{max-width:100%}.app .chapter .detail blockquote{margin:10px 0;padding:5px 10px;line-height:1.5;border-left:5px solid var(--color-teal-1);background:#f2faf7;color:var(--color-grey-2)}.app .chapter .detail blockquote p{margin:0}.app .chapter .detail code{display:inline;margin:0 2px;padding:0 2px;color:var(--color-orange-3);background:var(--color-plain-1);border-radius:2px;font-family:Menlo, Monaco, Consolas, 'Courier New', monospace}.app .chapter .detail>p{margin:12px 0}.app .chapter .detail ol{margin-left:1em;list-style:decimal outside none}.app .chapter .detail ul{margin-left:1em;list-style:disc outside none}.app .chapter .detail li{margin:0.5em 0}.app .chapter .detail li ol{margin-left:1em}.app .chapter .detail li ul{margin-left:1em;list-style-type:circle}.app .chapter .detail li ol ul,.app .chapter .detail li ul ul{list-style-type:square}.app .chapter .detail h1,.app .chapter .detail h2,.app .chapter .detail h3,.app .chapter .detail h4,.app .chapter .detail h5,.app .chapter .detail h6{margin:15px 0;line-height:2;font-weight:bold;font-size:16px}.app .chapter .detail h1 code,.app .chapter .detail h2 code,.app .chapter .detail h3 code,.app .chapter .detail h4 code,.app .chapter .detail h5 code,.app .chapter .detail h6 code{background:none}.app .chapter .detail h1 a,.app .chapter .detail h2 a,.app .chapter .detail h3 a,.app .chapter .detail h4 a,.app .chapter .detail h5 a,.app .chapter .detail h6 a{text-decoration:none;color:#333}.app .chapter .detail h3 a::before,.app .chapter .detail h4 a::before,.app .chapter .detail h5 a::before,.app .chapter .detail h6 a::before{content:'∮ ';color:var(--color-teal-1);font-weight:normal}.app .chapter .detail h1{margin:0 0 30px;font-size:24px;text-align:center}.app .chapter .detail h2{margin:20px 0;font-size:22px;border-bottom:1px solid var(--color-plain-2)}.app .chapter .detail h3{margin:20px 0 15px;font-size:20px}.app .chapter .detail h4{font-size:18px}.app .chapter .detail table{width:100%;border-spacing:0;border-collapse:collapse}.app .chapter .detail table tr{background-color:#fff}.app .chapter .detail table thead tr{background:var(--color-plain-1)}.app .chapter .detail table th,.app .chapter .detail table td{padding:6px 13px;border:1px solid var(--color-plain-2)}.app .chapter .detail table th{font-weight:bold}.app .chapter .detail table tr:nth-child(2n){background-color:#fcfdff}
|
||||
html{width:100%;height:100vh}body{display:flex;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app{position:relative;display:flex;width:100%;height:100%}.app .toc{width:260px;height:100%}.app .toc item{display:flex;align-items:center;height:36px;padding:0 12px;border-bottom:1px solid var(--color-plain-1);cursor:pointer}.app .toc item.lev-0{font-weight:bold}.app .toc item.lev-1{padding-left:24px;font-weight:bold}.app .toc item.lev-2{padding-left:36px}.app .toc item.lev-3{padding-left:48px}.app .toc item:hover{color:var(--color-blue-1)}.app .toc item.active{color:#fff;background:var(--color-blue-1)}.app .toc item:last-child{border-bottom:0}.app .chapter-box{flex:1;height:100%;border-left:1px solid var(--color-plain-2)}.app .chapter{display:flex;justify-content:center;padding:8px 24px}.app .chapter .detail{width:100%;max-width:768px;line-height:1.5;font-size:14px}.app .chapter .detail .cover{display:block;width:100%;height:calc(100vh - 16px);-o-object-fit:contain;object-fit:contain}.app .chapter .detail a{text-decoration:underline;color:var(--color-teal-2)}.app .chapter .detail a:hover{color:var(--color-teal-1);text-decoration:none}.app .chapter .detail em,.app .chapter .detail del{color:var(--color-grey-2)}.app .chapter .detail strong,.app .chapter .detail strong em,.app .chapter .detail strong{color:var(--color-dark-3)}.app .chapter .detail a strong,.app .chapter .detail a em{color:inherit}.app .chapter .detail em,.app .chapter .detail strong,.app .chapter .detail del{padding:0 2px}.app .chapter .detail img{max-width:100%}.app .chapter .detail blockquote{margin:10px 0;padding:5px 10px;line-height:1.5;border-left:5px solid var(--color-teal-1);background:#f2faf7;color:var(--color-grey-2)}.app .chapter .detail blockquote p{margin:0}.app .chapter .detail code{display:inline;margin:0 2px;padding:0 2px;color:var(--color-orange-3);background:var(--color-plain-1);border-radius:2px;font-family:Menlo, Monaco, Consolas, 'Courier New', monospace}.app .chapter .detail>p{margin:12px 0}.app .chapter .detail ol{margin-left:1em;list-style:decimal outside none}.app .chapter .detail ul{margin-left:1em;list-style:disc outside none}.app .chapter .detail li{margin:0.5em 0}.app .chapter .detail li ol{margin-left:1em}.app .chapter .detail li ul{margin-left:1em;list-style-type:circle}.app .chapter .detail li ol ul,.app .chapter .detail li ul ul{list-style-type:square}.app .chapter .detail h1,.app .chapter .detail h2,.app .chapter .detail h3,.app .chapter .detail h4,.app .chapter .detail h5,.app .chapter .detail h6{margin:15px 0;line-height:2;font-weight:bold;font-size:16px}.app .chapter .detail h1 code,.app .chapter .detail h2 code,.app .chapter .detail h3 code,.app .chapter .detail h4 code,.app .chapter .detail h5 code,.app .chapter .detail h6 code{background:none}.app .chapter .detail h1 a,.app .chapter .detail h2 a,.app .chapter .detail h3 a,.app .chapter .detail h4 a,.app .chapter .detail h5 a,.app .chapter .detail h6 a{text-decoration:none;color:#333}.app .chapter .detail h3 a::before,.app .chapter .detail h4 a::before,.app .chapter .detail h5 a::before,.app .chapter .detail h6 a::before{content:'∮ ';color:var(--color-teal-1);font-weight:normal}.app .chapter .detail h1{margin:0 0 30px;font-size:24px;text-align:center}.app .chapter .detail h2{margin:20px 0;font-size:22px;border-bottom:1px solid var(--color-plain-2)}.app .chapter .detail h3{margin:20px 0 15px;font-size:20px}.app .chapter .detail h4{font-size:18px}.app .chapter .detail table{width:100%;border-spacing:0;border-collapse:collapse}.app .chapter .detail table tr{background-color:#fff}.app .chapter .detail table thead tr{background:var(--color-plain-1)}.app .chapter .detail table th,.app .chapter .detail table td{padding:6px 13px;border:1px solid var(--color-plain-2)}.app .chapter .detail table th{font-weight:bold}.app .chapter .detail table tr:nth-child(2n){background-color:#fcfdff}
|
||||
|
|
|
@ -78,10 +78,18 @@ body {
|
|||
padding: 8px 24px;
|
||||
|
||||
.detail {
|
||||
width: 100%;
|
||||
max-width: 768px;
|
||||
line-height: 1.5;
|
||||
font-size: 14px;
|
||||
|
||||
.cover {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: calc(100vh - 16px);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: var(--color-teal-2);
|
||||
|
|
|
@ -88,15 +88,18 @@ Anot({
|
|||
fetch(`book://cache/${this.book}/${file}`)
|
||||
.then(r => r.text())
|
||||
.then(txt => {
|
||||
this.chapter = txt.replace(
|
||||
/<img[^>]*?src="(.*?)"[^>]*?\/?>/g,
|
||||
(m, s1) => {
|
||||
// s1 = s1.replace('../', '')
|
||||
this.chapter = txt
|
||||
.replace(/<img[^>]*?src="(.*?)"[^>]*?\/?>/g, (m, s1) => {
|
||||
s1 = join(dirname(file), s1)
|
||||
console.log(file, s1)
|
||||
return `<img src="book://cache/${this.book}/${s1}">`
|
||||
}
|
||||
)
|
||||
})
|
||||
.replace(/<image[^>]*?xlink:href="(.*?)"[^>]*?\/?>/g, (m, s1) => {
|
||||
s1 = join(dirname(file), s1)
|
||||
return `<img class="cover" src="book://cache/${
|
||||
this.book
|
||||
}/${s1}">`
|
||||
})
|
||||
.replace(/<\/?svg>/g, '')
|
||||
|
||||
setTimeout(() => {
|
||||
if (hash) {
|
||||
|
|
|
@ -63,6 +63,8 @@ module.exports = function(app, createViewWindow) {
|
|||
let { title } = eb.metadata
|
||||
let cover = ''
|
||||
let dir = path.join(CACHE_DIR, title)
|
||||
let dict = {}
|
||||
let toc = []
|
||||
|
||||
function saveImage(id, name) {
|
||||
return new Promise(done => {
|
||||
|
@ -90,13 +92,12 @@ module.exports = function(app, createViewWindow) {
|
|||
.replace(/<pre>/g, '<wc-code>')
|
||||
.replace(/<\/pre>/g, '</wc-code>')
|
||||
|
||||
htm = htm.replace(/<wc-code>([\w\W]*?)<\/wc-code>/g, function(
|
||||
m,
|
||||
s
|
||||
) {
|
||||
s = s.replace(/<\/?\w+>/g, '')
|
||||
return `<wc-code>${s}</wc-code>`
|
||||
})
|
||||
htm = htm
|
||||
.replace(/<wc-code>([\w\W]*?)<\/wc-code>/g, function(m, s) {
|
||||
s = s.replace(/<\/?\w+>/g, '')
|
||||
return `<wc-code>${s}</wc-code>`
|
||||
})
|
||||
.trim()
|
||||
|
||||
fs.echo(htm, path.join(dir, name.replace('.xhtml', '.html')))
|
||||
} else {
|
||||
|
@ -116,7 +117,10 @@ module.exports = function(app, createViewWindow) {
|
|||
break
|
||||
|
||||
case 'application/x-dtbncx+xml':
|
||||
fs.echo(JSON.stringify(eb.toc), path.join(dir, 'toc.json'))
|
||||
eb.toc.forEach(_ => {
|
||||
dict[_.id] = _
|
||||
})
|
||||
|
||||
break
|
||||
|
||||
case 'application/xhtml+xml':
|
||||
|
@ -133,6 +137,39 @@ module.exports = function(app, createViewWindow) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
toc = eb.flow.map((it, i) => {
|
||||
let tmp = dict[it.id] || { level: i === 0 ? i : undefined }
|
||||
if (!tmp.hasOwnProperty('level')) {
|
||||
tmp.level = 1
|
||||
}
|
||||
if (it.id === 'titlepage') {
|
||||
it.level = 0
|
||||
it.title = '封面'
|
||||
} else {
|
||||
it.level = tmp.level
|
||||
let cp
|
||||
|
||||
if (it.title) {
|
||||
cp = it.title
|
||||
} else {
|
||||
cp = fs
|
||||
.cat(path.join(dir, it.href.replace('.xhtml', '.html')))
|
||||
.toString()
|
||||
cp = cp.split(/[\r\n]/).shift()
|
||||
cp = cp.replace(/<\/?[\w\-]+[^>]*?>/g, '').trim()
|
||||
}
|
||||
|
||||
it.title = cp
|
||||
.slice(0, 20)
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
}
|
||||
return it
|
||||
})
|
||||
|
||||
fs.echo(JSON.stringify(toc), path.join(dir, 'toc.json'))
|
||||
|
||||
if (!cover) {
|
||||
cover = 'cover.webp'
|
||||
app.__main__.webContents.send('app', {
|
||||
|
|
Loading…
Reference in New Issue