前言

Calibre 是个管理电子书的工具,简单来说,如果你的电子书乱成一团,它能帮你整理得井井有条。Calibre 能转换电子书格式,改书名、换封面、整理分类,批量修改元数据等。

本期分享PC端Calibre使用过程中遇到的的一些问题和解决办法,附带WEB端的Docker搭建方法。

Calibre下载

书籍载入错误

点击阅读时出现无法加载书籍

错误图片

报错

错误详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
calibre, version 8.0.1
错误: 无法加载书籍: 无法打开位于 P:\书籍\__Zhu Rong Ji Da Ji Zhe Wen __ Bian\Zhu Rong Ji Da Ji Zhe Wen (175)\Zhu Rong Ji Da Ji Zhe Wen - __Zhu Rong Ji Da Ji Zhe Wen __ .epub 的书籍,点击“显示详情”获取更多信息。

Failed to convert book: P:\书籍\__Zhu Rong Ji Da Ji Zhe Wen __ Bian\Zhu Rong Ji Da Ji Zhe Wen (175)\Zhu Rong Ji Da Ji Zhe Wen - __Zhu Rong Ji Da Ji Zhe Wen __ .epub with error:
InputFormatPlugin: EPUB Input running
on P:\书籍\__Zhu Rong Ji Da Ji Zhe Wen __ Bian\Zhu Rong Ji Da Ji Zhe Wen (175)\Zhu Rong Ji Da Ji Zhe Wen - __Zhu Rong Ji Da Ji Zhe Wen __ .epub
Found HTML cover OPS/coverpage.html
Failed to run pipe worker with command: from calibre.srv.render_book import viewer_main; viewer_main()
Traceback (most recent call last):
File "runpy.py", line 198, in _run_module_as_main
File "runpy.py", line 88, in _run_code
File "site.py", line 83, in <module>
File "site.py", line 78, in main
File "site.py", line 50, in run_entry_point
File "calibre\utils\ipc\worker.py", line 196, in main
File "<string>", line 1, in <module>
File "calibre\srv\render_book.py", line 845, in viewer_main
File "calibre\srv\render_book.py", line 836, in render_for_viewer
File "calibre\srv\render_book.py", line 814, in render
File "calibre\srv\render_book.py", line 616, in process_exploded_book
calibre.srv.render_book.Spineless: Book is empty, no content in spine

查找原因

改epub文件后缀为.zip,解压软件解压

如果.epub 缺少content.opf文件或即使存在content.opf文件但是里面没有spine标签,就会导致 Calibre 无法正确解析。

content.opf

解决方法

选中这本书,右键转换书籍,单个转换,输入输出格式默认epub即可,其他也默认,直接点击确定。

会把这本epub格式的书籍重新转换成标准的epub格式,输出的目录和源书籍同一个目录。

调整行间距

有的书籍的行距很小,影响阅读体验。Calibre支持自定义书籍行间距。

调整前后的对比

行间距对比

调整方法

点击查看调整方法

打开你想阅读的电子书,在calibre电子书查看器中,依次“右键 - 首选项 - 样式”,然后, 在css样式框里添加自定义样式,如下:

1
body{line-height:36px}

如果以上代码对样式无效,就换下面的代码:

1
p{line-height:36px}

行距修改

书库拼音目录问题

添加书籍后书库的目录命名是以作者名字的字母拼音命名

问题详情

中文书籍的目录名字是拼英,非常不直观。

拼音目录

解决方法

安装 NoTrans插件解决

NoTrans插件的github地址

  1. 下载 NoTrans.zip
  2. 打开 Calibre - 首选项 - [高级选项] 插件 - 从文件加载插件(右下角) - 选择下载的 zip 文件
  3. 重启 Calibre
  4. 享受

插件推荐

大部分摘自Calibre 插件推荐

书籍元数据修改

导入书籍后出现书名有推广,或者有有其他“废话”

问题详情

书名

书名不对,影响后续元数据下载

解决方法

书籍不多的情况下,可以导入后右键编辑元数据进行修改。

书籍多的情况,可以结合以下命令通过脚本批量修改。

  • 查看书籍元数据
1
ebook-meta "你的书籍.azw3"
  • 更改数据元数据(以标题为例)
