惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
MongoDB | Blog
MongoDB | Blog
Know Your Adversary
Know Your Adversary
K
Kaspersky official blog
人人都是产品经理
人人都是产品经理
IT之家
IT之家
Recorded Future
Recorded Future
Recent Announcements
Recent Announcements
D
DataBreaches.Net
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
博客园 - 【当耐特】
I
Intezer
Cisco Talos Blog
Cisco Talos Blog
Spread Privacy
Spread Privacy
L
LINUX DO - 热门话题
H
Help Net Security
L
LangChain Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
The GitHub Blog
The GitHub Blog
博客园_首页
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
S
Secure Thoughts
The Register - Security
The Register - Security
Engineering at Meta
Engineering at Meta
T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
C
Cybersecurity and Infrastructure Security Agency CISA
T
Troy Hunt's Blog
罗磊的独立博客
腾讯CDC
Simon Willison's Weblog
Simon Willison's Weblog
Security Latest
Security Latest
Last Week in AI
Last Week in AI
P
Privacy & Cybersecurity Law Blog
Latest news
Latest news
The Cloudflare Blog
Jina AI
Jina AI
小众软件
小众软件
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
F
Full Disclosure
V
V2EX

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Creating Ebooks
questioner · 2026-06-27 · via DEV Community

制作没有数字痕迹的电子书


手工制作的目录

  • 输入
    • 掌握Markdown的基本语法
    • 撰写素材文档
    • 校对素材文档
    • 制作封面图片和插图
  • 准备
    • 安装Calibre
    • 配置Calibre
      • 自动生成的目录
      • 章节分页符
      • 相对固定的输出格式
  • 输出
    • 把素材文档导入书库
    • 编辑元数据
    • 生成书籍并另存为
    • 检查书籍的元数据
      • EPUB
      • DOCX
      • PDF
    • 清理

输入

掌握Markdown的基本语法

