From 4247fab1eacf91c686d0e278154a7affe7470786 Mon Sep 17 00:00:00 2001 From: Kenneth Gitere Date: Wed, 9 Jun 2021 08:04:50 +0300 Subject: [PATCH] feat: add css library for EPUB exports --- README.md | 4 ++++ src/assets/writ.min.css | 7 +++++++ src/epub.rs | 23 ++++++++++++++++++++--- src/extractor.rs | 1 + 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 src/assets/writ.min.css diff --git a/README.md b/README.md index f38c741..d80bbe7 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,10 @@ into a single epub using the `merge` flag and specifying the output file. 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 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: diff --git a/src/assets/writ.min.css b/src/assets/writ.min.css new file mode 100644 index 0000000..afef597 --- /dev/null +++ b/src/assets/writ.min.css @@ -0,0 +1,7 @@ +/*! + * Writ v1.0.4 + * + * Copyright © 2015, Curtis McEnroe + * + * 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} diff --git a/src/epub.rs b/src/epub.rs index e573260..6dc28b6 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -3,9 +3,10 @@ use std::fs::File; use comfy_table::{Attribute, Cell, CellAlignment, Color, ContentArrangement, Table}; use epub_builder::{EpubBuilder, EpubContent, TocElement, ZipLibrary}; +use html5ever::tendril::fmt::Slice; use indicatif::{ProgressBar, ProgressStyle}; use kuchiki::NodeRef; -use log::{debug, info}; +use log::{debug, error, info}; use crate::{ cli::AppConfig, @@ -27,8 +28,8 @@ pub fn generate_epubs( } else { let enabled_bar = ProgressBar::new(articles.len() as u64); 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); if !articles.is_empty() { enabled_bar.set_message("Generating epubs"); @@ -36,6 +37,8 @@ pub fn generate_epubs( enabled_bar }; + let stylesheet = include_bytes!("./assets/writ.min.css"); + let mut errors: Vec = Vec::new(); match app_config.merged { @@ -64,6 +67,16 @@ pub fn generate_epubs( }; debug!("Creating {:?}", name); 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 .iter() .enumerate() @@ -168,6 +181,9 @@ pub fn generate_epubs( if let Some(author) = article.metadata().byline() { epub.metadata("author", replace_escaped_characters(author))?; } + + epub.stylesheet(stylesheet.as_bytes())?; + let title = replace_escaped_characters(article.metadata().title()); epub.metadata("title", &title)?; @@ -248,6 +264,7 @@ fn generate_appendix(articles: Vec<&Extractor>) -> String { let template = format!( r#" +

Appendix

Article sources

diff --git a/src/extractor.rs b/src/extractor.rs index 110357b..ef470d9 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -37,6 +37,7 @@ impl Extractor { let template = r#" +