阅读与排版内容编辑
EPUB 模板写法速查
EPUB 编辑器片段模板能写的全部内容:片段源码、样式、占位符和取值方式、查找规则,以及「用 AI 写模板」从剪贴板导入用的 JSON 格式。
适用版本:Reeden 2.0.0 及以上。这里没列出的写法不支持。
片段模板是一段带占位符的 HTML,加上它自己的样式。在 EPUB 编辑器里可以插入到光标处、套到选中的几段上,或者按查找规则批量套到全书。
用 AI 写模板
- 打开 EPUB 编辑器的模板库,点右上角的菜单,选「用 AI 写模板」,提示词会复制到剪贴板。
- 把提示词发给任意 AI 助手,在末尾写上想要的样式,比如「网友评论卡片,头像、昵称、楼层号和时间排一行,下面是评论内容;昵称从几个网名里随机,楼层从 3 楼开始往上加」。
- 复制 AI 的完整回复,回到模板库菜单,选「从剪贴板导入」。
- 导入前会列出每个模板的效果预览。有错误的模板不能勾选,有提示的可以照常导入。
1. 导入格式
从剪贴板导入时,内容是一个 JSON 对象(可以包在 ```json 代码块里):
{
"reedenTemplates": 1,
"templates": [
{
"name": "模板名",
"html": "<div class=\"rd-card\"><p>{{正文}}</p></div>",
"css": ".rd-card { border: 1px solid #ccc; }",
"fields": [
{ "id": "正文", "isBody": true }
]
}
]
}每个模板的字段:
| 字段 | 必填 | 说明 |
|---|---|---|
name | 是 | 模板名,简短说清用途 |
html | 是 | 片段源码,见第 2 节 |
css | 否 | 样式,见第 3 节 |
fields | 否 | 占位符的设置,见第 4 节。不写时按源码里的占位符自动生成 |
rule | 否 | 查找规则,见第 6 节。不写表示只能手动插入或套用 |
一次可以导入多个模板。名字、源码和样式都相同的模板已经存在时跳过。
2. 片段源码(html 字段)
- 写成 XHTML:标签必须配对闭合,空元素写成
<br/>、<img .../>,属性值加引号。 - 用
{{名字}}标出要填的内容。名字可以是中文,它同时是填写表单里的标签。 - 结构只写
class,样式放在css里,不要写style="…"、<style>。 - 不能有
<script>,也不要引用书外的图片、字体或链接。需要图形时用边框、背景色、圆角这些 CSS 画;确实要用图片、音频,在模板编辑框里加「资源」,见下文 模板带图片和音频。 - 最外层只放一个元素(比如一个
<div>)。套用时会给它加一个用来识别的 class,不影响样式。 - 正文占位符只写一处。想让几条内容样式各不相同,模板里只写一条,在样式里用
.名字 + .名字区分第 2、3 条(见第 7 节)。 - JSON 里的双引号要转义:
class="x"写成class=\"x\"。
3. 样式(css 字段)
- 普通 CSS 规则,套用时写进书里的
reeden-custom.css,同一个模板套多少处都只有一份。 - class 名加一个前缀(比如
rd-),避免和书里原有的样式重名。 - 选择器写成
.rd-card .rd-title这样,限定在模板自己的元素里,不要写p { }、div { }这种会影响全书的规则。 - 尺寸用
em,跟着阅读字号缩放;不要写死很大的px宽度,手机上一行只有 18–20 个字。 - 颜色写具体的值(
#c8336a、rgba(0, 0, 0, 0.06))。浅色背景用半透明,深色主题下也不会太亮。 - 能用的:边框、圆角、背景色和渐变、内外边距、字体字号颜色、行高、
text-indent、display: block / inline-block、float、::before/::after和content、计数器、box-shadow。 - 不要用:
grid、position: fixed、动画、@import、@font-face。flex在 Reeden 里能用,但部分阅读器不支持,书要拿到别的阅读器看时优先用inline-block和float。 - 段落默认有首行缩进,卡片里的段落一般要写
text-indent: 0。
4. 占位符(fields 字段)
每个占位符一项,id 和源码里 {{}} 中的名字一致:
| 字段 | 说明 |
|---|---|
id | 占位符名字 |
label | 填写表单里显示的名字,不写时用 id |
default | 预填值 |
isBody | 正文占位符:套到选中段落时放段落内容。一个模板只设一个 |
multiline | 填写时允许多行 |
value | 取值方式,见第 5 节。不写就是固定值,每条都填 default |
没写 isBody 时,叫 body 的占位符、或者第一个名字里带「正文」「内容」的占位符会当作正文。
5. 取值方式(value 字段)
套到几段上、或者按规则套到全书时,每条现算一个值,适合评论区的昵称、楼层号这类每条不一样的内容。算出来的值作为普通文字写进书里。
{ "id": "昵称", "value": { "mode": "pick", "choices": ["路人甲", "匿名网友", "吃瓜群众"] } }
{ "id": "楼层", "value": { "mode": "sequence", "start": 3, "stepMin": 1, "stepMax": 8 } }
{ "id": "点赞", "value": { "mode": "number", "min": 1, "max": 999 } }| mode | 设置 | 效果 |
|---|---|---|
pick | choices:候选列表;noRepeat:相邻两条不重复,默认 true | 每条从候选里挑一个 |
sequence | start:起始值;stepMin、stepMax:每次加多少 | 第一条是起始值,之后每条加一个范围里的随机数。两个数相同就是固定步长 |
number | min、max | 每条取范围里的一个整数 |
- 数字只填数字本身,前后的符号写在源码里:楼层写成
#{{楼层}}、{{楼层}} 楼。 - 每次套用从起始值重新数;按规则套到全书时每章各自从起始值数。
- 正文占位符不能设取值方式。
6. 查找规则(rule 字段)
按正则在章节源码里找,找到的每一处都套一次模板:
"rule": { "pattern": "<p>【(?<text>[^】]*)】</p>", "mode": "replace", "firstMatchOnly": false }| 字段 | 说明 |
|---|---|
pattern | 正则,匹配章节的 HTML 源码(不是纯文字)。. 能跨行,不区分大小写 |
mode | replace(默认,替换找到的内容)、insertBefore(插到前面)、insertAfter(插到后面) |
firstMatchOnly | 每章只处理第一处,默认 false |
- 在占位符的
default里写$1、$text引用捕获到的内容,比如正文的default写"$text"。 - JSON 里的反斜杠要转义:
\s写成"\\s"。 - 一段一段地匹配(
<p>…</p>),不要写能跨很多段的贪婪匹配。
7. 示例
网友评论:昵称随机、楼层递增,几条连着的评论用 + 选择器换颜色。
{
"reedenTemplates": 1,
"templates": [
{
"name": "网友评论",
"html": "<div class=\"rd-cmt\"><p class=\"rd-cmt-head\"><span class=\"rd-cmt-name\">{{昵称}}</span><span class=\"rd-cmt-meta\">#{{楼层}} · {{时间}}</span></p><p class=\"rd-cmt-body\">{{正文}}</p></div>",
"css": ".rd-cmt { margin: 0.4em 0; padding: 0.5em 0.9em; border: 1px solid rgba(127, 127, 127, 0.25); border-radius: 10px; background-color: rgba(59, 130, 246, 0.06); }\n.rd-cmt + .rd-cmt { background-color: rgba(236, 72, 153, 0.06); }\n.rd-cmt + .rd-cmt + .rd-cmt { background-color: rgba(34, 197, 94, 0.06); }\n.rd-cmt p { text-indent: 0; margin: 0; }\n.rd-cmt-head { font-size: 0.85em; }\n.rd-cmt-name { font-weight: bold; }\n.rd-cmt-meta { float: right; color: rgba(127, 127, 127, 0.9); }\n.rd-cmt-body { margin-top: 0.3em; line-height: 1.6; }",
"fields": [
{ "id": "正文", "isBody": true },
{ "id": "昵称", "value": { "mode": "pick", "choices": ["路人甲", "匿名网友", "吃瓜群众", "深夜潜水员"] } },
{ "id": "楼层", "value": { "mode": "sequence", "start": 3, "stepMin": 1, "stepMax": 8 } },
{ "id": "时间", "value": { "mode": "pick", "choices": ["刚刚", "1 分钟前", "3 分钟前"] } }
]
},
{
"name": "作者有话说",
"html": "<div class=\"rd-note\"><p class=\"rd-note-title\">{{标题}}</p><p class=\"rd-note-body\">{{正文}}</p></div>",
"css": ".rd-note { margin: 1.2em 0; padding: 0.7em 1em; border: 1px dashed rgba(127, 127, 127, 0.5); border-radius: 8px; }\n.rd-note p { text-indent: 0; margin: 0; }\n.rd-note-title { font-weight: bold; font-size: 0.9em; margin-bottom: 0.4em; }",
"fields": [
{ "id": "标题", "default": "作者有话说" },
{ "id": "正文", "isBody": true, "default": "$note" }
],
"rule": { "pattern": "<p\\b[^>]*>\\s*作者有话说[::]\\s*(?<note>[^<]*)</p>" }
}
]
}模板带图片和音频
AI 写的模板和剪贴板导入只能写源码和样式。需要图片、音频时,导入后在模板库里打开这个模板的编辑框,在「资源」里「添加文件」:
- 在源码或样式里用
local:/引用,/指书的 OPF 所在目录,比如<img src="local:/Images/star.png"/>、<audio src="local:/Audio/bell.mp3"></audio>、background: url(local:/Images/bg.png)。每个文件旁边的复制按钮可以直接拿到写法,「修改路径」改它在书里的位置 - 套用模板时,书里没有这个文件就写进去,同路径已有就用书里那份;引用会换成相对路径
- 单个文件不超过 2 MB,一个模板合计不超过 5 MB。没被引用的文件会标「未引用」
8. 常见错误
- 标签没闭合(
<br>、<img ...>),导入时报「标签没有配对闭合」。 - 正文占位符写了好几处,套用时只有第一处有内容。
- 样式写在
style="…"或<style>里,换模板、改样式都要一处处改。 - 选择器没加前缀(
.card、p),和书里原有的样式互相影响。 - 宽度写死成
px,手机上挤成一列或者超出屏幕。
Reeden