feat: add css library for EPUB exports
This commit is contained in:
parent
d50bbdfb58
commit
4247fab1ea
4 changed files with 32 additions and 3 deletions
|
@ -118,6 +118,10 @@ into a single epub using the `merge` flag and specifying the output file.
|
||||||
paperoni -f links.txt --merge out.epub
|
paperoni -f links.txt --merge out.epub
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Recommended fonts
|
||||||
|
|
||||||
|
The styling on the EPUB files comes from the [writ.css](https://github.com/causal-agent/writ) library. This uses Palatino as the serif font which you can get online for free. However, you can use whichever serif fonts you have installed.
|
||||||
|
|
||||||
### Logging events
|
### Logging events
|
||||||
|
|
||||||
Logging is disabled by default. This can be activated by either using the `-v` flag or `--log-to-file` flag. If the `--log-to-file` flag is passed the logs are sent to a file in the default Paperoni directory `.paperoni/logs` which is on your home directory. The `-v` flag configures the verbosity levels such that:
|
Logging is disabled by default. This can be activated by either using the `-v` flag or `--log-to-file` flag. If the `--log-to-file` flag is passed the logs are sent to a file in the default Paperoni directory `.paperoni/logs` which is on your home directory. The `-v` flag configures the verbosity levels such that:
|
||||||
|
|
7
src/assets/writ.min.css
vendored
Normal file
7
src/assets/writ.min.css
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/*!
|
||||||
|
* Writ v1.0.4
|
||||||
|
*
|
||||||
|
* Copyright © 2015, Curtis McEnroe <curtis@cmcenroe.me>
|
||||||
|
*
|
||||||
|
* https://cmcenroe.me/writ/LICENSE (ISC)
|
||||||
|
*/dd,hr,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow-x:auto}a,ins{text-decoration:none}html{font-family:Palatino,Georgia,Lucida Bright,Book Antiqua,serif;font-size:16px;line-height:1.5rem}code,kbd,pre,samp{font-family:Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:.833rem;color:#111}kbd{font-weight:700}h1,h2,h3,h4,h5,h6,th{font-weight:400}h1{font-size:2.488em}h2{font-size:2.074em}h3{font-size:1.728em}h4{font-size:1.44em}h5{font-size:1.2em}h6{font-size:1em}small{font-size:.833em}h1,h2,h3{line-height:3rem}blockquote,dl,h1,h2,h3,h4,h5,h6,ol,p,pre,table,ul{margin:1.5rem 0 0}pre,table{margin-bottom:-1px}hr{border:none;padding:1.5rem 0 0}table{line-height:calc(1.5rem - 1px);width:100%;border-collapse:collapse}pre{margin-top:calc(1.5rem - 1px)}body{color:#222;margin:1.5rem 1ch}a,a code,header nav a:visited{color:#00e}a:visited,a:visited code{color:#60b}mark{color:inherit;background-color:#fe0}code,pre,samp,tfoot,thead{background-color:rgba(0,0,0,.05)}blockquote,ins,main aside{border:rgba(0,0,0,.05) solid}blockquote,main aside{border-width:0 0 0 .5ch}code,pre,samp{border:rgba(0,0,0,.1) solid}td,th{border:solid #dbdbdb}body>header{text-align:center}body>footer,main{display:block;max-width:78ch;margin:auto}main aside,main figure{float:right;margin:1.5rem 0 0 1ch}main aside{max-width:26ch;padding:0 0 0 .5ch}blockquote{margin-right:3ch;margin-left:1.5ch;padding:0 0 0 1ch}pre{border-width:1px;border-radius:2px;padding:0 .5ch}pre code{border:none;padding:0;background-color:transparent;white-space:inherit}code,ins,samp,td,th{border-width:1px}img{max-width:100%}dd,ol,ul{padding:0 0 0 3ch}ul>li{list-style-type:disc}li ul>li{list-style-type:circle}li li ul>li{list-style-type:square}ol>li{list-style-type:decimal}li ol>li{list-style-type:lower-roman}li li ol>li{list-style-type:lower-alpha}nav ul{padding:0;list-style-type:none}nav ul li{display:inline;padding-left:1ch;white-space:nowrap}nav ul li:first-child{padding-left:0}ins,mark{padding:1px}td,th{padding:0 .5ch}sub,sup{font-size:.75em;line-height:1em}code,samp{border-radius:2px;padding:.1em .2em;white-space:nowrap}
|
23
src/epub.rs
23
src/epub.rs
|
@ -3,9 +3,10 @@ use std::fs::File;
|
||||||
|
|
||||||
use comfy_table::{Attribute, Cell, CellAlignment, Color, ContentArrangement, Table};
|
use comfy_table::{Attribute, Cell, CellAlignment, Color, ContentArrangement, Table};
|
||||||
use epub_builder::{EpubBuilder, EpubContent, TocElement, ZipLibrary};
|
use epub_builder::{EpubBuilder, EpubContent, TocElement, ZipLibrary};
|
||||||
|
use html5ever::tendril::fmt::Slice;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use kuchiki::NodeRef;
|
use kuchiki::NodeRef;
|
||||||
use log::{debug, info};
|
use log::{debug, error, info};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::AppConfig,
|
cli::AppConfig,
|
||||||
|
@ -27,8 +28,8 @@ pub fn generate_epubs(
|
||||||
} else {
|
} else {
|
||||||
let enabled_bar = ProgressBar::new(articles.len() as u64);
|
let enabled_bar = ProgressBar::new(articles.len() as u64);
|
||||||
let style = ProgressStyle::default_bar().template(
|
let style = ProgressStyle::default_bar().template(
|
||||||
"{spinner:.cyan} [{elapsed_precise}] {bar:40.white} {:>8} epub {pos}/{len:7} {msg:.green}",
|
"{spinner:.cyan} [{elapsed_precise}] {bar:40.white} {:>8} epub {pos}/{len:7} {msg:.green}",
|
||||||
);
|
);
|
||||||
enabled_bar.set_style(style);
|
enabled_bar.set_style(style);
|
||||||
if !articles.is_empty() {
|
if !articles.is_empty() {
|
||||||
enabled_bar.set_message("Generating epubs");
|
enabled_bar.set_message("Generating epubs");
|
||||||
|
@ -36,6 +37,8 @@ pub fn generate_epubs(
|
||||||
enabled_bar
|
enabled_bar
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let stylesheet = include_bytes!("./assets/writ.min.css");
|
||||||
|
|
||||||
let mut errors: Vec<PaperoniError> = Vec::new();
|
let mut errors: Vec<PaperoniError> = Vec::new();
|
||||||
|
|
||||||
match app_config.merged {
|
match app_config.merged {
|
||||||
|
@ -64,6 +67,16 @@ pub fn generate_epubs(
|
||||||
};
|
};
|
||||||
debug!("Creating {:?}", name);
|
debug!("Creating {:?}", name);
|
||||||
epub.inline_toc();
|
epub.inline_toc();
|
||||||
|
match epub.stylesheet(stylesheet.as_bytes()) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Unable to add stylesheets to epub file");
|
||||||
|
let mut paperoni_err: PaperoniError = e.into();
|
||||||
|
paperoni_err.set_article_source(name);
|
||||||
|
errors.push(paperoni_err);
|
||||||
|
return Err(errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
articles
|
articles
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -168,6 +181,9 @@ pub fn generate_epubs(
|
||||||
if let Some(author) = article.metadata().byline() {
|
if let Some(author) = article.metadata().byline() {
|
||||||
epub.metadata("author", replace_escaped_characters(author))?;
|
epub.metadata("author", replace_escaped_characters(author))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
epub.stylesheet(stylesheet.as_bytes())?;
|
||||||
|
|
||||||
let title = replace_escaped_characters(article.metadata().title());
|
let title = replace_escaped_characters(article.metadata().title());
|
||||||
epub.metadata("title", &title)?;
|
epub.metadata("title", &title)?;
|
||||||
|
|
||||||
|
@ -248,6 +264,7 @@ fn generate_appendix(articles: Vec<&Extractor>) -> String {
|
||||||
let template = format!(
|
let template = format!(
|
||||||
r#"<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
r#"<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="stylesheet" href="stylesheet.css" type="text/css"></link>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>Appendix</h2><h3>Article sources</h3>
|
<h2>Appendix</h2><h3>Article sources</h3>
|
||||||
|
|
|
@ -37,6 +37,7 @@ impl Extractor {
|
||||||
let template = r#"
|
let template = r#"
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="stylesheet" href="stylesheet.css" type="text/css"></link>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
|
Reference in a new issue