1
ebook-meta "三体全集.套装共3册.azw3" --title "三体全集"

元数据

Txt转Epub

txt转成epub标准格式的书籍,主页涉及以下三个方面

  • 字体
  • 文字样式
  • 目录

字体

选中要转换的书籍,右键,转换书籍,选择界面外观,点击嵌入字体选项,选择或上传字体

修改字体

文字样式

在界面外观选线里面自定义喜欢的样式

自定义样式

这里给个样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
少数派CSS:
/* Sspai Web Theme A theme to [sspai](ssp.ai) default theme. Developed by Codegass(wchweichenhao@gmial.com) & Yves(yves@sspai.com) Download Cuto on the App Store and Google Play! */

body {
font-size: 15px;
color: #333;
background: #fff;
font-family: Helvetica, Arial, "PingFang SC", "Microsoft YaHei", "WenQuanYi Micro Hei", "tohoma,sans-serif";
margin: 0;
padding: 10%;
}
h1 {
font-size: 2.2em;
font-weight: 700;
line-height: 1.1;
padding-top: 16px;
margin-bottom: 4px;
}
h2, h3, h4, h5, h6 {
line-height: 1.5em;
margin-top: 2.2em;
margin-bottom: 4px;
}
h2 {
font-size: 1.4em;
margin: 40px 10px 20px 0;
padding-left: 9px;
border-left: 6px solid #ff7e79;
font-weight: 700;
line-height: 1.4;
}
h3 {
font-weight: 700;
font-size: 1.2em;
line-height: 1.4;
margin: 10px 0 5px;
padding-top: 10px;
}
h4 {
font-weight: 700;
text-transform: uppercase;
font-size: 1.1em;
line-height: 1.4;
margin: 10px 0 5px;
padding-top: 10px
}
h5, h6 {
font-size: .9em;
}
h5 {
font-weight: bold;
text-transform: uppercase;
}
h6 {
font-weight: normal;
color: #AAA;
}
img {
width: 100%;
border-radius: 5px;
display: block;
margin-bottom: 15px;
height: auto;
}
dl, ol, ul {
margin-top: 12px;
margin-bottom: 20px;
padding-left: 5%;
line-height: 1.8;
}
p {
margin: 0 0 20px;
padding: 0;
line-height: 1.8;
}
a {
color: #f22f27;
text-decoration: none;
}
a:hover {
color: #f55852;
text-decoration: underline;
}
a:focus {
outline-offset: -2px;
}
blockquote {
font-size: 1em;
font-style: normal;
padding: 30px 38px;
margin: 0 0 15px;
position: relative;
line-height: 1.8;
text-indent: 0;
border: none;
color: #888;
}
blockquote:before {
content: "“";
left: 12px;
top: 0;
color: #E0E0E0;
font-size: 4em;
font-family: Arial, serif;
line-height: 1em;
font-weight: 700;
position: absolute;
}
blockquote:after {
content: "”";
right: 12px;
bottom: -26px;
color: #E0E0E0;
font-size: 4em;
font-family: Arial, serif;
line-height: 1em;
font-weight: 700;
position: absolute;
bottom: -31px;
}
strong, dfn {
font-weight: 700;
}
em, dfn {
font-style: italic;
font-weight: 400;
}
del {
text-decoration: line-through;
}
/*code {font-size:90%;}*/

/*pre {text-align:left; overflow-x: scroll; color: #257fa0; background: #f6f6f6; padding: 10pt 15pt; border-radius: 3px; border: solid 1px #e2e2e2;}*/