Markdown是通用、健壮、易学易读易写、便于移植的轻量级标记语言,教程见Markdown GuideDaring Fireball。主要语法列举如下:

    用至少一个空白行分隔不同段落(包括标题)。
    正常段落没有必要缩进(即空两格),需要时每4个空格( )或1个制表符(TAB)可缩进一级。
    # 一级标题
    ## 二级标题
    ### 三级标题
    #### 四级标题
    **粗体**
    *斜体*
    ***粗体和斜体***
    1. 有序列表第一项
    1. 有序列表第二项
    1. 有序列表第三项
    - 无序列表第一项
    * 无序列表第二项
    + 无序列表第三项
    ```段落之间的等宽字体代码块```
    ``段落内部嵌入的等宽字体代码``
    > 引用的第一个段落
    >
    > 引用的第二个段落
    >> 嵌套引用的段落
    <blockquote>段落之间的多行引用块</blockquote>
    [外部超链接显示名](外部超链接地址)
    [外部超链接显示名](外部超链接地址 "鼠标悬停在链接上时显示的文字提示")
    ![图片无法加载时显示的文字描述](图片路径)
    ![图片无法加载时显示的文字描述](图片路径 "鼠标悬停在图片上时显示的文字提示")
    [^1]: 脚注
    * [目录中的二级标题显示名](#正文中的二级标题)
    * [目录中的二级标题显示名](#二级标题ID)
    <h2 id="二级标题ID">正文中的二级标题</h2>
    <h3 id="三级标题ID">正文中的三级标题</h3>
    \转义符

撰写素材文档

从这里开始,所有步骤建议在虚拟机内执行。为避免泄露制作的日期和时间,应当关闭虚拟机的时间同步功能,修改虚拟机的系统时间。但是时间错误的情况下,依赖证书的网站连接将受到影响。可以先满足联网需求,在输出前才修改时间。在没有虚拟机的情况下,可以修改物理计算机的时间。

在加密分区、容器新建文本文档,后缀名可以是txt、md等,文件名将是电子书的默认书名,但后续步骤中可以修改书名。

按Markdown格式书写需要生成的电子书。在Windows系统中,建议使用记事本等简易的文本编辑器,不建议使用Microsoft Word。

其他格式的现有文档、网页或电子书可以分别依靠Word to MarkdownURL to MarkdownZamzar Epub to MarkdownConvertio eBook Converter等线上转换工具或Calibre等线下转换工具预处理,然后人工校对。

目录可以在后续过程中自动生成,一般不需要按Markdown语法自行撰写。

外部超链接地址应当经过处理,删除跟踪参数。

Markdown的标准语法能够满足绝大多数需要。如有特殊需要,可使用html代码,或支持扩展语法的解析器。更详细的注意事项见Create Clean EPUBs using Calibre

校对素材文档

Markdown格式的文本可以使用以下工具检查是否存在语法错误。

制作封面图片和插图

JPG/JPEG、TIF、PNG、WEBP四种图片可能含有EXIF数据,可能涉及修改时间、制作软件、拍摄设备、经纬度、速度等大量信息。应事先使用以下工具检查和清理:

今后如以EPUB格式输出,图片的修改时间将在嵌入EPUB文件时改为输出的时间。

Markdown的标准语法并不适合复杂的图文混排。为提高对不同系统的兼容性,图片路径应避免使用绝对路径。为避免从互联网下载,图片路径也应避免使用URL。建议把图片与素材文档放在同一个文件夹,在图片路径处直接写图片的文件名,例如image.jpg。文件名应当不包含个人信息,也不包含空格和括号。

Markdown的标准语法也不支持文字居中。如需在图片上方或下方增加图片说明且水平方向居中,可使用以下两种写法:

  • <div align="center">图片说明</div>

  • <center>图片说明</center>

准备

安装Calibre

Calibre是自由软件,可用于阅读、制作、编辑、转换电子书,下载地址calibre-ebook.com。Windows 10以上可使用普通版绿色版,Windows 8最高可使用5.44版,Windows 7最高可使用3.48版。混淆Calibre版本号的一个办法是故意使用旧版本

安装Calibre,通常无需更改默认参数。

首次运行时,将显示配置向导:

  • 语言建议首先选择自己掌握的某门外语,其次可选择Simplified Chinese或Traditional Chinese,不建议选择Chinese。以下说明将提供中英双语。
  • “书库”(Library)位置应选择便于清理的硬盘分区或U盘,重要书籍务必选择加密分区、容器内的空文件夹。绿色版的书库位置默认在绿色版所在的目录,在首次运行时无法在配置向导中修改,需要手动点击“书库”(Library),“切换/创建书库”(Switch/create library)。
  • “设备”(Device)使用默认配置。

配置Calibre

进入主界面后,点击上方大按钮“偏好选项”(Preferences)。有时因为窗口较小没有显示,或者把窗口最大化,或者点击其他大按钮最右侧的竖排三个点┇。

自动生成的目录

在“转换”(Conversion)处,选择“通用选项”(Common options):

  • 点击“目录”(Table of Contents),勾选“创建目录时允许重复的链接”(Allow duplicate links when creating the Table of Contents)。
  • 在一、二、三级目录(Level 1/2/3 TOC)的“XPath表达式”(XPath expression)框内分别输入//h:h1、//h:h2、//h:h3(英语半角冒号,不含顿号)。
  • 点击“应用”(Apply)。

章节分页符

在“转换”(Conversion)处,选择“通用选项”(Common options):

  • 点击“结构检测”(Structure detection),填写“前置插入分页符的XPath表达式”(Insert page breaks before (XPath expression)):
    • 每个一、二级标题之间都分页://*[name()='h1' or name()='h2']
    • 仅在每个一级标题之间分页://*[name()='h1']
    • 各级标题之间都不分页:/
  • 点击“应用”(Apply)。

相对固定的输入格式

在“转换”(Conversion)处,选择“输入格式选项”(Input options):

  • 在“TXT输入”(TXT input)处
    • “格式化样式”(Formatting style)选择markdown。但在默认选择auto的情况下,通常也能自动准确地识别为markdown。
  • 点击“应用”(Apply)。

相对固定的输出格式

在“转换”(Conversion)处,选择“输出格式选项”(Output options):

  • 在“EPUB输出”(EPUB output)处
    • 如需要将目录添加到正文之前,可勾选“将目录内嵌到书籍”(Insert inline Table of Contents),并填写“内嵌目录的标题”(Title for inserted ToC,默认是Table of Contents。
  • 在“DOCX输出”(DOCX output)处
    • 按需调整“页面大小”(Paper size),默认letter是8.5 x 11 inch,合21.59 x 27.94厘米。
    • 按需调整“页面边距”(Page margin),默认是72.0 pt,合1 inch或2.54厘米。
    • 如需要将目录添加到正文之前,可不勾选“不将目录作为页面插入文档开头”(Do not insert the Table of Contents as a page at the start of the document),目录的标题只能是Table of Contents。
  • 在“PDF输出”(PDF output)处

    • 按需调整“页面大小”(Paper size),默认Letter/ANSI A是8.5 x 11 inch,合21.59 x 27.94厘米。
    • 按需勾选“在文档末尾添加可打印的目录”(Add a printable Table of Contents at the end),并填写“目录的标题”(Title for ToC)。
    • 按需调整字体,避免使用小众字体。“衬线字体”(Serif family)可改为宋体(SimSun),但也可以使用非衬线字体;“非衬线字体”(Sans family)可改为微软雅黑(Microsoft YaHei)、黑体(Simhei),但也可以使用衬线字体。
    • 按需调整“默认字体大小”(Default font size),例如六号7.5 pt、小五9 pt、五号10.5 pt、小四12 pt、四号14 pt、小三15 pt、三号16 pt、小二18 pt、二号22 pt、小一24 pt、一号26 pt等,以适应不同的读者群。
    • 按需调整“页边距”(Page margins),默认是72.0 pt,合1 inch或2.54厘米。
    • 按需勾选“在每页底部添加页码”(Add page numbers to the bottom of every page),在“页眉模板”(Header template)、“页脚模板”(Footer template)填写HTML代码片段,支持一次粘贴多行代码。例如,

      • 页眉字体大小小于正文,奇数页页眉是带下划线的最高级标题(即一级标题)且默认左对齐,偶数页页眉是粗体的最低级标题(例如二级或三级标题)且强制右对齐,可使用页眉模板:
      <header style="font-size: smaller">
      <div class="odd-page"><u>_TOP_LEVEL_SECTION_</u></div>
      <div class="even-page" style="text-align: right; width: 100%"><b>_SECTION_</b></div>
      </header>
      
      • 页脚是“页码/总页数”,水平方向居中,上下无外边距,可使用页脚模板:

      <footer><div style="margin: auto">_PAGENUM_/_TOTAL_PAGES_</div></footer>

      • 如指定页脚模板,那么“在每页底部添加页码”的选项将被忽略。
  • 注意:字体、字体大小、页面大小、页边距、页眉、页脚等不同的参数组合就相当于印刷机的字模,可以成为识别制作者的一种特征。应尽量保证同一丛书的参数相同,不同丛书的参数相异,或尽量使用默认设置,即点击“恢复默认值”(Restore defaults)。

  • 点击“应用”(Apply)。

完成配置

  • 点击“关闭”(Close)。

输出

把素材文档导入书库

在Calibre的主界面,执行以下步骤。

  • 点击“添加书籍”(Add books),“从单个文件夹添加”(Add books from a single folder)。
  • 选择写好的素材文档。导入过程即复制到书库内,此后的操作都将针对书库内的文档。素材文档如何修改不再影响最终制作出来的电子书。
  • 如已经修改素材文档,需要更新书库内的文档,可选中导入的书籍,点击“添加书籍”(Add books),“添加文件到所选书籍中”(Add files to selected book records)。

编辑元数据

在Calibre的主界面,执行以下步骤。

  • 选中导入的书籍,点击“编辑元数据”(Edit metadata),“逐个编辑元数据”(Edit metadata individually)。
  • 根据需要修改“书名”(Title)、“作者”(Author)、“丛书名”(Series)、“丛书编号”(Number)等,其中只有书名是必填项。注意修改相应的“排序书名”(Title sort)和“排序作者”(Author sort),可以与书名、作者一致或不一致。
  • 在“创建日期”(Published)处,点击右侧按钮“清除日期”(Clear date)。
  • 在“更换封面”(Change cover)处,点击“浏览”(Browse),选择事先备好的封面图片。也可以多次点击“生成封面”(Generate cover),每次都将以默认图片为背景自动生成一个包含书名、作者、丛书名、丛书编号的封面,因此作者、丛书名、丛书编号实际上可以分别用来填写联系方式、出品方、期号等其他信息。
  • 点击“确定”(OK)。
  • 如不希望元数据里残留Calibre的版本号,可找到以下路径的文档,并用任意文本编辑器打开后修改contributor字段:书库位置\作者\书名\metadata.opf

生成书籍并另存为

在Calibre的主界面,执行以下步骤。

  • 选中导入的书籍,点击“转换书籍”(Convert books),“逐个转换”(Convert individually)。
  • 输出格式选择EPUB、DOCX或PDF。
  • 在“页面设置”(Page setup)处,选择输出设备的规格,一般无需调整。
  • 在“目录”(Table of Contents)处,由于之前已经修改默认配置,一般无需调整。
  • 在“TXT输入”(TXT input)处,由于之前已经修改默认配置,一般无需调整。
  • 在“输出”(input)处,由于之前已经修改默认配置,一般无需调整。
  • 点击“确定”(OK)并等待完成,其中PDF的输出过程会比较慢。
  • 选中导入的书籍,点击“保存到硬盘”(Save to disk)。
    • 只需要一种输出格式时,选择“保存单一格式到硬盘”(Save single format to disk)。
    • 需要多种输出格式时,选择“保存到硬盘的单个文件夹”(Save to disk in a single folder)。
  • 如中途修改过素材文档或元数据,应当仔细检查内容、封面、插图是否正确。如不正确,可以执行清理步骤后重新操作。

检查书籍的元数据

在要求不高的情况下,可以不使用Calibre,直接制作DOCX文件,并另存为PDF,然后使用以下推荐的工具删除大多数元数据。但这个过程比较依赖经验,有可能残留除了元数据以外的痕迹,例如字体、样式、语言、区域、批注、修订、最近打开记录、自动恢复文件等。

以下检查步骤仍针对Calibre生成的电子书。

EPUB

一般来说,残留的痕迹包括:

  • Title:书名
  • Title for Sorting:书名
  • Creator:作者
  • Contributor:calibre (版本号)
  • Language:Calibre的界面语言
  • Timestamp:Calibre编辑元数据时设置的“创建日期”
  • Series:Calibre编辑元数据时设置的“丛书名”
  • Series Index:Calibre编辑元数据时设置的“丛书编号”

如需检查和进一步清理上述痕迹,可使用开源软件Sigil EPUB Editor。使用前,需要安装新版Microsoft Visual C++ Redistributable。运行后,进入菜单Tools的Metadata Editor,选中相关字段并点击Remove。但即使全部清空,仍会留下Sigil的版本号、使用Sigil修改元数据的日期(不含时间)。

DOCX

一般来说,残留的痕迹包括:

  • Title:书名
  • Last Modified:输出日期和时间
  • Created:输出日期和时间
  • Author:作者
  • Last Modified By:calibre

如需检查上述痕迹,可使用Microsoft Word自带的“检查文档”(Inspect document)功能,但进一步清理后的痕迹未必少于清理前。建议在不打开Microsoft Word的情况下,右键点击文档,进入“属性”(Properties)的“详细内容”(Details),直接修改某些元数据。

PDF

一般来说,残留的痕迹包括:

  • Title:书名
  • Author:作者
  • Creators:作者
  • Creator:calibre 版本号
  • Producer:calibre 版本号
  • Creation Date:输出日期和时间
  • Modification Date:输出日期和时间
  • Metadata Date:输出日期和时间
  • Languages:Calibre的界面语言

如需检查和进一步清理上述痕迹,可使用开源软件PDF Metadata Editor

也可使用自由软件Hexonic PDF Metadata Editor。使用前,需要安装Microsoft .NET Framework 3.5

清理

  • 可找到以下路径,用专门软件直接擦除其中的全部文件:书库位置\作者\书名\
  • 在Calibre的主界面,选中导入的书籍,点击“删除书籍”(Remove books),“删除所选书籍”(Remove selected books)。
  • 可找到以下路径,根据文件夹的创建和修改时间判断该书籍对应的文件夹,用专门软件擦除其中的metadata.opf文档:书库位置\.caltrash\
  • 在Calibre的主界面,点击“删除书籍”(Remove books),“恢复最近删除的书籍”(Restore recently deleted),确认导入的书籍已被彻底删除、无法恢复。
  • 在Calibre的主界面,点击“书库”(Library),“书库维护”(Library maintenance),“检查书库”(Check library),勾选“同时压缩全文搜索数据库”(Also compact the Full text search database),依次点击“确定”(OK)、“是”(Yes),从而重建以下路径的文件:书库位置\metadata.db
  • 清理书库所在的硬盘分区或U盘。
  • 如使用虚拟机,恢复到历史状态。

以上内容的Markdown原始代码

# 手工制作的目录
* [输入](#输入)
    * [掌握Markdown的基本语法](#掌握Markdown的基本语法)
    * [撰写素材文档](#撰写素材文档)
    * [校对素材文档](#校对素材文档)
    * [制作封面图片和插图](#制作封面图片和插图)
* [准备](#准备)
    * [安装Calibre](#安装Calibre)
    * [配置Calibre](#配置Calibre)
        * [自动生成的目录](#自动生成的目录)
        * [章节分页符](#章节分页符)
        * [相对固定的输出格式](#相对固定的输出格式)
* [输出](#输出)
    * [把素材文档导入书库](#把素材文档导入书库)
    * [编辑元数据](#编辑元数据)
    * [生成书籍并另存为](#生成书籍并另存为)
    * [检查书籍的元数据](#检查书籍的元数据)
        * [EPUB](#EPUB)
        * [DOCX](#DOCX)
        * [PDF](#PDF)
    * [清理](#清理)

# 输入

## 掌握Markdown的基本语法

Markdown是通用、健壮、易学易读易写、便于移植的轻量级标记语言,教程见[Markdown Guide](https://www.markdownguide.org/cheat-sheet/)[Daring Fireball](https://daringfireball.net/projects/markdown/syntax)。主要语法列举如下:

````
    用至少一个空白行分隔不同段落(包括标题)。
    正常段落没有必要缩进(即空两格),需要时每4个空格( )或1个制表符(TAB)可缩进一级。
    # 一级标题
    ## 二级标题
    ### 三级标题
    #### 四级标题
    **粗体**
    *斜体*
    ***粗体和斜体***
    1. 有序列表第一项
    1. 有序列表第二项
    1. 有序列表第三项
    - 无序列表第一项
    * 无序列表第二项
    + 无序列表第三项
    ```段落之间的等宽字体代码块```
    ``段落内部嵌入的等宽字体代码``
    > 引用的第一个段落
    >
    > 引用的第二个段落
    >> 嵌套引用的段落
    <blockquote>段落之间的多行引用块</blockquote>
    [外部超链接显示名](外部超链接地址)
    [外部超链接显示名](外部超链接地址 "鼠标悬停在链接上时显示的文字提示")
    ![图片无法加载时显示的文字描述](图片路径)
    ![图片无法加载时显示的文字描述](图片路径 "鼠标悬停在图片上时显示的文字提示")
    [^1]: 脚注
    * [目录中的二级标题显示名](#正文中的二级标题)
    * [目录中的二级标题显示名](#二级标题ID)
    <h2 id="二级标题ID">正文中的二级标题</h2>
    <h3 id="三级标题ID">正文中的三级标题</h3>
    \转义符
````

## 撰写素材文档

**从这里开始,所有步骤建议在虚拟机内执行。**为避免泄露制作的日期和时间,应当关闭虚拟机的时间同步功能,修改虚拟机的系统时间。但是时间错误的情况下,依赖证书的网站连接将受到影响。可以先满足联网需求,在输出前才修改时间。在没有虚拟机的情况下,可以修改物理计算机的时间。

在加密分区、容器新建文本文档,后缀名可以是txt、md等,文件名将是电子书的默认书名,但后续步骤中可以修改书名。

按Markdown格式书写需要生成的电子书。在Windows系统中,建议使用记事本等简易的文本编辑器,不建议使用Microsoft Word。

其他格式的现有文档、网页或电子书可以分别依靠[Word to Markdown](https://word2md.com/)[URL to Markdown](https://urltomarkdown.com/)[Zamzar Epub to Markdown](https://www.zamzar.com/convert/epub-to-md/)[Convertio eBook Converter](https://convertio.co/ebook-converter/)等线上转换工具或Calibre等线下转换工具预处理,然后人工校对。

目录可以在后续过程中自动生成,一般不需要按Markdown语法自行撰写。

外部超链接地址应当经过处理,删除跟踪参数。

Markdown的标准语法能够满足绝大多数需要。如有特殊需要,可使用html代码,或支持扩展语法的解析器。更详细的注意事项见[Create Clean EPUBs using Calibre](https://evelynchartres.com/create-clean-epubs-using-calibre/)## 校对素材文档

Markdown格式的文本可以使用以下工具检查是否存在语法错误。
* 线上工具:[StackEdit](https://stackedit.io/app)[Dillinger](https://dillinger.io/)[Rentry.co](https://rentry.co/)* 线下工具:[Zettlr](https://www.zettlr.com/)[MarkText](https://www.marktext.cc/)[ghostwriter](https://ghostwriter.kde.org/)## 制作封面图片和插图

JPG/JPEG、TIF、PNG、WEBP四种图片可能含有EXIF数据,可能涉及修改时间、制作软件、拍摄设备、经纬度、速度等大量信息。应事先使用以下工具检查和清理:
* 线上工具:[Ver Exif](https://www.verexif.com/)* 线下工具:[ExifCleaner](https://github.com/szTheory/exifcleaner/releases)等

今后如以EPUB格式输出,图片的修改时间将在嵌入EPUB文件时改为输出的时间。

Markdown的标准语法并不适合复杂的图文混排。为提高对不同系统的兼容性,图片路径应避免使用绝对路径。为避免从互联网下载,图片路径也应避免使用URL。建议把图片与素材文档放在同一个文件夹,在图片路径处直接写图片的文件名,例如image.jpg。文件名应当不包含个人信息,也不包含空格和括号。

Markdown的标准语法也不支持文字居中。如需在图片上方或下方增加图片说明且水平方向居中,可使用以下两种写法:
* ``<div align="center">图片说明</div>``

* ``<center>图片说明</center>``

# 准备

## 安装Calibre

Calibre是自由软件,可用于阅读、制作、编辑、转换电子书,下载地址[calibre-ebook.com](https://www.calibre-ebook.com/download)。Windows 10以上可使用[普通版](https://calibre-ebook.com/download_windows)[绿色版](https://calibre-ebook.com/download_portable),Windows 8最高可使用[5.44版](https://download.calibre-ebook.com/5.44.0),Windows 7最高可使用[3.48版](https://download.calibre-ebook.com/3.48.0)。混淆Calibre版本号的一个办法是故意使用[旧版本](https://download.calibre-ebook.com/)。

安装Calibre,通常无需更改默认参数。

首次运行时,将显示配置向导:

* 语言建议首先选择自己掌握的某门外语,其次可选择Simplified Chinese或Traditional Chinese,不建议选择Chinese。以下说明将提供中英双语。
* “书库”(Library)位置应选择便于清理的硬盘分区或U盘,重要书籍务必选择加密分区、容器内的空文件夹。绿色版的书库位置默认在绿色版所在的目录,在首次运行时无法在配置向导中修改,需要手动点击“书库”(Library),“切换/创建书库”(Switch/create library)。
* “设备”(Device)使用默认配置。

## 配置Calibre

进入主界面后,点击上方大按钮“偏好选项”(Preferences)。有时因为窗口较小没有显示,或者把窗口最大化,或者点击其他大按钮最右侧的竖排三个点┇。

### 自动生成的目录

在“转换”(Conversion)处,选择“通用选项”(Common options):

* 点击“目录”(Table of Contents),勾选“创建目录时允许重复的链接”(Allow duplicate links when creating the Table of Contents)。
* 在一、二、三级目录(Level 1/2/3 TOC)的“XPath表达式”(XPath expression)框内分别输入//h:h1、//h:h2、//h:h3(英语半角冒号,不含顿号)。
* 点击“应用”(Apply)。

### 章节分页符

在“转换”(Conversion)处,选择“通用选项”(Common options):

* 点击“结构检测”(Structure detection),填写“前置插入分页符的XPath表达式”(Insert page breaks before (XPath expression)):
    * 每个一、二级标题之间都分页://*[name()='h1' or name()='h2']
    * 仅在每个一级标题之间分页://*[name()='h1']
    * 各级标题之间都不分页:/
* 点击“应用”(Apply)。

### 相对固定的输入格式

在“转换”(Conversion)处,选择“输入格式选项”(Input options):

* 在“TXT输入”(TXT input)处
    * “格式化样式”(Formatting style)选择markdown。但在默认选择auto的情况下,通常也能自动准确地识别为markdown。
* 点击“应用”(Apply)。

### 相对固定的输出格式

在“转换”(Conversion)处,选择“输出格式选项”(Output options):

* 在“EPUB输出”(EPUB output)处
    * 如需要将目录添加到正文之前,可勾选“将目录内嵌到书籍”(Insert inline Table of Contents),并填写“内嵌目录的标题”(Title for inserted ToC,默认是Table of Contents。
* 在“DOCX输出”(DOCX output)处
    * 按需调整“页面大小”(Paper size),默认letter是8.5 x 11 inch,合21.59 x 27.94厘米。
    * 按需调整“页面边距”(Page margin),默认是72.0 pt,合1 inch或2.54厘米。
    * 如需要将目录添加到正文之前,可不勾选“不将目录作为页面插入文档开头”(Do not insert the Table of Contents as a page at the start of the document),目录的标题只能是Table of Contents。
* 在“PDF输出”(PDF output)处
    * 按需调整“页面大小”(Paper size),默认Letter/ANSI A是8.5 x 11 inch,合21.59 x 27.94厘米。
    * 按需勾选“在文档末尾添加可打印的目录”(Add a printable Table of Contents at the end),并填写“目录的标题”(Title for ToC)。
    * 按需调整字体,避免使用小众字体。“衬线字体”(Serif family)可改为宋体(SimSun),但也可以使用非衬线字体;“非衬线字体”(Sans family)可改为微软雅黑(Microsoft YaHei)、黑体(Simhei),但也可以使用衬线字体。
    * 按需调整“默认字体大小”(Default font size),例如六号7.5 pt、小五9 pt、五号10.5 pt、小四12 pt、四号14 pt、小三15 pt、三号16 pt、小二18 pt、二号22 pt、小一24 pt、一号26 pt等,以适应不同的读者群。
    * 按需调整“页边距”(Page margins),默认是72.0 pt,合1 inch或2.54厘米。
    * 按需勾选“在每页底部添加页码”(Add page numbers to the bottom of every page),在“页眉模板”(Header template)、“页脚模板”(Footer template)填写HTML代码片段,支持一次粘贴多行代码。例如,

        * 页眉字体大小小于正文,奇数页页眉是带下划线的最高级标题(即一级标题)且默认左对齐,偶数页页眉是粗体的最低级标题(例如二级或三级标题)且强制右对齐,可使用页眉模板:

        > ```
        > <header style="font-size: smaller">
        > <div class="odd-page"><u>_TOP_LEVEL_SECTION_</u></div>
        > <div class="even-page" style="text-align: right; width: 100%"><b>_SECTION_</b></div>
        > </header>
        > ```

        * 页脚是“页码/总页数”,水平方向居中,上下无外边距,可使用页脚模板:

        > ``<footer><div style="margin: auto">_PAGENUM_/_TOTAL_PAGES_</div></footer>``

        * 如指定页脚模板,那么“在每页底部添加页码”的选项将被忽略。

* **注意:**字体、字体大小、页面大小、页边距、页眉、页脚等不同的参数组合就相当于印刷机的字模,可以成为识别制作者的一种特征。应尽量保证同一丛书的参数相同,不同丛书的参数相异,或尽量使用默认设置,即点击“恢复默认值”(Restore defaults)。

* 点击“应用”(Apply)。

### 完成配置

* 点击“关闭”(Close)。

# 输出

## 把素材文档导入书库

在Calibre的主界面,执行以下步骤。

* 点击“添加书籍”(Add books),“从单个文件夹添加”(Add books from a single folder)。
* 选择写好的素材文档。导入过程即复制到书库内,此后的操作都将针对书库内的文档。素材文档如何修改不再影响最终制作出来的电子书。
* 如已经修改素材文档,需要更新书库内的文档,可**选中导入的书籍**,点击“添加书籍”(Add books),“添加文件到所选书籍中”(Add files to selected book records)。

## 编辑元数据

在Calibre的主界面,执行以下步骤。

* 选中导入的书籍,点击“编辑元数据”(Edit metadata),“逐个编辑元数据”(Edit metadata individually)。
* 根据需要修改“书名”(Title)、“作者”(Author)、“丛书名”(Series)、“丛书编号”(Number)等,其中只有书名是必填项。注意修改相应的“排序书名”(Title sort)和“排序作者”(Author sort),可以与书名、作者一致或不一致。
* 在“创建日期”(Published)处,点击右侧按钮“清除日期”(Clear date)。
* 在“更换封面”(Change cover)处,点击“浏览”(Browse),选择事先备好的封面图片。也可以多次点击“生成封面”(Generate cover),每次都将以默认图片为背景自动生成一个包含书名、作者、丛书名、丛书编号的封面,因此作者、丛书名、丛书编号实际上可以分别用来填写联系方式、出品方、期号等其他信息。
* 点击“确定”(OK)。
* 如不希望元数据里残留Calibre的版本号,可找到以下路径的文档,并用任意文本编辑器打开后修改contributor字段:书库位置\作\书\metadata.opf

## 生成书籍并另存为

在Calibre的主界面,执行以下步骤。

* 选中导入的书籍,点击“转换书籍”(Convert books),“逐个转换”(Convert individually)。
* 输出格式选择EPUB、DOCX或PDF。
* 在“页面设置”(Page setup)处,选择输出设备的规格,一般无需调整。
* 在“目录”(Table of Contents)处,由于之前已经修改默认配置,一般无需调整。
* 在“TXT输入”(TXT input)处,由于之前已经修改默认配置,一般无需调整。
* 在“输出”(input)处,由于之前已经修改默认配置,一般无需调整。
* 点击“确定”(OK)并等待完成,其中PDF的输出过程会比较慢。
* 选中导入的书籍,点击“保存到硬盘”(Save to disk)。
    * 只需要一种输出格式时,选择“保存单一格式到硬盘”(Save single format to disk)。
    * 需要多种输出格式时,选择“保存到硬盘的单个文件夹”(Save to disk in a single folder)。
* 如中途修改过素材文档或元数据,应当仔细检查内容、封面、插图是否正确。如不正确,可以执行清理步骤后重新操作。

## 检查书籍的元数据

**在要求不高的情况下,可以不使用Calibre,直接制作DOCX文件,并另存为PDF,然后使用以下推荐的工具删除大多数元数据。**但这个过程比较依赖经验,有可能残留除了元数据以外的痕迹,例如字体、样式、语言、区域、批注、修订、最近打开记录、自动恢复文件等。

以下检查步骤仍针对Calibre生成的电子书。

### EPUB

一般来说,残留的痕迹包括:

* Title:书名
* Title for Sorting:书名
* Creator:作者
* Contributor:calibre (版本号)
* Language:Calibre的界面语言
* Timestamp:Calibre编辑元数据时设置的“创建日期”
* Series:Calibre编辑元数据时设置的“丛书名”
* Series Index:Calibre编辑元数据时设置的“丛书编号”

如需检查和进一步清理上述痕迹,可使用开源软件[Sigil EPUB Editor](https://sigil-ebook.com/sigil/download/)。使用前,需要安装新版[Microsoft Visual C++ Redistributable](https://learn.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redist)。运行后,进入菜单Tools的Metadata Editor,选中相关字段并点击Remove。但即使全部清空,仍会留下Sigil的版本号、使用Sigil修改元数据的日期(不含时间)。

### DOCX

一般来说,残留的痕迹包括:

* Title:书名
* Last Modified:输出日期和时间
* Created:输出日期和时间
* Author:作者
* Last Modified By:calibre

如需检查上述痕迹,可使用Microsoft Word自带的“检查文档”(Inspect document)功能,**但进一步清理后的痕迹未必少于清理前**。建议在不打开Microsoft Word的情况下,右键点击文档,进入“属性”(Properties)的“详细内容”(Details),直接修改某些元数据。

### PDF

一般来说,残留的痕迹包括:

* Title:书名
* Author:作者
* Creators:作者
* Creator:calibre 版本号
* Producer:calibre 版本号
* Creation Date:输出日期和时间
* Modification Date:输出日期和时间
* Metadata Date:输出日期和时间
* Languages:Calibre的界面语言

如需检查和进一步清理上述痕迹,可使用开源软件[PDF Metadata Editor](https://pdf.metadata.care/download/)。

也可使用自由软件[Hexonic PDF Metadata Editor](http://www.hexonic-software.com/index.php/hexonic-pdf-metadata-editor)。使用前,需要安装[Microsoft .NET Framework 3.5](https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/net35-sp1?wt.mc_id=install-docs)## 清理

* 可找到以下路径,用专门软件直接擦除其中的全部文件:书库位置\作\书\
* 在Calibre的主界面,选中导入的书籍,点击“删除书籍”(Remove books),“删除所选书籍”(Remove selected books)。
* 可找到以下路径,根据文件夹的创建和修改时间判断该书籍对应的文件夹,用专门软件擦除其中的metadata.opf文档:书库位置\\.caltrash\
* 在Calibre的主界面,点击“删除书籍”(Remove books),“恢复最近删除的书籍”(Restore recently deleted),确认导入的书籍已被彻底删除、无法恢复。
* 在Calibre的主界面,点击“书库”(Library),“书库维护”(Library maintenance),“检查书库”(Check library),勾选“同时压缩全文搜索数据库”(Also compact the Full text search database),依次点击“确定”(OK)、“是”(Yes),从而重建以下路径的文件:书库位置\metadata.db
* 清理书库所在的硬盘分区或U盘。
* 如使用虚拟机,恢复到历史状态。