8 releases (4 breaking)

new 0.5.0 Nov 9, 2024
0.4.1 Sep 12, 2024
0.3.0 Sep 2, 2024
0.2.0 Aug 30, 2024
0.1.1 Jul 19, 2024

#316 in Text processing

MIT license

2MB
6K SLoC

iepub

EPUB格式读写库, MOBI格式读库,

EPUB

支持从文件和内存读取和生成EPUB电子书

生成

  • 可以使用EpubBook结构体手动生成epub
  • (推荐)使用EpubBuilder快速生成
use iepub::EpubHtml;
use iepub::EpubBuilder;

EpubBuilder::default()
    .with_title("书名")
    .with_creator("作者")
    .with_date("2024-03-14")
    .with_description("一本好书")
    .with_identifier("isbn")
    .with_publisher("行星出版社")
    .add_chapter(
        EpubHtml::default()
            .with_file_name("0.xml")
            .with_data("<p>锻炼</p>".to_string().as_bytes().to_vec()),
    )
    .add_assets("1.css", "p{color:red}".to_string().as_bytes().to_vec())
    .metadata("s", "d")
    .metadata("h", "m")
    .file("target/build.epub")
    .unwrap();

读取

use iepub::prelude::{reader::read_from_vec, reader::read_from_file, EpubHtml};
let mut data = Vec::new();// epub的二进制数据

let mut book = read_from_vec(data);
// 从文件读取
let mut bbook = read_from_file("epub格式文件绝对路径");

// 注意,默认情况下读取采用懒加载,上述代码只完成了基础结构读取,包括目录,文件列表等等,具体某个章节或者资源的数据将会推迟到第一次调用`data()`方法时读取
// 例如

let mut chap = book.get_chapter("0.xhtml").unwrap();
let data = chap.data();// 此时将会实际读取并解析文件
let data2 = chap.data();// 第二次不会再读取文件了

注意事项

  • iepub使用EpubHtml来存储章节内容,但是EpubHtml#data实际只会存储 html>body 节点内的内容,并且不包括body节点的属性(attribute),其他比如样式表将会存放在其他属性中
  • 不同的阅读器对于文件名的兼容性不同,这里建议文件最好使用.xhtml后缀,例如EpubHtml::default().with_file_name("1.xhtml")

自定义目录

  • 如果需要自定义目录,需要调用custome_nav(false),然后调用add_nav()添加目录

mobi

读取

use iepub::prelude::*;

let path = std::env::current_dir().unwrap().join("1.mobi");
let mut mobi = MobiReader::new(std::fs::File::open(path.to_str().unwrap()).unwrap()).unwrap();
let book = mobi.load().unwrap();

写入

使用builder

let v = MobiBuilder::default()
            .with_title("书名")
            .with_creator("作者")
            .with_date("2024-03-14")
            .with_description("一本好书")
            .with_identifier("isbn")
            .with_publisher("行星出版社")
            .append_title(true)
            .custome_nav(true)
            .add_chapter(MobiHtml::new(1).with_title("标题").with_data("<p>锻炼</p>"))
            // .file("builder.mobi")
            .mem()
            .unwrap();

自定义目录

  • 如果需要自定义目录,需要调用custome_nav(false),然后调用add_nav()添加目录
  • 为了关联目录nav和章节chap,需要调用MobiNav#set_chap_id()指明指向的章节;如果是类似卷首目录,指向最接近的章节即可

图片

  • mobi格式中图片是不存在文件路径的,如果需要添加图片,首先在章节中使用 img 标签的src属性,随便给个文件名,只要不重复就行,然后添加图片的时候也指向同一个文件名,最后写入就会添加图片了
  • 由于mobi设计原因,如果某个图片未被引用,最终仍然会被写入到文件,但是不可索引,不可查看,只能白白占用空间
  • 另外封面需要调用cover()设置

标题

默认情况下会在章节的html片段前面加一段标题xml,如果章节内容里本身就有可阅读的标题,设置append_title(false)

转换

mobi -> epub

use iepub::prelude::*;
let mut book = std::fs::File::open(std::path::PathBuf::from("example.mobi"))
            .map_err(|e| IError::Io(e))
            .and_then(|f| MobiReader::new(f))
            .and_then(|mut f| f.load())
            .unwrap();

let mut epub = mobi_to_epub(&mut book).unwrap();
epub.write("convert.epub").unwrap();

epub -> mobi

use iepub::prelude::*;
let mut epub = EpubBook::default();

let mobi = epub_to_mobi(&mut epub).unwrap();
let mut v = std::io::Cursor::new(Vec::new());
MobiWriter::new(&mut v)
    .unwrap()
    .with_append_title(false)
    .write(&mobi)
    .unwrap();

命令行工具

tool目录为命令行工具,支持mobi和epub格式,但是不同格式支持的命令不尽相同

目前支持

  • 获取元数据,如标题、作者
  • 修改元数据
  • 提取封面
  • 提取所有图片
  • 提取某章节文本
  • 获取目录
  • 格式转换

可通过-h获取使用方法说明

Dependencies

~19–25MB
~420K SLoC