From 197a6cb7d5c962eb82c94b5a2304de2efcab27a6 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 28 Nov 2020 16:19:24 -0800 Subject: [PATCH 01/28] 0.5.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 794b490..45d5715 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bk" -version = "0.5.0" +version = "0.5.1" dependencies = [ "anyhow", "argh", diff --git a/Cargo.toml b/Cargo.toml index f7ac1ef..e01e9c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bk" -version = "0.5.0" +version = "0.5.1" authors = ["James Campos "] edition = "2018" license = "MIT" From f20adc60a3dcc744a3adbd40ba6aa6917f06d9c7 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 3 Jan 2021 17:54:33 -0800 Subject: [PATCH 02/28] cargo update --- Cargo.lock | 101 +++++++++++++++++++++++----------------------------- src/epub.rs | 8 ++--- src/view.rs | 23 ++++++------ 3 files changed, 61 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45d5715..754e2ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,9 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "anyhow" -version = "1.0.34" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" +checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" [[package]] name = "argh" @@ -43,9 +43,9 @@ checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1" [[package]] name = "base64" -version = "0.12.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" @@ -85,15 +85,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cloudabi" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" -dependencies = [ - "bitflags", -] - [[package]] name = "crc32fast" version = "1.2.1" @@ -105,9 +96,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb" +checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c" dependencies = [ "bitflags", "crossterm_winapi", @@ -121,9 +112,9 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2265c3f8e080075d9b6417aa72293fc71662f34b4af2612d8d1b074d29510db" +checksum = "0da8964ace4d3e4a044fd027919b2237000b24315a37c916f61809f1ff2140b9" dependencies = [ "winapi", ] @@ -142,9 +133,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" dependencies = [ "unicode-segmentation", ] @@ -166,9 +157,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" [[package]] name = "lock_api" @@ -199,9 +190,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33bc887064ef1fd66020c9adfc45bb9f33d75a42096c81e7c56c65b75dd1a8b" +checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7" dependencies = [ "libc", "log", @@ -242,12 +233,11 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", + "cfg-if 1.0.0", "instant", "libc", "redox_syscall", @@ -266,9 +256,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" dependencies = [ "proc-macro2", ] @@ -281,9 +271,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "ron" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a58080b7bb83b2ea28c3b7a9a994fd5e310330b7c8ca5258d99b98128ecfe4" +checksum = "064ea8613fb712a19faf920022ec8ddf134984f100090764a4e1d768f3827f1f" dependencies = [ "base64", "bitflags", @@ -292,9 +282,9 @@ dependencies = [ [[package]] name = "roxmltree" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17dfc6c39f846bfc7d2ec442ad12055d79608d501380789b965d22f9354451f2" +checksum = "bf58a7d05b28e14b1e8902fa04c4d5d6109f5450ef71a5e6597f66e53f541504" dependencies = [ "xmlparser", ] @@ -307,18 +297,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" dependencies = [ "proc-macro2", "quote", @@ -327,9 +317,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed" +checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729" dependencies = [ "libc", "mio", @@ -338,36 +328,35 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" dependencies = [ "libc", ] [[package]] name = "smallvec" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" +checksum = "1a55ca5f3b68e41c979bf8c46a6f1da892ca4db8f94023ce0bd32407573b1ac0" [[package]] name = "socket2" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", "winapi", ] [[package]] name = "syn" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443b4178719c5a851e1bde36ce12da21d74a0e60b4d982ec3385a933c812f0f6" +checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6" dependencies = [ "proc-macro2", "quote", @@ -376,18 +365,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" +checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" +checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" dependencies = [ "proc-macro2", "quote", @@ -396,9 +385,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8716a166f290ff49dabc18b44aa407cb7c6dbe1aa0971b44b8a24b0ca35aae" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" [[package]] name = "unicode-width" @@ -442,9 +431,9 @@ checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" [[package]] name = "zip" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "543adf038106b64cfca4711c82c917d785e3540e04f7996554488f988ec43124" +checksum = "cc2896475a242c41366941faa27264df2cb935185a92e059a004d0048feb2ac5" dependencies = [ "byteorder", "crc32fast", diff --git a/src/epub.rs b/src/epub.rs index 496ee96..9fb2adc 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -86,7 +86,7 @@ impl Epub { } fn get_spine(&mut self) -> Result> { let xml = self.get_text("META-INF/container.xml"); - let doc = Document::parse(&xml)?; + let doc = Document::parse(&xml).unwrap(); let path = doc .descendants() .find(|n| n.has_tag_name("rootfile")) @@ -94,7 +94,7 @@ impl Epub { .attribute("full-path") .unwrap(); let xml = self.get_text(path); - let doc = Document::parse(&xml)?; + let doc = Document::parse(&xml).unwrap(); // zip expects unix path even on windows self.rootdir = match path.rfind('/') { @@ -131,13 +131,13 @@ impl Epub { .attribute("href") .unwrap(); let xml = self.get_text(&format!("{}{}", self.rootdir, path)); - let doc = Document::parse(&xml)?; + let doc = Document::parse(&xml).unwrap(); epub3(doc, &mut nav); } else { let id = spine_node.attribute("toc").unwrap_or("ncx"); let path = manifest.get(id).unwrap(); let xml = self.get_text(&format!("{}{}", self.rootdir, path)); - let doc = Document::parse(&xml)?; + let doc = Document::parse(&xml).unwrap(); epub2(doc, &mut nav); } Ok(spine_node diff --git a/src/view.rs b/src/view.rs index bdbe0cc..1bc5ca9 100644 --- a/src/view.rs +++ b/src/view.rs @@ -2,6 +2,7 @@ use crossterm::{ event::{ KeyCode::{self, *}, MouseEvent, + MouseEventKind, }, style::Attribute, }; @@ -132,10 +133,10 @@ impl View for Nav { self.cursor(bk); } fn on_mouse(&self, bk: &mut Bk, e: MouseEvent) { - match e { - MouseEvent::Down(_, _, row, _) => self.click(bk, row as usize), - MouseEvent::ScrollDown(_, _, _) => self.next(bk, 3), - MouseEvent::ScrollUp(_, _, _) => self.prev(bk, 3), + match e.kind { + MouseEventKind::Down(_) => self.click(bk, e.row as usize), + MouseEventKind::ScrollDown => self.next(bk, 3), + MouseEventKind::ScrollUp => self.prev(bk, 3), _ => (), } } @@ -183,16 +184,16 @@ impl View for Nav { pub struct Page; impl View for Page { fn on_mouse(&self, bk: &mut Bk, e: MouseEvent) { - match e { - MouseEvent::Down(_, col, row, _) => { + match e.kind { + MouseEventKind::Down(_) => { let c = bk.chap(); - let line = bk.line + row as usize; + let line = bk.line + e.row as usize; - if col < bk.pad() || line >= c.lines.len() { + if e.column < bk.pad() || line >= c.lines.len() { return; } let (start, end) = c.lines[line]; - let line_col = (col - bk.pad()) as usize; + let line_col = (e.column - bk.pad()) as usize; let mut cols = 0; let mut found = false; @@ -227,8 +228,8 @@ impl View for Page { bk.jump((chapter, line)); } } - MouseEvent::ScrollDown(_, _, _) => bk.scroll_down(3), - MouseEvent::ScrollUp(_, _, _) => bk.scroll_up(3), + MouseEventKind::ScrollDown => bk.scroll_down(3), + MouseEventKind::ScrollUp => bk.scroll_up(3), _ => (), } } From 482d58e47791009ddf7bdeb1dec254bc0028f3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Fro=C5=82ow?= Date: Mon, 4 Jan 2021 04:21:49 +0100 Subject: [PATCH 03/28] allow_dtd --- src/epub.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/epub.rs b/src/epub.rs index 9fb2adc..ff78918 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -1,6 +1,6 @@ use anyhow::Result; use crossterm::style::{Attribute, Attributes}; -use roxmltree::{Document, Node}; +use roxmltree::{Document, Node, ParsingOptions}; use std::{collections::HashMap, fs::File, io::Read}; pub struct Chapter { @@ -51,9 +51,11 @@ impl Epub { fn get_chapters(&mut self, spine: Vec<(String, String)>) { for (title, path) in spine { let xml = self.get_text(&format!("{}{}", self.rootdir, path)); + let opt = ParsingOptions { allow_dtd: true }; // https://github.com/RazrFalcon/roxmltree/issues/12 // UnknownEntityReference for HTML entities - let doc = Document::parse(&xml).unwrap(); + let doc = Document::parse_with_options(&xml, opt) + .unwrap_or_else(|_| panic!("Could not parse path: {}", &path)); let body = doc.root_element().last_element_child().unwrap(); let state = Attributes::default(); let mut c = Chapter { From dcf3178721beae1a98a6d1030f1f679be7d819f1 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 3 Jan 2021 22:11:13 -0800 Subject: [PATCH 04/28] stricter dep versions --- Cargo.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e01e9c9..5bfa167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,15 +11,15 @@ readme = "README.md" repository = "https://github.com/aeosynth/bk" [dependencies] -anyhow = "1" -argh = "0" -crossterm = "0" -ron = "0" -roxmltree = "0" -serde = "1" -unicode-width = "0" +anyhow = "^1.0" +argh = "^0.1" +crossterm = "^0.19" +ron = "^0.6" +roxmltree = "^0.14" +serde = "^1.0" +unicode-width = "^0.1" [dependencies.zip] -version = "0" +version = "^0.5" default-features = false features = ["deflate"] From 91647ca4c826d83210f54d29871d606b15e37c80 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 4 Jan 2021 15:56:34 -0800 Subject: [PATCH 05/28] tweak --- src/epub.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/epub.rs b/src/epub.rs index ff78918..fa88234 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -50,12 +50,11 @@ impl Epub { } fn get_chapters(&mut self, spine: Vec<(String, String)>) { for (title, path) in spine { - let xml = self.get_text(&format!("{}{}", self.rootdir, path)); - let opt = ParsingOptions { allow_dtd: true }; // https://github.com/RazrFalcon/roxmltree/issues/12 // UnknownEntityReference for HTML entities - let doc = Document::parse_with_options(&xml, opt) - .unwrap_or_else(|_| panic!("Could not parse path: {}", &path)); + let xml = self.get_text(&format!("{}{}", self.rootdir, path)); + let opt = ParsingOptions { allow_dtd: true }; + let doc = Document::parse_with_options(&xml, opt).unwrap(); let body = doc.root_element().last_element_child().unwrap(); let state = Attributes::default(); let mut c = Chapter { From 8c36ebb0d040dcfa70a399cd2e71647c5d003cfe Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 4 Jan 2021 18:25:56 -0800 Subject: [PATCH 06/28] nav -> toc --- src/main.rs | 4 ++-- src/view.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index fedcdc6..1b4c351 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ use std::{ use unicode_width::UnicodeWidthChar; mod view; -use view::{Nav, Page, Search, View}; +use view::{Toc, Page, Search, View}; mod epub; use epub::Chapter; @@ -146,7 +146,7 @@ impl Bk<'_> { cols, rows: rows as usize, max_width: args.width, - view: Some(if args.toc { &Nav } else { &Page }), + view: Some(if args.toc { &Toc } else { &Page }), cursor: 0, dir: Direction::Next, meta, diff --git a/src/view.rs b/src/view.rs index 1bc5ca9..50af1c6 100644 --- a/src/view.rs +++ b/src/view.rs @@ -106,8 +106,8 @@ PageDown Right Space f l Page Down } } -pub struct Nav; -impl Nav { +pub struct Toc; +impl Toc { fn prev(&self, bk: &mut Bk, n: usize) { bk.chapter = bk.chapter.saturating_sub(n); self.cursor(bk); @@ -128,7 +128,7 @@ impl Nav { } } } -impl View for Nav { +impl View for Toc { fn on_resize(&self, bk: &mut Bk) { self.cursor(bk); } @@ -238,8 +238,8 @@ impl View for Page { Esc | Char('q') => bk.view = None, Tab => { bk.mark('\''); - Nav.cursor(bk); - bk.view = Some(&Nav); + Toc.cursor(bk); + bk.view = Some(&Toc); } F(_) => bk.view = Some(&Help), Char('m') => bk.view = Some(&Mark), From b6dda9fa8e1c159412c177fb3cc0a55652091d35 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 4 Jan 2021 18:27:21 -0800 Subject: [PATCH 07/28] subsections --- src/epub.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/epub.rs b/src/epub.rs index fa88234..7357cda 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -250,7 +250,8 @@ fn epub2(doc: Document, nav: &mut HashMap) { .text() .unwrap() .to_string(); - nav.insert(path, text); + // TODO subsections + nav.entry(path).or_insert(text); }); } fn epub3(doc: Document, nav: &mut HashMap) { From 88554c41dbc1a2dcfe7cb6a2c8e277d06075b0e9 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 4 Jan 2021 21:52:03 -0800 Subject: [PATCH 08/28] tweak page progress --- src/view.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/view.rs b/src/view.rs index 50af1c6..1fdb449 100644 --- a/src/view.rs +++ b/src/view.rs @@ -58,8 +58,9 @@ impl View for Metadata { let total = lines.iter().sum::(); let progress = current as f32 / total as f32 * 100.0; - let pages = lines[bk.chapter] / bk.rows; - let page = bk.line / bk.rows; + let pages = (lines[bk.chapter] as f32 / bk.rows as f32).ceil() as usize; + // if the last line is visible we're on the last page. first page is the short one + let page = pages - (lines[bk.chapter] - 1 - bk.line) / bk.rows; let mut vec = vec![ format!("chapter: {}/{}", page, pages), From 4bce09ec025c1de859da556b14b76d67824e5754 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 4 Jan 2021 21:55:11 -0800 Subject: [PATCH 09/28] 0.5.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 754e2ff..2be4a2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bk" -version = "0.5.1" +version = "0.5.2" dependencies = [ "anyhow", "argh", diff --git a/Cargo.toml b/Cargo.toml index 5bfa167..e67bf73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bk" -version = "0.5.1" +version = "0.5.2" authors = ["James Campos "] edition = "2018" license = "MIT" From a7f3196c240c790e281e7a24ed2d6d2fa2da0776 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 25 Jan 2021 17:12:22 -0800 Subject: [PATCH 10/28] update --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2be4a2c..604c580 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,9 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "anyhow" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" [[package]] name = "argh" @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.3.4" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" [[package]] name = "cfg-if" @@ -157,9 +157,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" [[package]] name = "lock_api" @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" dependencies = [ "cfg-if 0.1.10", ] @@ -297,18 +297,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.118" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" dependencies = [ "proc-macro2", "quote", @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a55ca5f3b68e41c979bf8c46a6f1da892ca4db8f94023ce0bd32407573b1ac0" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "socket2" @@ -354,9 +354,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.57" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", From 5c46d948c54cbeb0a5c3403df6f4bd0236a59757 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 25 Jan 2021 17:51:14 -0800 Subject: [PATCH 11/28] ignore mousemove, fix #16 --- src/main.rs | 44 ++++++++++++++++++++++++++++++-------------- src/view.rs | 33 ++++++++++++++++----------------- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1b4c351..d330bf8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use anyhow::Result; use crossterm::{ cursor, - event::{self, DisableMouseCapture, EnableMouseCapture, Event}, + event::{DisableMouseCapture, EnableMouseCapture, Event}, queue, style::{self, Print}, terminal, @@ -18,7 +18,7 @@ use std::{ use unicode_width::UnicodeWidthChar; mod view; -use view::{Toc, Page, Search, View}; +use view::{Page, Search, Toc, View}; mod epub; use epub::Chapter; @@ -97,6 +97,7 @@ enum Direction { } pub struct Bk<'a> { + quit: bool, chapters: Vec, // position in the book chapter: usize, @@ -108,7 +109,7 @@ pub struct Bk<'a> { rows: usize, max_width: u16, // view state - view: Option<&'a dyn View>, + view: &'a dyn View, cursor: usize, dir: Direction, meta: Vec, @@ -138,6 +139,7 @@ impl Bk<'_> { } let mut bk = Bk { + quit: false, chapters, chapter: args.chapter, line: 0, @@ -146,7 +148,7 @@ impl Bk<'_> { cols, rows: rows as usize, max_width: args.width, - view: Some(if args.toc { &Toc } else { &Page }), + view: if args.toc { &Toc } else { &Page }, cursor: 0, dir: Direction::Next, meta, @@ -171,21 +173,31 @@ impl Bk<'_> { )?; terminal::enable_raw_mode()?; - while let Some(view) = self.view { + let mut render = |bk: &Bk| { queue!( stdout, terminal::Clear(terminal::ClearType::All), Print(style::Attribute::Reset) - )?; - for (i, line) in view.render(self).iter().enumerate() { - queue!(stdout, cursor::MoveTo(self.pad(), i as u16), Print(line))?; + ) + .unwrap(); + for (i, line) in bk.view.render(bk).iter().enumerate() { + queue!(stdout, cursor::MoveTo(bk.pad(), i as u16), Print(line)).unwrap(); } - queue!(stdout, cursor::MoveTo(self.pad(), self.cursor as u16))?; + queue!(stdout, cursor::MoveTo(bk.pad(), bk.cursor as u16)).unwrap(); stdout.flush().unwrap(); + }; - match event::read()? { - Event::Key(e) => view.on_key(self, e.code), - Event::Mouse(e) => view.on_mouse(self, e), + render(self); + loop { + match crossterm::event::read()? { + Event::Key(e) => self.view.on_key(self, e.code), + Event::Mouse(e) => { + // XXX idk seems lame + if e.kind == crossterm::event::MouseEventKind::Moved { + continue; + } + self.view.on_mouse(self, e); + } Event::Resize(cols, rows) => { self.rows = rows as usize; if cols != self.cols { @@ -195,10 +207,14 @@ impl Bk<'_> { c.lines = wrap(&c.text, width); } } - view.on_resize(self); + self.view.on_resize(self); // XXX marks aren't updated } } + if self.quit { + break; + } + render(self); } queue!( @@ -256,7 +272,7 @@ impl Bk<'_> { self.mark('\''); self.query.clear(); self.dir = dir; - self.view = Some(&Search); + self.view = &Search; } fn search(&mut self, args: SearchArgs) -> bool { let (start, end) = self.chap().lines[self.line]; diff --git a/src/view.rs b/src/view.rs index 1fdb449..6d4af33 100644 --- a/src/view.rs +++ b/src/view.rs @@ -1,8 +1,7 @@ use crossterm::{ event::{ KeyCode::{self, *}, - MouseEvent, - MouseEventKind, + MouseEvent, MouseEventKind, }, style::Attribute, }; @@ -25,7 +24,7 @@ impl View for Mark { if let Char(c) = kc { bk.mark(c) } - bk.view = Some(&Page) + bk.view = &Page } fn render(&self, bk: &Bk) -> Vec { Page::render(&Page, bk) @@ -40,7 +39,7 @@ impl View for Jump { bk.jump(pos); } } - bk.view = Some(&Page); + bk.view = &Page; } fn render(&self, bk: &Bk) -> Vec { Page::render(&Page, bk) @@ -50,7 +49,7 @@ impl View for Jump { struct Metadata; impl View for Metadata { fn on_key(&self, bk: &mut Bk, _: KeyCode) { - bk.view = Some(&Page); + bk.view = &Page; } fn render(&self, bk: &Bk) -> Vec { let lines: Vec = bk.chapters.iter().map(|c| c.lines.len()).collect(); @@ -75,7 +74,7 @@ impl View for Metadata { struct Help; impl View for Help { fn on_key(&self, bk: &mut Bk, _: KeyCode) { - bk.view = Some(&Page); + bk.view = &Page; } fn render(&self, _: &Bk) -> Vec { let text = r#" @@ -125,7 +124,7 @@ impl Toc { if start + row < bk.chapters.len() { bk.chapter = start + row; bk.line = 0; - bk.view = Some(&Page); + bk.view = &Page; } } } @@ -146,12 +145,12 @@ impl View for Toc { Esc | Tab | Left | Char('h') | Char('q') => { bk.jump_reset(); bk.cursor = 0; - bk.view = Some(&Page); + bk.view = &Page; } Enter | Right | Char('l') => { bk.cursor = 0; bk.line = 0; - bk.view = Some(&Page); + bk.view = &Page; } Down | Char('j') => self.next(bk, 1), Up | Char('k') => self.prev(bk, 1), @@ -236,16 +235,16 @@ impl View for Page { } fn on_key(&self, bk: &mut Bk, kc: KeyCode) { match kc { - Esc | Char('q') => bk.view = None, + Esc | Char('q') => bk.quit = true, Tab => { bk.mark('\''); Toc.cursor(bk); - bk.view = Some(&Toc); + bk.view = &Toc; } - F(_) => bk.view = Some(&Help), - Char('m') => bk.view = Some(&Mark), - Char('\'') => bk.view = Some(&Jump), - Char('i') => bk.view = Some(&Metadata), + F(_) => bk.view = &Help, + Char('m') => bk.view = &Mark, + Char('\'') => bk.view = &Jump, + Char('i') => bk.view = &Metadata, Char('?') => bk.start_search(Direction::Prev), Char('/') => bk.start_search(Direction::Next), Char('N') => { @@ -380,10 +379,10 @@ impl View for Search { match kc { Esc => { bk.jump_reset(); - bk.view = Some(&Page); + bk.view = &Page; } Enter => { - bk.view = Some(&Page); + bk.view = &Page; } Backspace => { bk.query.pop(); From 599dab45bba56245d679ef63e96a19e6bb3c2528 Mon Sep 17 00:00:00 2001 From: James Campos Date: Thu, 25 Mar 2021 17:37:51 -0700 Subject: [PATCH 12/28] update --- Cargo.lock | 77 ++++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 604c580..b34e8e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,9 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "anyhow" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767" [[package]] name = "argh" @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cfg-if" @@ -157,9 +157,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.82" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" +checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7" [[package]] name = "lock_api" @@ -172,11 +172,11 @@ dependencies = [ [[package]] name = "log" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] @@ -190,9 +190,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.7" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7" +checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" dependencies = [ "libc", "log", @@ -203,11 +203,10 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "socket2", "winapi", ] @@ -233,9 +232,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" dependencies = [ "cfg-if 1.0.0", "instant", @@ -256,18 +255,21 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.1.57" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] [[package]] name = "ron" @@ -297,18 +299,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.123" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.123" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", "quote", @@ -341,22 +343,11 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi", -] - [[package]] name = "syn" -version = "1.0.60" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" dependencies = [ "proc-macro2", "quote", @@ -365,18 +356,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ "proc-macro2", "quote", @@ -431,9 +422,9 @@ checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" [[package]] name = "zip" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2896475a242c41366941faa27264df2cb935185a92e059a004d0048feb2ac5" +checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6" dependencies = [ "byteorder", "crc32fast", From 5f6d7208fbed417afa23f1ec6cc982685fffc21c Mon Sep 17 00:00:00 2001 From: James Campos Date: Thu, 25 Mar 2021 21:07:48 -0700 Subject: [PATCH 13/28] internal --- src/main.rs | 85 +++----------------- src/view.rs | 219 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 160 insertions(+), 144 deletions(-) diff --git a/src/main.rs b/src/main.rs index d330bf8..f2ba392 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,13 +12,12 @@ use std::{ collections::HashMap, env, fs, io::{stdout, Write}, - iter, process::exit, }; use unicode_width::UnicodeWidthChar; mod view; -use view::{Page, Search, Toc, View}; +use view::{Page, Toc, View}; mod epub; use epub::Chapter; @@ -133,7 +132,7 @@ impl Bk<'_> { .title .chars() .take(width - 1) - .chain(iter::once('…')) + .chain(std::iter::once('…')) .collect(); } } @@ -160,9 +159,6 @@ impl Bk<'_> { bk } - fn pad(&self) -> u16 { - self.cols.saturating_sub(self.max_width) / 2 - } fn run(&mut self) -> crossterm::Result<()> { let mut stdout = stdout(); queue!( @@ -225,8 +221,8 @@ impl Bk<'_> { )?; terminal::disable_raw_mode() } - fn mark(&mut self, c: char) { - self.mark.insert(c, (self.chapter, self.line)); + fn chap(&self) -> &Chapter { + &self.chapters[self.chapter] } fn jump(&mut self, (c, l): (usize, usize)) { self.mark('\''); @@ -238,74 +234,11 @@ impl Bk<'_> { self.chapter = c; self.line = l; } - fn chap(&self) -> &Chapter { - &self.chapters[self.chapter] - } - fn next_chapter(&mut self) { - if self.chapter < self.chapters.len() - 1 { - self.chapter += 1; - self.line = 0; - } - } - fn prev_chapter(&mut self) { - if self.chapter > 0 { - self.chapter -= 1; - self.line = 0; - } - } - fn scroll_down(&mut self, n: usize) { - if self.line + self.rows < self.chap().lines.len() { - self.line += n; - } else { - self.next_chapter(); - } - } - fn scroll_up(&mut self, n: usize) { - if self.line > 0 { - self.line = self.line.saturating_sub(n); - } else if self.chapter > 0 { - self.chapter -= 1; - self.line = self.chap().lines.len().saturating_sub(self.rows); - } - } - fn start_search(&mut self, dir: Direction) { - self.mark('\''); - self.query.clear(); - self.dir = dir; - self.view = &Search; + fn mark(&mut self, c: char) { + self.mark.insert(c, (self.chapter, self.line)); } - fn search(&mut self, args: SearchArgs) -> bool { - let (start, end) = self.chap().lines[self.line]; - match args.dir { - Direction::Next => { - let byte = if args.skip { end } else { start }; - let head = (self.chapter, byte); - let tail = (self.chapter + 1..self.chapters.len() - 1).map(|n| (n, 0)); - for (c, byte) in iter::once(head).chain(tail) { - if let Some(index) = self.chapters[c].text[byte..].find(&self.query) { - self.line = get_line(&self.chapters[c].lines, index + byte); - self.chapter = c; - return true; - } - } - false - } - Direction::Prev => { - let byte = if args.skip { start } else { end }; - let head = (self.chapter, byte); - let tail = (0..self.chapter) - .rev() - .map(|c| (c, self.chapters[c].text.len())); - for (c, byte) in iter::once(head).chain(tail) { - if let Some(index) = self.chapters[c].text[..byte].rfind(&self.query) { - self.line = get_line(&self.chapters[c].lines, index); - self.chapter = c; - return true; - } - } - false - } - } + fn pad(&self) -> u16 { + self.cols.saturating_sub(self.max_width) / 2 } } @@ -377,7 +310,7 @@ fn init() -> Result { } let (path, chapter, byte) = match (&save, &path) { - (Err(_), None) => return Err(anyhow::anyhow!("no path arg and no or invalid save file")), + (Err(_), None) => return Err(anyhow::anyhow!("no path arg and no valid save file")), (Err(_), Some(p)) => (p, 0, 0), (Ok(save), None) => { let &(chapter, byte) = save.files.get(&save.last).unwrap(); diff --git a/src/view.rs b/src/view.rs index 6d4af33..2028fda 100644 --- a/src/view.rs +++ b/src/view.rs @@ -8,7 +8,7 @@ use crossterm::{ use std::cmp::{min, Ordering}; use unicode_width::UnicodeWidthChar; -use crate::{get_line, Bk, Direction, SearchArgs}; +use crate::{Bk, Direction, SearchArgs}; pub trait View { fn render(&self, bk: &Bk) -> Vec; @@ -148,8 +148,8 @@ impl View for Toc { bk.view = &Page; } Enter | Right | Char('l') => { - bk.cursor = 0; bk.line = 0; + bk.cursor = 0; bk.view = &Page; } Down | Char('j') => self.next(bk, 1), @@ -182,54 +182,90 @@ impl View for Toc { } pub struct Page; -impl View for Page { - fn on_mouse(&self, bk: &mut Bk, e: MouseEvent) { - match e.kind { - MouseEventKind::Down(_) => { - let c = bk.chap(); - let line = bk.line + e.row as usize; - - if e.column < bk.pad() || line >= c.lines.len() { - return; - } - let (start, end) = c.lines[line]; - let line_col = (e.column - bk.pad()) as usize; +impl Page { + fn next_chapter(&self, bk: &mut Bk) { + if bk.chapter < bk.chapters.len() - 1 { + bk.chapter += 1; + bk.line = 0; + } + } + fn prev_chapter(&self, bk: &mut Bk) { + if bk.chapter > 0 { + bk.chapter -= 1; + bk.line = 0; + } + } + fn scroll_down(&self, bk: &mut Bk, n: usize) { + if bk.line + bk.rows < bk.chap().lines.len() { + bk.line += n; + } else { + self.next_chapter(bk); + } + } + fn scroll_up(&self, bk: &mut Bk, n: usize) { + if bk.line > 0 { + bk.line = bk.line.saturating_sub(n); + } else if bk.chapter > 0 { + bk.chapter -= 1; + bk.line = bk.chap().lines.len().saturating_sub(bk.rows); + } + } + fn click(&self, bk: &mut Bk, e: MouseEvent) { + let c = bk.chap(); + let line = bk.line + e.row as usize; - let mut cols = 0; - let mut found = false; - let mut byte = start; - for (i, c) in c.text[start..end].char_indices() { - cols += c.width().unwrap(); - if cols > line_col { - byte += i; - found = true; - break; - } - } + if e.column < bk.pad() || line >= c.lines.len() { + return; + } + let (start, end) = c.lines[line]; + let line_col = (e.column - bk.pad()) as usize; - if !found { - return; - } + let mut cols = 0; + let mut found = false; + let mut byte = start; + for (i, c) in c.text[start..end].char_indices() { + cols += c.width().unwrap(); + if cols > line_col { + byte += i; + found = true; + break; + } + } - let r = c.links.binary_search_by(|&(start, end, _)| { - if start > byte { - Ordering::Greater - } else if end <= byte { - Ordering::Less - } else { - Ordering::Equal - } - }); + if !found { + return; + } - if let Ok(i) = r { - let url = &c.links[i].2; - let &(chapter, byte) = bk.links.get(url).unwrap(); - let line = get_line(&bk.chapters[chapter].lines, byte); - bk.jump((chapter, line)); - } + let r = c.links.binary_search_by(|&(start, end, _)| { + if start > byte { + Ordering::Greater + } else if end <= byte { + Ordering::Less + } else { + Ordering::Equal } - MouseEventKind::ScrollDown => bk.scroll_down(3), - MouseEventKind::ScrollUp => bk.scroll_up(3), + }); + + if let Ok(i) = r { + let url = &c.links[i].2; + let &(chapter, byte) = bk.links.get(url).unwrap(); + let line = super::get_line(&bk.chapters[chapter].lines, byte); + bk.jump((chapter, line)); + } + } + fn start_search(&self, bk: &mut Bk, dir: Direction) { + bk.mark('\''); + bk.query.clear(); + bk.dir = dir; + bk.view = &Search; + } +} +impl View for Page { + fn on_mouse(&self, bk: &mut Bk, e: MouseEvent) { + match e.kind { + MouseEventKind::Down(_) => self.click(bk, e), + MouseEventKind::ScrollDown => self.scroll_down(bk, 3), + MouseEventKind::ScrollUp => self.scroll_up(bk, 3), _ => (), } } @@ -245,19 +281,27 @@ impl View for Page { Char('m') => bk.view = &Mark, Char('\'') => bk.view = &Jump, Char('i') => bk.view = &Metadata, - Char('?') => bk.start_search(Direction::Prev), - Char('/') => bk.start_search(Direction::Next), + Char('?') => self.start_search(bk, Direction::Prev), + Char('/') => self.start_search(bk, Direction::Next), Char('N') => { - bk.search(SearchArgs { - dir: Direction::Prev, - skip: true, - }); + Search::search( + &Search, + bk, + SearchArgs { + dir: Direction::Prev, + skip: true, + }, + ); } Char('n') => { - bk.search(SearchArgs { - dir: Direction::Next, - skip: true, - }); + Search::search( + &Search, + bk, + SearchArgs { + dir: Direction::Next, + skip: true, + }, + ); } End | Char('G') => { bk.mark('\''); @@ -267,16 +311,16 @@ impl View for Page { bk.mark('\''); bk.line = 0; } - Char('d') => bk.scroll_down(bk.rows / 2), - Char('u') => bk.scroll_up(bk.rows / 2), - Up | Char('k') => bk.scroll_up(3), + Char('d') => self.scroll_down(bk, bk.rows / 2), + Char('u') => self.scroll_up(bk, bk.rows / 2), + Up | Char('k') => self.scroll_up(bk, 3), Left | PageUp | Char('b') | Char('h') => { - bk.scroll_up(bk.rows); + self.scroll_up(bk, bk.rows); } - Down | Char('j') => bk.scroll_down(3), - Right | PageDown | Char('f') | Char('l') | Char(' ') => bk.scroll_down(bk.rows), - Char('[') => bk.prev_chapter(), - Char(']') => bk.next_chapter(), + Down | Char('j') => self.scroll_down(bk, 3), + Right | PageDown | Char('f') | Char('l') | Char(' ') => self.scroll_down(bk, bk.rows), + Char('[') => self.prev_chapter(bk), + Char(']') => self.next_chapter(bk), _ => (), } } @@ -374,11 +418,47 @@ impl View for Page { } pub struct Search; +impl Search { + fn search(&self, bk: &mut Bk, args: SearchArgs) -> bool { + let (start, end) = bk.chap().lines[bk.line]; + match args.dir { + Direction::Next => { + let byte = if args.skip { end } else { start }; + let head = (bk.chapter, byte); + let tail = (bk.chapter + 1..bk.chapters.len() - 1).map(|n| (n, 0)); + for (c, byte) in std::iter::once(head).chain(tail) { + if let Some(index) = bk.chapters[c].text[byte..].find(&bk.query) { + bk.line = super::get_line(&bk.chapters[c].lines, index + byte); + bk.chapter = c; + return true; + } + } + false + } + Direction::Prev => { + let byte = if args.skip { start } else { end }; + let head = (bk.chapter, byte); + let tail = (0..bk.chapter) + .rev() + .map(|c| (c, bk.chapters[c].text.len())); + for (c, byte) in std::iter::once(head).chain(tail) { + if let Some(index) = bk.chapters[c].text[..byte].rfind(&bk.query) { + bk.line = super::get_line(&bk.chapters[c].lines, index); + bk.chapter = c; + return true; + } + } + false + } + } + } +} impl View for Search { fn on_key(&self, bk: &mut Bk, kc: KeyCode) { match kc { Esc => { bk.jump_reset(); + bk.query.clear(); bk.view = &Page; } Enter => { @@ -387,10 +467,13 @@ impl View for Search { Backspace => { bk.query.pop(); bk.jump_reset(); - bk.search(SearchArgs { - dir: bk.dir.clone(), - skip: false, - }); + self.search( + bk, + SearchArgs { + dir: bk.dir.clone(), + skip: false, + }, + ); } Char(c) => { bk.query.push(c); @@ -398,7 +481,7 @@ impl View for Search { dir: bk.dir.clone(), skip: false, }; - if !bk.search(args) { + if self.search(bk, args) { bk.jump_reset(); } } From 48786a80c2f96afd9a935688015ffd5da1cbfeb0 Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 26 Mar 2021 20:07:44 -0700 Subject: [PATCH 14/28] normal intensity --- src/epub.rs | 4 +- src/view.rs | 129 +++++++++++++++++++++++++++------------------------- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/src/epub.rs b/src/epub.rs index 7357cda..66d1077 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -205,10 +205,10 @@ fn render(n: Node, c: &mut Chapter) { } } "em" => c.render(n, Attribute::Italic, Attribute::NoItalic), - "strong" => c.render(n, Attribute::Bold, Attribute::NoBold), + "strong" => c.render(n, Attribute::Bold, Attribute::NormalIntensity), "h1" | "h2" | "h3" | "h4" | "h5" | "h6" => { c.text.push('\n'); - c.render(n, Attribute::Bold, Attribute::NoBold); + c.render(n, Attribute::Bold, Attribute::NormalIntensity); c.text.push('\n'); } "blockquote" | "div" | "p" | "tr" => { diff --git a/src/view.rs b/src/view.rs index 2028fda..e06c1ff 100644 --- a/src/view.rs +++ b/src/view.rs @@ -5,7 +5,10 @@ use crossterm::{ }, style::Attribute, }; -use std::cmp::{min, Ordering}; +use std::{ + cmp::{min, Ordering}, + iter, +}; use unicode_width::UnicodeWidthChar; use crate::{Bk, Direction, SearchArgs}; @@ -330,89 +333,89 @@ impl View for Page { } fn render(&self, bk: &Bk) -> Vec { let c = bk.chap(); - let line_end = min(bk.line + bk.rows, c.lines.len()); - - let attrs = { - let text_start = c.lines[bk.line].0; - let text_end = c.lines[line_end - 1].1; - - let qlen = bk.query.len(); - let mut search = Vec::new(); - if qlen > 0 { - for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) { - search.push((text_start + pos, Attribute::Reverse)); - search.push((text_start + pos + qlen, Attribute::NoReverse)); - } - } - let mut search_iter = search.into_iter().peekable(); + let last_line = min(bk.line + bk.rows, c.lines.len()); + let text_start = c.lines[bk.line].0; + let text_end = c.lines[last_line - 1].1; - let mut merged = Vec::new(); - let attr_start = match c + let mut base = { + let start = match c .attrs - .binary_search_by_key(&text_start, |&(pos, _, _)| pos) + .binary_search_by_key(&text_start, |&x| x.0) { Ok(n) => n, Err(n) => n - 1, }; - let mut attrs_iter = c.attrs[attr_start..].iter(); - let (_, _, attr) = attrs_iter.next().unwrap(); + + let attr = c.attrs[start].2; + let mut head = Vec::new(); if attr.has(Attribute::Bold) { - merged.push((text_start, Attribute::Bold)); + head.push((text_start, Attribute::Bold)); } if attr.has(Attribute::Italic) { - merged.push((text_start, Attribute::Italic)); + head.push((text_start, Attribute::Italic)); } if attr.has(Attribute::Underlined) { - merged.push((text_start, Attribute::Underlined)); + head.push((text_start, Attribute::Underlined)); } - let mut attrs_iter = attrs_iter - .map(|&(pos, a, _)| (pos, a)) - .take_while(|(pos, _)| pos <= &text_end) - .peekable(); + let tail = c.attrs[start + 1..] + .iter() + .take_while(|x| x.0 < text_end) + .map(|x| (x.0, x.1)); + head.into_iter().chain(tail).peekable() + }; - // use itertools? - loop { - match (search_iter.peek(), attrs_iter.peek()) { - (None, None) => break, - (Some(_), None) => { - merged.extend(search_iter); - break; - } - (None, Some(_)) => { - merged.extend(attrs_iter); - break; - } - (Some(&s), Some(&a)) => { - if s.0 < a.0 { - merged.push(s); - search_iter.next(); - } else { - merged.push(a); - attrs_iter.next(); - } + let mut search = Vec::new(); + if !bk.query.is_empty() { + let len = bk.query.len(); + for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) { + search.push((text_start + pos, Attribute::Reverse)); + search.push((text_start + pos + len, Attribute::NoReverse)); + } + } + let mut search = search.into_iter().peekable(); + + let mut attrs = Vec::new(); + loop { + match (search.peek(), base.peek()) { + (None, None) => break, + (Some(_), None) => { + attrs.extend(search); + break; + } + (None, Some(_)) => { + attrs.extend(base); + break; + } + (Some(&s), Some(&b)) => { + if s.0 < b.0 { + attrs.push(s); + search.next(); + } else { + attrs.push(b); + base.next(); } } } + } + let mut attrs = attrs.into_iter().peekable(); - merged - }; - - let mut buf = Vec::new(); - let mut iter = attrs.into_iter().peekable(); - for &(mut start, end) in &c.lines[bk.line..line_end] { + // itertools: peeking take while + let mut buf = Vec::with_capacity(last_line - bk.line); + for &(mut pos, line_end) in &c.lines[bk.line..last_line] { let mut s = String::new(); - while let Some(&(pos, attr)) = iter.peek() { - if pos > end { + while let Some(&(attr_pos, attr)) = attrs.peek() { + if attr_pos > line_end { break; } - s.push_str(&c.text[start..pos]); + s.push_str(&c.text[pos..attr_pos]); s.push_str(&attr.to_string()); - start = pos; - iter.next(); + pos = attr_pos; + attrs.next(); } - s.push_str(&c.text[start..end]); + s.push_str(&c.text[pos..line_end]); buf.push(s); } + buf } } @@ -426,7 +429,7 @@ impl Search { let byte = if args.skip { end } else { start }; let head = (bk.chapter, byte); let tail = (bk.chapter + 1..bk.chapters.len() - 1).map(|n| (n, 0)); - for (c, byte) in std::iter::once(head).chain(tail) { + for (c, byte) in iter::once(head).chain(tail) { if let Some(index) = bk.chapters[c].text[byte..].find(&bk.query) { bk.line = super::get_line(&bk.chapters[c].lines, index + byte); bk.chapter = c; @@ -441,7 +444,7 @@ impl Search { let tail = (0..bk.chapter) .rev() .map(|c| (c, bk.chapters[c].text.len())); - for (c, byte) in std::iter::once(head).chain(tail) { + for (c, byte) in iter::once(head).chain(tail) { if let Some(index) = bk.chapters[c].text[..byte].rfind(&bk.query) { bk.line = super::get_line(&bk.chapters[c].lines, index); bk.chapter = c; @@ -481,7 +484,7 @@ impl View for Search { dir: bk.dir.clone(), skip: false, }; - if self.search(bk, args) { + if !self.search(bk, args) { bk.jump_reset(); } } From e89d24bfc8242e43992eb420ffe468092e381a62 Mon Sep 17 00:00:00 2001 From: James Campos Date: Fri, 26 Mar 2021 22:13:10 -0700 Subject: [PATCH 15/28] internal --- src/view.rs | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/view.rs b/src/view.rs index e06c1ff..4a5cb73 100644 --- a/src/view.rs +++ b/src/view.rs @@ -338,29 +338,23 @@ impl View for Page { let text_end = c.lines[last_line - 1].1; let mut base = { - let start = match c - .attrs - .binary_search_by_key(&text_start, |&x| x.0) - { + let start = match c.attrs.binary_search_by_key(&text_start, |&x| x.0) { Ok(n) => n, Err(n) => n - 1, }; - let attr = c.attrs[start].2; + let map = c.attrs[start].2; let mut head = Vec::new(); - if attr.has(Attribute::Bold) { - head.push((text_start, Attribute::Bold)); - } - if attr.has(Attribute::Italic) { - head.push((text_start, Attribute::Italic)); - } - if attr.has(Attribute::Underlined) { - head.push((text_start, Attribute::Underlined)); + let list = [Attribute::Bold, Attribute::Italic, Attribute::Underlined]; + for attr in std::array::IntoIter::new(list) { + if map.has(attr) { + head.push((text_start, attr)); + } } let tail = c.attrs[start + 1..] - .iter() - .take_while(|x| x.0 < text_end) - .map(|x| (x.0, x.1)); + .iter() + .take_while(|x| x.0 <= text_end) + .map(|x| (x.0, x.1)); head.into_iter().chain(tail).peekable() }; @@ -399,18 +393,13 @@ impl View for Page { } let mut attrs = attrs.into_iter().peekable(); - // itertools: peeking take while let mut buf = Vec::with_capacity(last_line - bk.line); for &(mut pos, line_end) in &c.lines[bk.line..last_line] { let mut s = String::new(); - while let Some(&(attr_pos, attr)) = attrs.peek() { - if attr_pos > line_end { - break; - } + while let Some((attr_pos, attr)) = attrs.next_if(|a| a.0 <= line_end) { s.push_str(&c.text[pos..attr_pos]); s.push_str(&attr.to_string()); pos = attr_pos; - attrs.next(); } s.push_str(&c.text[pos..line_end]); buf.push(s); From 72c7da0a85089b3ed6303ef641a137c6ea61927f Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 27 Mar 2021 01:57:04 -0700 Subject: [PATCH 16/28] workflow --- .github/workflows/main.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..6d8d965 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,29 @@ +name: Main + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Stable rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: Build + run: | + cargo build --verbose --release + mv target/release/bk bk-linux + strip bk-linux + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: bk-linux + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 443361479ca7da32c5a9be47b96a65cd4ae8aa80 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 27 Mar 2021 01:57:49 -0700 Subject: [PATCH 17/28] 0.5.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b34e8e3..838a4c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bk" -version = "0.5.2" +version = "0.5.3" dependencies = [ "anyhow", "argh", diff --git a/Cargo.toml b/Cargo.toml index e67bf73..ae660f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bk" -version = "0.5.2" +version = "0.5.3" authors = ["James Campos "] edition = "2018" license = "MIT" From b79c05312df99115d475b69eabd5961e8a4e485f Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 27 Mar 2021 02:15:42 -0700 Subject: [PATCH 18/28] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ce53f76 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +ko_fi: aeosynth From 9809dc99acd2ff65358b7bbe3c1be6c303f558b7 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sun, 28 Mar 2021 01:35:32 -0700 Subject: [PATCH 19/28] remove anyhow doesn't work on None --- Cargo.lock | 7 ------- Cargo.toml | 1 - src/epub.rs | 17 ++++++++++------- src/main.rs | 53 ++++++++++++++++++++++------------------------------- 4 files changed, 32 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 838a4c8..fcc37ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,12 +6,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" -[[package]] -name = "anyhow" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767" - [[package]] name = "argh" version = "0.1.4" @@ -57,7 +51,6 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" name = "bk" version = "0.5.3" dependencies = [ - "anyhow", "argh", "crossterm", "ron", diff --git a/Cargo.toml b/Cargo.toml index ae660f8..9e00bbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ readme = "README.md" repository = "https://github.com/aeosynth/bk" [dependencies] -anyhow = "^1.0" argh = "^0.1" crossterm = "^0.19" ron = "^0.6" diff --git a/src/epub.rs b/src/epub.rs index 66d1077..a52c9d0 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -1,7 +1,10 @@ -use anyhow::Result; use crossterm::style::{Attribute, Attributes}; use roxmltree::{Document, Node, ParsingOptions}; -use std::{collections::HashMap, fs::File, io::Read}; +use std::{ + collections::HashMap, + fs::File, + io::{self, Read}, +}; pub struct Chapter { pub title: String, @@ -24,7 +27,7 @@ pub struct Epub { } impl Epub { - pub fn new(path: &str, meta: bool) -> Result { + pub fn new(path: &str, meta: bool) -> io::Result { let file = File::open(path)?; let mut epub = Epub { container: zip::ZipArchive::new(file)?, @@ -33,7 +36,7 @@ impl Epub { links: HashMap::new(), meta: String::new(), }; - let chapters = epub.get_spine()?; + let chapters = epub.get_spine(); if !meta { epub.get_chapters(chapters); } @@ -85,7 +88,7 @@ impl Epub { self.chapters.push(c); } } - fn get_spine(&mut self) -> Result> { + fn get_spine(&mut self) -> Vec<(String, String)> { let xml = self.get_text("META-INF/container.xml"); let doc = Document::parse(&xml).unwrap(); let path = doc @@ -141,7 +144,7 @@ impl Epub { let doc = Document::parse(&xml).unwrap(); epub2(doc, &mut nav); } - Ok(spine_node + spine_node .children() .filter(Node::is_element) .enumerate() @@ -151,7 +154,7 @@ impl Epub { let label = nav.remove(path).unwrap_or_else(|| i.to_string()); (label, path.to_string()) }) - .collect()) + .collect() } } diff --git a/src/main.rs b/src/main.rs index f2ba392..fefce50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use crossterm::{ cursor, event::{DisableMouseCapture, EnableMouseCapture, Event}, @@ -11,7 +10,7 @@ use std::{ cmp::min, collections::HashMap, env, fs, - io::{stdout, Write}, + io::{self, Write}, process::exit, }; use unicode_width::UnicodeWidthChar; @@ -160,7 +159,7 @@ impl Bk<'_> { bk } fn run(&mut self) -> crossterm::Result<()> { - let mut stdout = stdout(); + let mut stdout = io::stdout(); queue!( stdout, terminal::EnterAlternateScreen, @@ -282,7 +281,7 @@ struct State { bk: Props, } -fn init() -> Result { +fn init() -> Result> { let save_path = if cfg!(windows) { format!("{}\\bk", env::var("APPDATA")?) } else { @@ -290,46 +289,38 @@ fn init() -> Result { }; // XXX will silently create a new default save if ron errors but path arg works. // revisit if/when stabilizing. ez file format upgrades - let save = fs::read_to_string(&save_path) - .map_err(anyhow::Error::new) - .and_then(|s| { - let save: Save = ron::from_str(&s)?; - Ok(save) - }); + let save: io::Result = fs::read_to_string(&save_path).and_then(|s| { + ron::from_str(&s) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "invalid save file")) + }); let args: Args = argh::from_env(); let mut path = args.path; - // abort on path error - if path.is_some() { - path = Some( - fs::canonicalize(path.unwrap())? - .to_str() - .unwrap() - .to_string(), - ); + if let Some(p) = path { + path = Some(fs::canonicalize(p)?.to_str().unwrap().to_string()); } - let (path, chapter, byte) = match (&save, &path) { - (Err(_), None) => return Err(anyhow::anyhow!("no path arg and no valid save file")), - (Err(_), Some(p)) => (p, 0, 0), - (Ok(save), None) => { - let &(chapter, byte) = save.files.get(&save.last).unwrap(); - (&save.last, chapter, byte) + let (path, save, chapter, byte) = match (save, path) { + (Err(e), None) => return Err(Box::new(e)), + (Err(_), Some(p)) => (p, Save::default(), 0, 0), + (Ok(s), None) => { + let &(chapter, byte) = s.files.get(&s.last).unwrap(); + (s.last.clone(), s, chapter, byte) } - (Ok(save), Some(p)) => { - if save.files.contains_key(p) { - let &(chapter, byte) = save.files.get(p).unwrap(); - (p, chapter, byte) + (Ok(s), Some(p)) => { + if s.files.contains_key(&p) { + let &(chapter, byte) = s.files.get(&p).unwrap(); + (p, s, chapter, byte) } else { - (p, 0, 0) + (p, s, 0, 0) } } }; Ok(State { + path, + save, save_path, - path: path.clone(), - save: save.unwrap_or_default(), meta: args.meta, bk: Props { chapter, From 5b9abdbafa6106dda8a7b862f4ce3d037a307961 Mon Sep 17 00:00:00 2001 From: James Campos Date: Thu, 1 Apr 2021 18:31:42 -0700 Subject: [PATCH 20/28] internal --- README.md | 2 +- src/main.rs | 67 ++++++++++++++++++++++-------- src/view.rs | 115 +++++++++++++++------------------------------------- 3 files changed, 83 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index fcb3702..5d94211 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # bk -bk is a WIP terminal EPUB reader, written in Rust. +bk is a terminal EPUB reader, written in Rust. # Features - Cross platform - Linux, macOS and Windows support diff --git a/src/main.rs b/src/main.rs index fefce50..d3e978c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use std::{ collections::HashMap, env, fs, io::{self, Write}, + iter, process::exit, }; use unicode_width::UnicodeWidthChar; @@ -19,7 +20,6 @@ mod view; use view::{Page, Toc, View}; mod epub; -use epub::Chapter; fn wrap(text: &str, max_cols: usize) -> Vec<(usize, usize)> { let mut lines = Vec::new(); @@ -76,13 +76,6 @@ fn wrap(text: &str, max_cols: usize) -> Vec<(usize, usize)> { lines } -fn get_line(lines: &[(usize, usize)], byte: usize) -> usize { - match lines.binary_search_by_key(&byte, |&(a, _)| a) { - Ok(n) => n, - Err(n) => n - 1, - } -} - struct SearchArgs { dir: Direction, skip: bool, @@ -139,7 +132,7 @@ impl Bk<'_> { let mut bk = Bk { quit: false, chapters, - chapter: args.chapter, + chapter: 0, line: 0, mark: HashMap::new(), links: epub.links, @@ -153,7 +146,7 @@ impl Bk<'_> { query: String::new(), }; - bk.line = get_line(&bk.chap().lines, args.byte); + bk.jump_byte(args.chapter, args.byte); bk.mark('\''); bk @@ -220,14 +213,21 @@ impl Bk<'_> { )?; terminal::disable_raw_mode() } - fn chap(&self) -> &Chapter { - &self.chapters[self.chapter] - } fn jump(&mut self, (c, l): (usize, usize)) { self.mark('\''); self.chapter = c; self.line = l; } + fn jump_byte(&mut self, c: usize, byte: usize) { + self.chapter = c; + self.line = match self.chapters[c] + .lines + .binary_search_by_key(&byte, |&(a, _)| a) + { + Ok(n) => n, + Err(n) => n - 1, + } + } fn jump_reset(&mut self) { let &(c, l) = self.mark.get(&'\'').unwrap(); self.chapter = c; @@ -239,6 +239,37 @@ impl Bk<'_> { fn pad(&self) -> u16 { self.cols.saturating_sub(self.max_width) / 2 } + fn search(&mut self, args: SearchArgs) -> bool { + let (start, end) = self.chapters[self.chapter].lines[self.line]; + match args.dir { + Direction::Next => { + let byte = if args.skip { end } else { start }; + let head = (self.chapter, byte); + let tail = (self.chapter + 1..self.chapters.len() - 1).map(|n| (n, 0)); + for (c, byte) in iter::once(head).chain(tail) { + if let Some(index) = self.chapters[c].text[byte..].find(&self.query) { + self.jump_byte(c, index + byte); + return true; + } + } + false + } + Direction::Prev => { + let byte = if args.skip { start } else { end }; + let head = (self.chapter, byte); + let tail = (0..self.chapter) + .rev() + .map(|c| (c, self.chapters[c].text.len())); + for (c, byte) in iter::once(head).chain(tail) { + if let Some(index) = self.chapters[c].text[..byte].rfind(&self.query) { + self.jump_byte(c, index); + return true; + } + } + false + } + } + } } #[derive(argh::FromArgs)] @@ -295,10 +326,10 @@ fn init() -> Result> { }); let args: Args = argh::from_env(); - let mut path = args.path; - if let Some(p) = path { - path = Some(fs::canonicalize(p)?.to_str().unwrap().to_string()); - } + let path = match args.path { + Some(p) => Some(fs::canonicalize(p)?.to_str().unwrap().to_string()), + None => None, + }; let (path, save, chapter, byte) = match (save, path) { (Err(e), None) => return Err(Box::new(e)), @@ -350,7 +381,7 @@ fn main() { exit(1); }); - let byte = bk.chap().lines[bk.line].0; + let byte = bk.chapters[bk.chapter].lines[bk.line].0; state .save .files diff --git a/src/view.rs b/src/view.rs index 4a5cb73..fa50532 100644 --- a/src/view.rs +++ b/src/view.rs @@ -5,10 +5,7 @@ use crossterm::{ }, style::Attribute, }; -use std::{ - cmp::{min, Ordering}, - iter, -}; +use std::cmp::{min, Ordering}; use unicode_width::UnicodeWidthChar; use crate::{Bk, Direction, SearchArgs}; @@ -199,7 +196,7 @@ impl Page { } } fn scroll_down(&self, bk: &mut Bk, n: usize) { - if bk.line + bk.rows < bk.chap().lines.len() { + if bk.line + bk.rows < bk.chapters[bk.chapter].lines.len() { bk.line += n; } else { self.next_chapter(bk); @@ -210,11 +207,11 @@ impl Page { bk.line = bk.line.saturating_sub(n); } else if bk.chapter > 0 { bk.chapter -= 1; - bk.line = bk.chap().lines.len().saturating_sub(bk.rows); + bk.line = bk.chapters[bk.chapter].lines.len().saturating_sub(bk.rows); } } fn click(&self, bk: &mut Bk, e: MouseEvent) { - let c = bk.chap(); + let c = &bk.chapters[bk.chapter]; let line = bk.line + e.row as usize; if e.column < bk.pad() || line >= c.lines.len() { @@ -251,9 +248,9 @@ impl Page { if let Ok(i) = r { let url = &c.links[i].2; - let &(chapter, byte) = bk.links.get(url).unwrap(); - let line = super::get_line(&bk.chapters[chapter].lines, byte); - bk.jump((chapter, line)); + let &(c, byte) = bk.links.get(url).unwrap(); + bk.mark('\''); + bk.jump_byte(c, byte); } } fn start_search(&self, bk: &mut Bk, dir: Direction) { @@ -287,28 +284,20 @@ impl View for Page { Char('?') => self.start_search(bk, Direction::Prev), Char('/') => self.start_search(bk, Direction::Next), Char('N') => { - Search::search( - &Search, - bk, - SearchArgs { - dir: Direction::Prev, - skip: true, - }, - ); + bk.search(SearchArgs { + dir: Direction::Prev, + skip: true, + }); } Char('n') => { - Search::search( - &Search, - bk, - SearchArgs { - dir: Direction::Next, - skip: true, - }, - ); + bk.search(SearchArgs { + dir: Direction::Next, + skip: true, + }); } End | Char('G') => { bk.mark('\''); - bk.line = bk.chap().lines.len().saturating_sub(bk.rows); + bk.line = bk.chapters[bk.chapter].lines.len().saturating_sub(bk.rows); } Home | Char('g') => { bk.mark('\''); @@ -329,14 +318,24 @@ impl View for Page { } fn on_resize(&self, bk: &mut Bk) { // lazy - bk.line = min(bk.line, bk.chap().lines.len() - 1); + bk.line = min(bk.line, bk.chapters[bk.chapter].lines.len() - 1); } fn render(&self, bk: &Bk) -> Vec { - let c = bk.chap(); + let c = &bk.chapters[bk.chapter]; let last_line = min(bk.line + bk.rows, c.lines.len()); let text_start = c.lines[bk.line].0; let text_end = c.lines[last_line - 1].1; + let mut search = Vec::new(); + if !bk.query.is_empty() { + let len = bk.query.len(); + for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) { + search.push((text_start + pos, Attribute::Reverse)); + search.push((text_start + pos + len, Attribute::NoReverse)); + } + } + let mut search = search.into_iter().peekable(); + let mut base = { let start = match c.attrs.binary_search_by_key(&text_start, |&x| x.0) { Ok(n) => n, @@ -358,16 +357,6 @@ impl View for Page { head.into_iter().chain(tail).peekable() }; - let mut search = Vec::new(); - if !bk.query.is_empty() { - let len = bk.query.len(); - for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) { - search.push((text_start + pos, Attribute::Reverse)); - search.push((text_start + pos + len, Attribute::NoReverse)); - } - } - let mut search = search.into_iter().peekable(); - let mut attrs = Vec::new(); loop { match (search.peek(), base.peek()) { @@ -410,41 +399,6 @@ impl View for Page { } pub struct Search; -impl Search { - fn search(&self, bk: &mut Bk, args: SearchArgs) -> bool { - let (start, end) = bk.chap().lines[bk.line]; - match args.dir { - Direction::Next => { - let byte = if args.skip { end } else { start }; - let head = (bk.chapter, byte); - let tail = (bk.chapter + 1..bk.chapters.len() - 1).map(|n| (n, 0)); - for (c, byte) in iter::once(head).chain(tail) { - if let Some(index) = bk.chapters[c].text[byte..].find(&bk.query) { - bk.line = super::get_line(&bk.chapters[c].lines, index + byte); - bk.chapter = c; - return true; - } - } - false - } - Direction::Prev => { - let byte = if args.skip { start } else { end }; - let head = (bk.chapter, byte); - let tail = (0..bk.chapter) - .rev() - .map(|c| (c, bk.chapters[c].text.len())); - for (c, byte) in iter::once(head).chain(tail) { - if let Some(index) = bk.chapters[c].text[..byte].rfind(&bk.query) { - bk.line = super::get_line(&bk.chapters[c].lines, index); - bk.chapter = c; - return true; - } - } - false - } - } - } -} impl View for Search { fn on_key(&self, bk: &mut Bk, kc: KeyCode) { match kc { @@ -459,13 +413,10 @@ impl View for Search { Backspace => { bk.query.pop(); bk.jump_reset(); - self.search( - bk, - SearchArgs { - dir: bk.dir.clone(), - skip: false, - }, - ); + bk.search(SearchArgs { + dir: bk.dir.clone(), + skip: false, + }); } Char(c) => { bk.query.push(c); @@ -473,7 +424,7 @@ impl View for Search { dir: bk.dir.clone(), skip: false, }; - if !self.search(bk, args) { + if !bk.search(args) { bk.jump_reset(); } } From c7c15e29581ff60d3ac528783cf689bf5b671869 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 1 May 2021 19:00:40 -0700 Subject: [PATCH 21/28] update --- Cargo.lock | 71 +++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcc37ad..955c2f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,10 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "adler32" -version = "1.2.0" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "argh" @@ -35,6 +35,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1" +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + [[package]] name = "base64" version = "0.13.0" @@ -66,12 +72,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -84,7 +84,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -114,11 +114,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.14" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" +checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", "crc32fast", "libc", "miniz_oxide", @@ -139,7 +139,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -150,15 +150,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.91" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" [[package]] name = "lock_api" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" dependencies = [ "scopeguard", ] @@ -169,16 +169,17 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "miniz_oxide" -version = "0.3.7" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ - "adler32", + "adler", + "autocfg", ] [[package]] @@ -229,7 +230,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", "redox_syscall", @@ -239,9 +240,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid", ] @@ -257,9 +258,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2" dependencies = [ "bitflags", ] @@ -277,9 +278,9 @@ dependencies = [ [[package]] name = "roxmltree" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf58a7d05b28e14b1e8902fa04c4d5d6109f5450ef71a5e6597f66e53f541504" +checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" dependencies = [ "xmlparser", ] @@ -338,9 +339,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.64" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" dependencies = [ "proc-macro2", "quote", @@ -381,9 +382,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "winapi" @@ -415,9 +416,9 @@ checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" [[package]] name = "zip" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6" +checksum = "9c83dc9b784d252127720168abd71ea82bf8c3d96b17dc565b5e2a02854f2b27" dependencies = [ "byteorder", "crc32fast", From 417c5d258c8a80790b848882e4b92dc2b5ae5f63 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 1 May 2021 22:31:59 -0700 Subject: [PATCH 22/28] themes --- README.md | 5 +++-- src/main.rs | 41 ++++++++++++++++++++++++++++++++++++++--- src/view.rs | 2 +- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5d94211..21648eb 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ or from github: read a book Options: + --bg background color (eg 282a36) + --fg foreground color (eg f8f8f2) -m, --meta print metadata and exit -t, --toc start with table of contents open -w, --width characters per line @@ -44,13 +46,12 @@ Check if your terminal supports italics: | - | - | - | | runtime deps | ❌ | python, curses | | wide characters | ✔️ | ❌ | -| inline styles | ✔️ | ❌ | | incremental search | ✔️ | ❌ | | multi line search | ✔️ | ❌ | | regex search | ❌ | ✔️ | | links | ✔️ | ❌ | | images | ❌ | ✔️ | -| themes | ❌ | ✔️ | +| themes | ✔️ | ✔️ | | choose file from history | ❌ | ✔️ | | additional formats | ❌ | FictionBook, Mobi, AZW3 | | external integration | see 1 | dictionary | diff --git a/src/main.rs b/src/main.rs index d3e978c..e23896c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use crossterm::{ cursor, event::{DisableMouseCapture, EnableMouseCapture, Event}, queue, - style::{self, Print}, + style::{self, Color::Rgb, Colors, Print, SetColors}, terminal, }; use serde::{Deserialize, Serialize}; @@ -96,6 +96,7 @@ pub struct Bk<'a> { mark: HashMap, links: HashMap, // layout + colors: Colors, cols: u16, rows: usize, max_width: u16, @@ -136,6 +137,7 @@ impl Bk<'_> { line: 0, mark: HashMap::new(), links: epub.links, + colors: args.colors, cols, rows: rows as usize, max_width: args.width, @@ -157,15 +159,16 @@ impl Bk<'_> { stdout, terminal::EnterAlternateScreen, cursor::Hide, - EnableMouseCapture + EnableMouseCapture, )?; terminal::enable_raw_mode()?; let mut render = |bk: &Bk| { queue!( stdout, + Print(style::Attribute::Reset), + SetColors(bk.colors), terminal::Clear(terminal::ClearType::All), - Print(style::Attribute::Reset) ) .unwrap(); for (i, line) in bk.view.render(bk).iter().enumerate() { @@ -278,6 +281,14 @@ struct Args { #[argh(positional)] path: Option, + /// background color (eg 282a36) + #[argh(option)] + bg: Option, + + /// foreground color (eg f8f8f2) + #[argh(option)] + fg: Option, + /// print metadata and exit #[argh(switch, short = 'm')] meta: bool, @@ -292,6 +303,7 @@ struct Args { } struct Props { + colors: Colors, chapter: usize, byte: usize, width: u16, @@ -348,12 +360,35 @@ fn init() -> Result> { } }; + // XXX oh god what + let fg = args + .fg + .and_then(|s| { + Some(Rgb { + r: u8::from_str_radix(&s[0..2], 16).unwrap(), + g: u8::from_str_radix(&s[2..4], 16).unwrap(), + b: u8::from_str_radix(&s[4..6], 16).unwrap(), + }) + }) + .unwrap_or(style::Color::Reset); + let bg = args + .bg + .and_then(|s| { + Some(Rgb { + r: u8::from_str_radix(&s[0..2], 16).unwrap(), + g: u8::from_str_radix(&s[2..4], 16).unwrap(), + b: u8::from_str_radix(&s[4..6], 16).unwrap(), + }) + }) + .unwrap_or(style::Color::Reset); + Ok(State { path, save, save_path, meta: args.meta, bk: Props { + colors: Colors::new(fg, bg), chapter, byte, width: args.width, diff --git a/src/view.rs b/src/view.rs index fa50532..5e48772 100644 --- a/src/view.rs +++ b/src/view.rs @@ -175,7 +175,7 @@ impl View for Toc { "{}{}{}", Attribute::Reverse, arr[bk.cursor], - Attribute::Reset + Attribute::NoReverse ); arr } From c24f48a85aedb79261d3ec16678b17963cc0fe7d Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 19 Jun 2021 12:53:45 -0700 Subject: [PATCH 23/28] clippy --- src/main.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index e23896c..4ed14b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -363,22 +363,18 @@ fn init() -> Result> { // XXX oh god what let fg = args .fg - .and_then(|s| { - Some(Rgb { - r: u8::from_str_radix(&s[0..2], 16).unwrap(), - g: u8::from_str_radix(&s[2..4], 16).unwrap(), - b: u8::from_str_radix(&s[4..6], 16).unwrap(), - }) + .map(|s| Rgb { + r: u8::from_str_radix(&s[0..2], 16).unwrap(), + g: u8::from_str_radix(&s[2..4], 16).unwrap(), + b: u8::from_str_radix(&s[4..6], 16).unwrap(), }) .unwrap_or(style::Color::Reset); let bg = args .bg - .and_then(|s| { - Some(Rgb { - r: u8::from_str_radix(&s[0..2], 16).unwrap(), - g: u8::from_str_radix(&s[2..4], 16).unwrap(), - b: u8::from_str_radix(&s[4..6], 16).unwrap(), - }) + .map(|s| Rgb { + r: u8::from_str_radix(&s[0..2], 16).unwrap(), + g: u8::from_str_radix(&s[2..4], 16).unwrap(), + b: u8::from_str_radix(&s[4..6], 16).unwrap(), }) .unwrap_or(style::Color::Reset); From 8f362702675e56cfcf38c78e78516dd64f91f3c8 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 31 Jul 2021 04:03:51 -0700 Subject: [PATCH 24/28] cargo update --- Cargo.lock | 102 ++++++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 955c2f0..6f5da7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler" version = "1.0.2" @@ -8,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "argh" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91792f088f87cdc7a2cfb1d617fa5ea18d7f1dc22ef0e1b5f82f3157cdc522be" +checksum = "2e7317a549bc17c5278d9e72bb6e62c6aa801ac2567048e39ebc1c194249323e" dependencies = [ "argh_derive", "argh_shared", @@ -18,9 +20,9 @@ dependencies = [ [[package]] name = "argh_derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4eb0c0c120ad477412dc95a4ce31e38f2113e46bd13511253f79196ca68b067" +checksum = "60949c42375351e9442e354434b0cba2ac402c1237edf673cac3a4bf983b8d3c" dependencies = [ "argh_shared", "heck", @@ -31,9 +33,9 @@ dependencies = [ [[package]] name = "argh_shared" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1" +checksum = "8a61eb019cb8f415d162cb9f12130ee6bbe9168b7d953c17f4ad049e4051ca00" [[package]] name = "autocfg" @@ -89,25 +91,25 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c" +checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d" dependencies = [ "bitflags", "crossterm_winapi", - "lazy_static", "libc", "mio", "parking_lot", "signal-hook", + "signal-hook-mio", "winapi", ] [[package]] name = "crossterm_winapi" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da8964ace4d3e4a044fd027919b2237000b24315a37c916f61809f1ff2140b9" +checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507" dependencies = [ "winapi", ] @@ -126,33 +128,27 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "instant" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ "cfg-if", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.94" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "lock_api" @@ -184,9 +180,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" dependencies = [ "libc", "log", @@ -240,9 +236,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] @@ -258,9 +254,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] @@ -293,18 +289,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" dependencies = [ "proc-macro2", "quote", @@ -313,20 +309,30 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.17" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729" +checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" dependencies = [ "libc", - "mio", "signal-hook-registry", ] +[[package]] +name = "signal-hook-mio" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] @@ -339,9 +345,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.71" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" dependencies = [ "proc-macro2", "quote", @@ -350,18 +356,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", @@ -370,9 +376,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" @@ -416,9 +422,9 @@ checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" [[package]] name = "zip" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c83dc9b784d252127720168abd71ea82bf8c3d96b17dc565b5e2a02854f2b27" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" dependencies = [ "byteorder", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index 9e00bbd..1ab9a3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/aeosynth/bk" [dependencies] argh = "^0.1" -crossterm = "^0.19" +crossterm = "^0.20" ron = "^0.6" roxmltree = "^0.14" serde = "^1.0" From 95c4c859e920e075616fc49d877f6d70cd56d70f Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 31 Jul 2021 04:15:54 -0700 Subject: [PATCH 25/28] internal --- src/main.rs | 8 ++++---- src/view.rs | 22 ++++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4ed14b2..57aa177 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use crossterm::{ cursor, - event::{DisableMouseCapture, EnableMouseCapture, Event}, + event::{self, DisableMouseCapture, EnableMouseCapture, Event}, queue, style::{self, Color::Rgb, Colors, Print, SetColors}, terminal, @@ -153,7 +153,7 @@ impl Bk<'_> { bk } - fn run(&mut self) -> crossterm::Result<()> { + fn run(&mut self) -> io::Result<()> { let mut stdout = io::stdout(); queue!( stdout, @@ -180,11 +180,11 @@ impl Bk<'_> { render(self); loop { - match crossterm::event::read()? { + match event::read()? { Event::Key(e) => self.view.on_key(self, e.code), Event::Mouse(e) => { // XXX idk seems lame - if e.kind == crossterm::event::MouseEventKind::Moved { + if e.kind == event::MouseEventKind::Moved { continue; } self.view.on_mouse(self, e); diff --git a/src/view.rs b/src/view.rs index 5e48772..8194132 100644 --- a/src/view.rs +++ b/src/view.rs @@ -3,7 +3,7 @@ use crossterm::{ KeyCode::{self, *}, MouseEvent, MouseEventKind, }, - style::Attribute, + style::Attribute::*, }; use std::cmp::{min, Ordering}; use unicode_width::UnicodeWidthChar; @@ -142,7 +142,7 @@ impl View for Toc { } fn on_key(&self, bk: &mut Bk, kc: KeyCode) { match kc { - Esc | Tab | Left | Char('h') | Char('q') => { + Esc | Tab | Left | Char('h' | 'q') => { bk.jump_reset(); bk.cursor = 0; bk.view = &Page; @@ -171,12 +171,7 @@ impl View for Toc { .iter() .map(|c| c.title.clone()) .collect::>(); - arr[bk.cursor] = format!( - "{}{}{}", - Attribute::Reverse, - arr[bk.cursor], - Attribute::NoReverse - ); + arr[bk.cursor] = format!("{}{}{}", Reverse, arr[bk.cursor], NoReverse); arr } } @@ -306,11 +301,11 @@ impl View for Page { Char('d') => self.scroll_down(bk, bk.rows / 2), Char('u') => self.scroll_up(bk, bk.rows / 2), Up | Char('k') => self.scroll_up(bk, 3), - Left | PageUp | Char('b') | Char('h') => { + Left | PageUp | Char('b' | 'h') => { self.scroll_up(bk, bk.rows); } Down | Char('j') => self.scroll_down(bk, 3), - Right | PageDown | Char('f') | Char('l') | Char(' ') => self.scroll_down(bk, bk.rows), + Right | PageDown | Char('f' | 'l' | ' ') => self.scroll_down(bk, bk.rows), Char('[') => self.prev_chapter(bk), Char(']') => self.next_chapter(bk), _ => (), @@ -330,8 +325,8 @@ impl View for Page { if !bk.query.is_empty() { let len = bk.query.len(); for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) { - search.push((text_start + pos, Attribute::Reverse)); - search.push((text_start + pos + len, Attribute::NoReverse)); + search.push((text_start + pos, Reverse)); + search.push((text_start + pos + len, NoReverse)); } } let mut search = search.into_iter().peekable(); @@ -344,8 +339,7 @@ impl View for Page { let map = c.attrs[start].2; let mut head = Vec::new(); - let list = [Attribute::Bold, Attribute::Italic, Attribute::Underlined]; - for attr in std::array::IntoIter::new(list) { + for attr in [Bold, Italic, Underlined] { if map.has(attr) { head.push((text_start, attr)); } From 4d1af5f00d0aa5bf41b9a24a818f2aab1a4db26c Mon Sep 17 00:00:00 2001 From: James Campos Date: Wed, 27 Oct 2021 22:36:08 -0700 Subject: [PATCH 26/28] update, rust 2021 --- Cargo.lock | 100 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 6 ++-- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f5da7f..42d2523 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "argh" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7317a549bc17c5278d9e72bb6e62c6aa801ac2567048e39ebc1c194249323e" +checksum = "f023c76cd7975f9969f8e29f0e461decbdc7f51048ce43427107a3d192f1c9bf" dependencies = [ "argh_derive", "argh_shared", @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "argh_derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60949c42375351e9442e354434b0cba2ac402c1237edf673cac3a4bf983b8d3c" +checksum = "48ad219abc0c06ca788aface2e3a1970587e3413ab70acd20e54b6ec524c1f8f" dependencies = [ "argh_shared", "heck", @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "argh_shared" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a61eb019cb8f415d162cb9f12130ee6bbe9168b7d953c17f4ad049e4051ca00" +checksum = "38de00daab4eac7d753e97697066238d67ce9d7e2d823ab4f72fe14af29f3f33" [[package]] name = "autocfg" @@ -51,9 +51,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bk" @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.20.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d" +checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c" dependencies = [ "bitflags", "crossterm_winapi", @@ -107,18 +107,18 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" dependencies = [ "winapi", ] [[package]] name = "flate2" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ "cfg-if", "crc32fast", @@ -137,24 +137,24 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] [[package]] name = "libc" -version = "0.2.98" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -211,9 +211,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if", "instant", @@ -236,36 +236,36 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] [[package]] name = "ron" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064ea8613fb712a19faf920022ec8ddf134984f100090764a4e1d768f3827f1f" +checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678" dependencies = [ "base64", "bitflags", @@ -289,18 +289,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" +checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1" dependencies = [ "libc", "signal-hook-registry", @@ -339,15 +339,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "syn" -version = "1.0.74" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" dependencies = [ "proc-macro2", "quote", @@ -356,18 +356,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -382,9 +382,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" diff --git a/Cargo.toml b/Cargo.toml index 1ab9a3e..98bdd45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bk" version = "0.5.3" authors = ["James Campos "] -edition = "2018" +edition = "2021" license = "MIT" description = "Terminal Epub reader" keywords = ["ebook", "epub"] @@ -12,8 +12,8 @@ repository = "https://github.com/aeosynth/bk" [dependencies] argh = "^0.1" -crossterm = "^0.20" -ron = "^0.6" +crossterm = "^0.22" +ron = "^0.7" roxmltree = "^0.14" serde = "^1.0" unicode-width = "^0.1" From 61beded518e759884d72732a068744935c11ea6f Mon Sep 17 00:00:00 2001 From: James Campos Date: Wed, 27 Oct 2021 23:59:59 -0700 Subject: [PATCH 27/28] pre tags Co-authored-by: jonseitz --- src/epub.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/epub.rs b/src/epub.rs index a52c9d0..f70964c 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -225,6 +225,15 @@ fn render(n: Node, c: &mut Chapter) { c.render_text(n); c.text.push('\n'); } + "pre" => { + c.text.push_str("\n "); + n + .descendants() + .filter(Node::is_text) + .map(|n| n.text().unwrap().replace('\n', "\n ")) + .for_each(|s| c.text.push_str(&s)); + c.text.push('\n'); + } _ => c.render_text(n), } } From 8d527788821faee1a2f961d576997351cd68767d Mon Sep 17 00:00:00 2001 From: James Campos Date: Thu, 2 Nov 2023 22:12:30 -0700 Subject: [PATCH 28/28] 0.6.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42d2523..58df1b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,7 +57,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bk" -version = "0.5.3" +version = "0.6.0" dependencies = [ "argh", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index 98bdd45..fdc63ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bk" -version = "0.5.3" +version = "0.6.0" authors = ["James Campos "] edition = "2021" license = "MIT"