pre {
margin: 0 0 10px;
font-size: 13px;
line-height: 1.42857;
word-break: break-all;
word-wrap: break-word;
border-radius: 4px;
white-space: pre-wrap;
display: block;
background: #f8f8f8;
padding: 10px 20px;
border: none;
margin-bottom: 25px;
color: #666;
font-family: Courier, sans-serif;
}
code {
color: #c7254e;
background-color: #f9f2f4;
border-radius: 4px;
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
padding: 2px 4px;
font-size: 90%;
}
p>code {
color: #c7264e;
background-color: #f9f2f4;
font-size: .95em;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
figure {
margin: 1em 0;
}
figcaption {
font-size: 0.75em;
padding: 0.5em 2em;
margin-bottom: 2em;
}
figure img {
margin-bottom: 0px;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
ol p, ul p {
margin-bottom: 0px;
}
li {
margin-bottom: 0.75em;
margin-top: 0.75em;
}
ol#footnotes {
font-size: 0.95em;
padding-top: 1em;
margin-top: 1em;
margin-left: 0;
border-top: 1px solid #eaeaea;
counter-reset: footer-counter;
list-style: none;
color: #555;
padding-left: 5%;
margin: 20px 0;
}
ol#footnotes li {
margin-bottom: 10px;
margin-left: 16px;
font-weight: 400;
line-height: 2;
list-style-type: none;
}
ol#footnotes li:before {
content: counter(footer-counter) ". ";
counter-increment: footer-counter;
font-weight: 800;
font-size: .95em;
}
@keyframes highfade {
0% {
background-color: none;
}
20% {
background-color: yellow;
}
100% {
background-color: none;
}
}
@-webkit-keyframes highfade {
0% {
background-color: none;
}
20% {
background-color: yellow;
}
100% {
background-color: none;
}
}
a:target, ol#footnotes li:target, sup a:target {
animation-name: highfade;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in-out;
-webkit-animation-name: highfade;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
a:target {
border: 0;
outline: 0;
}
animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
a:target {
border: 0;
outline: 0;
}
tion-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
a:target {
border: 0;
outline: 0;
}

样式使用前后对比:

样式对比

目录生成

通过calibre的结构检测可以生成目录。

目录结构的生成,需要根据txt书籍的章节特征来写对应的正则表达式。

纯数字的章节特征

比如某个txt的结构如下

1
2
3
4
5
6
7
8
9
10
11
12
1
  内容
2
  内容
3
  内容
4
  内容
5
  内容
6
  内容

检测章节的Xpath表达式就要这么写

1
//*[re:test(., "^\s*[0-9]+\s*$")]

目录添加

其他

  1. PC端Calibre人工精准抓取元数据常规步骤
    • 拖动书籍到软件页面
    • 选中添加的书籍
    • 右键编辑元数据,逐个编辑元数据
    • 设置Calibre抓取元数据的数据源(“下载元数据”旁边的按钮,勾选安装的豆瓣插件,后续不用再设置)
    • 确保书名没有多余内容,点击“下载元数据”,等待抓取数据
    • 核对抓取的数据和书籍是否一致(从书名和作者看),点击确定,选择封面,点击确定,点击确定
  2. 书籍尽量找epub格式,一般都自带侧边栏目录和样式,而且Calibre也支持epub在线看,其他格式好像不支持。
  3. 找好书源,实在找不到好书源再折腾转换格式之类。

点击下载以上出现的Caliber相关文件

Calibre-web端

可以再搭建个WEB端的Calibre,web端的阅读体验比PC端的好,重要的是配合内网穿透可以异地随时访问家中搭建的书库。

我个人的web端是通过Docker搭建在之前买的N3540小主机上,书库目录映射到PC端Calibre的书库目录,这样就可以避免使用性能较差的N3540来整理书籍,整理的过程使用PC端的Calibre。

docker-compose.yml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: "2.1"
services:
calibre-web:
image: lscr.io/linuxserver/calibre-web:latest
container_name: calibre-web
environment:
- PUID=0
- PGID=0
- TZ=Asia/Shanghai
- DOCKER_MODS=linuxserver/mods:universal-calibre #optional
- OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional
volumes:
- /mnt/gd2/calibre/data:/config
- /mnt/gd2/calibre/library:/books
ports:
- 8983:8083
restart: unless-stopped

启动后,恢复下数据库

注意点:/mnt/gd2/calibre/library目录需要有初始数据(PC端安装好后,上传书籍会自动生成数据库相关文件)

1
2
3
4
5
6
7
8
9
docker exec -it calibre-web sh #进入容器内部

cd /app/calibre/bin #进入bin文件夹

calibredb restore_database --really-do-it --with-library /books #恢复一个数据库

chmod a+w /books/metadata.db #添加写的权限

exit # 退出容器

搭建好后,IOS端想在手机端看书,可以使用KyBook 3

软件配置好Calibre-web的APi就可以

API接口格式:http://ip:port/opds

详细可看KyBook 3 | calibre-web - IOS系统最佳图书伴侣