mirror of
https://github.com/cyborg42/epub2mdbook.git
synced 2026-02-10 16:24:50 -05:00
update book.toml
This commit is contained in:
parent
ef9ded9a17
commit
2bf293c4d7
3 changed files with 1859 additions and 39 deletions
1815
Cargo.lock
generated
1815
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "epub2mdbook"
|
name = "epub2mdbook"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "A tool to convert EPUB files to MDBook format"
|
description = "A tool to convert EPUB files to MDBook format"
|
||||||
authors = ["Maverick Liu <maverick.liu42@gmail.com>"]
|
authors = ["Maverick Liu <maverick.liu42@gmail.com>"]
|
||||||
|
|
@ -13,5 +13,7 @@ categories = ["command-line-utilities", "text-processing"]
|
||||||
clap = { version = "4.5.30", features = ["derive"] }
|
clap = { version = "4.5.30", features = ["derive"] }
|
||||||
epub = "2.1.1"
|
epub = "2.1.1"
|
||||||
htmd = "0.1.6"
|
htmd = "0.1.6"
|
||||||
|
mdbook = "0.4.45"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
thiserror = "2.0.11"
|
thiserror = "2.0.11"
|
||||||
|
toml = "0.8.20"
|
||||||
|
|
|
||||||
79
src/lib.rs
79
src/lib.rs
|
|
@ -2,6 +2,7 @@ pub mod error;
|
||||||
|
|
||||||
use epub::doc::{EpubDoc, NavPoint};
|
use epub::doc::{EpubDoc, NavPoint};
|
||||||
use error::Error;
|
use error::Error;
|
||||||
|
use mdbook::config::BookConfig;
|
||||||
use regex::{Captures, Regex};
|
use regex::{Captures, Regex};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
|
|
@ -10,7 +11,7 @@ use std::path::{Path, PathBuf};
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
|
|
||||||
/// Convert an EPUB file to an MDBook
|
/// Convert an EPUB file to MDBook format
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
|
|
@ -23,37 +24,26 @@ pub fn convert_epub_to_mdbook(
|
||||||
with_file_name: bool,
|
with_file_name: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let epub_path = epub_path.as_ref();
|
let epub_path = epub_path.as_ref();
|
||||||
let output_dir = output_dir.as_ref();
|
|
||||||
if !epub_path.is_file() {
|
if !epub_path.is_file() {
|
||||||
return Err(Error::NotAFile(epub_path.display().to_string()));
|
return Err(Error::NotAFile(epub_path.display().to_string()));
|
||||||
}
|
}
|
||||||
let book_name = epub_path
|
let mut output_dir = output_dir.as_ref().to_owned();
|
||||||
.with_extension("")
|
if with_file_name {
|
||||||
.file_name()
|
let book_name = epub_path
|
||||||
.expect("unreachable")
|
.with_extension("")
|
||||||
.to_string_lossy()
|
.file_name()
|
||||||
.to_string();
|
.expect("unreachable")
|
||||||
let output_dir = if with_file_name {
|
.to_string_lossy()
|
||||||
output_dir.join(&book_name)
|
.to_string();
|
||||||
} else {
|
output_dir.push(book_name)
|
||||||
output_dir.to_owned()
|
}
|
||||||
};
|
|
||||||
fs::create_dir_all(output_dir.join("src"))?;
|
fs::create_dir_all(output_dir.join("src"))?;
|
||||||
|
|
||||||
let mut epub_doc = EpubDoc::new(epub_path)?;
|
let mut epub_doc = EpubDoc::new(epub_path)?;
|
||||||
let title = epub_doc
|
let (summary_md, html_to_md) = generate_summary_md(&epub_doc);
|
||||||
.metadata
|
|
||||||
.get("title")
|
|
||||||
.and_then(|v| v.first().cloned())
|
|
||||||
.unwrap_or(book_name);
|
|
||||||
let creator = epub_doc
|
|
||||||
.metadata
|
|
||||||
.get("creator")
|
|
||||||
.and_then(|v| v.first().cloned());
|
|
||||||
let (summary_md, html_to_md) = generate_summary_md(&epub_doc, &title);
|
|
||||||
extract_chapters_and_resources(&mut epub_doc, &output_dir, &html_to_md)?;
|
extract_chapters_and_resources(&mut epub_doc, &output_dir, &html_to_md)?;
|
||||||
fs::write(output_dir.join("src/SUMMARY.md"), summary_md)?;
|
fs::write(output_dir.join("src/SUMMARY.md"), summary_md)?;
|
||||||
write_book_toml(&output_dir, &title, creator)?;
|
write_book_toml(&epub_doc, &output_dir)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +72,6 @@ fn epub_nav_to_md(
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `epub_doc` - The EPUB document
|
/// * `epub_doc` - The EPUB document
|
||||||
/// * `title` - The title of the book
|
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
|
|
@ -90,9 +79,13 @@ fn epub_nav_to_md(
|
||||||
/// * `html_to_md` - The file mapping from html to md
|
/// * `html_to_md` - The file mapping from html to md
|
||||||
pub fn generate_summary_md<R: Read + Seek>(
|
pub fn generate_summary_md<R: Read + Seek>(
|
||||||
epub_doc: &EpubDoc<R>,
|
epub_doc: &EpubDoc<R>,
|
||||||
title: &str,
|
|
||||||
) -> (String, HashMap<PathBuf, PathBuf>) {
|
) -> (String, HashMap<PathBuf, PathBuf>) {
|
||||||
let mut summary_md = format!("# {}\n\n", title);
|
let title = epub_doc.metadata.get("title").and_then(|v| v.first());
|
||||||
|
let mut summary_md = if let Some(title) = title {
|
||||||
|
format!("# {}\n\n", title)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
let html_to_md = epub_doc
|
let html_to_md = epub_doc
|
||||||
.resources
|
.resources
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -185,17 +178,35 @@ fn post_process_md(markdown: &str, file_name_map: &HashMap<&OsStr, &OsStr>) -> S
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_book_toml(
|
fn write_book_toml<R: Read + Seek>(
|
||||||
|
epub_doc: &EpubDoc<R>,
|
||||||
output_dir: impl AsRef<Path>,
|
output_dir: impl AsRef<Path>,
|
||||||
title: &str,
|
|
||||||
creator: Option<String>,
|
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let output_dir = output_dir.as_ref();
|
let output_dir = output_dir.as_ref();
|
||||||
let author = match creator {
|
let title = epub_doc
|
||||||
Some(creator) => format!("author = \"{creator}\"\n"),
|
.metadata
|
||||||
None => "".to_string(),
|
.get("title")
|
||||||
|
.and_then(|v| v.first().cloned());
|
||||||
|
let authors = epub_doc.metadata.get("creator").cloned().unwrap_or(vec![]);
|
||||||
|
let description = epub_doc
|
||||||
|
.metadata
|
||||||
|
.get("description")
|
||||||
|
.and_then(|v| v.first().cloned())
|
||||||
|
.map(|s| htmd::convert(&s).expect("unreachable"));
|
||||||
|
let lang = epub_doc
|
||||||
|
.metadata
|
||||||
|
.get("lang")
|
||||||
|
.and_then(|v| v.first().cloned());
|
||||||
|
let config = BookConfig {
|
||||||
|
title,
|
||||||
|
authors,
|
||||||
|
description,
|
||||||
|
src: PathBuf::from("src"),
|
||||||
|
multilingual: false,
|
||||||
|
language: lang,
|
||||||
|
text_direction: None,
|
||||||
};
|
};
|
||||||
let toml_content = format!("[book]\ntitle = \"{title}\"\n{author}",);
|
let toml_content = format!("[book]\n{}", toml::to_string(&config).expect("unreachable"));
|
||||||
fs::write(output_dir.join("book.toml"), toml_content)?;
|
fs::write(output_dir.join("book.toml"), toml_content)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue