From dacfd249ae587b39a1b72b6994dbc5df0d99957f Mon Sep 17 00:00:00 2001 From: c Date: Tue, 10 Dec 2024 11:04:00 +0100 Subject: [PATCH 01/15] clippy --- examples/html2term.rs | 20 ++++++++------------ src/ansi_colours.rs | 1 + src/css.rs | 10 ++++------ src/css/parser.rs | 12 +++++------- src/lib.rs | 37 +++++++++++++++++++------------------ src/markup5ever_rcdom.rs | 2 +- 6 files changed, 38 insertions(+), 44 deletions(-) diff --git a/examples/html2term.rs b/examples/html2term.rs index a1c2937..141479f 100644 --- a/examples/html2term.rs +++ b/examples/html2term.rs @@ -269,21 +269,17 @@ mod top { Key::Char('k') | Key::Up => { if inspect_path.is_empty() { doc_y = doc_y.saturating_sub(1); - } else { - if *inspect_path.last().unwrap() > 1 { - *inspect_path.last_mut().unwrap() -= 1; - annotated = rerender(&dom, &inspect_path, width, &options); - } + } else if *inspect_path.last().unwrap() > 1 { + *inspect_path.last_mut().unwrap() -= 1; + annotated = rerender(&dom, &inspect_path, width, &options); } } Key::Char('h') | Key::Left => { if inspect_path.is_empty() { doc_x = doc_x.saturating_sub(1); - } else { - if inspect_path.len() > 1 { - inspect_path.pop(); - annotated = rerender(&dom, &inspect_path, width, &options); - } + } else if inspect_path.len() > 1 { + inspect_path.pop(); + annotated = rerender(&dom, &inspect_path, width, &options); } } Key::Char('l') | Key::Right => { @@ -378,7 +374,7 @@ mod top { }; if inspect_path.is_empty() { let render_tree = config - .dom_to_render_tree(&dom) + .dom_to_render_tree(dom) .expect("Failed to build render tree"); config .render_to_lines(render_tree, width) @@ -405,7 +401,7 @@ mod top { ) .expect("Invalid CSS"); let render_tree = config - .dom_to_render_tree(&dom) + .dom_to_render_tree(dom) .expect("Failed to build render tree"); config .render_to_lines(render_tree, width) diff --git a/src/ansi_colours.rs b/src/ansi_colours.rs index 9dd54a1..edf8da4 100644 --- a/src/ansi_colours.rs +++ b/src/ansi_colours.rs @@ -8,6 +8,7 @@ use crate::{parse, RichAnnotation, RichDecorator}; use std::io; /// Reads HTML from `input`, and returns text wrapped to `width` columns. +/// /// The text is returned as a `Vec>`; the annotations are vectors /// of `RichAnnotation`. The "outer" annotation comes first in the `Vec`. /// diff --git a/src/css.rs b/src/css.rs index f3207e9..219ed73 100644 --- a/src/css.rs +++ b/src/css.rs @@ -132,10 +132,8 @@ impl Selector { if Rc::ptr_eq(child, node) { break; } - } else { - if Rc::ptr_eq(child, node) { - return false; - } + } else if Rc::ptr_eq(child, node) { + return false; } } } @@ -148,14 +146,14 @@ impl Selector { */ let idx_offset = idx - b; if *a == 0 { - return idx_offset == 0 && Self::do_matches(&comps[1..], &node); + return idx_offset == 0 && Self::do_matches(&comps[1..], node); } if (idx_offset % a) != 0 { // Not a multiple return false; } let n = idx_offset / a; - n >= 0 && Self::do_matches(&comps[1..], &node) + n >= 0 && Self::do_matches(&comps[1..], node) } }, } diff --git a/src/css/parser.rs b/src/css/parser.rs index 0d64f0c..83886dd 100644 --- a/src/css/parser.rs +++ b/src/css/parser.rs @@ -397,13 +397,11 @@ fn parse_faulty_color( text: &str, ) -> Result>> { let text = text.trim(); - if text.chars().all(|c| c.is_hex_digit()) { - if text.len() == 6 { - let r = u8::from_str_radix(&text[0..2], 16).unwrap(); - let g = u8::from_str_radix(&text[2..4], 16).unwrap(); - let b = u8::from_str_radix(&text[4..6], 16).unwrap(); - return Ok(Colour::Rgb(r, g, b)); - } + if text.chars().all(|c| c.is_hex_digit()) && text.len() == 6 { + let r = u8::from_str_radix(&text[0..2], 16).unwrap(); + let g = u8::from_str_radix(&text[2..4], 16).unwrap(); + let b = u8::from_str_radix(&text[4..6], 16).unwrap(); + return Ok(Colour::Rgb(r, g, b)); } Err(e) } diff --git a/src/lib.rs b/src/lib.rs index 41bea8a..b546477 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -846,7 +846,7 @@ impl RenderNode { if style.internal_pre { write!(f, " internal_pre")?; } - writeln!(f, "") + writeln!(f) } fn write_self( &self, @@ -858,52 +858,52 @@ impl RenderNode { match &self.info { RenderNodeInfo::Text(s) => writeln!(f, "{:indent$}{s:?}", "")?, RenderNodeInfo::Container(v) => { - self.write_container("Container", &v, f, indent)?; + self.write_container("Container", v, f, indent)?; } RenderNodeInfo::Link(targ, v) => { - self.write_container(&format!("Link({})", targ), &v, f, indent)?; + self.write_container(&format!("Link({})", targ), v, f, indent)?; } RenderNodeInfo::Em(v) => { - self.write_container("Em", &v, f, indent)?; + self.write_container("Em", v, f, indent)?; } RenderNodeInfo::Strong(v) => { - self.write_container("Strong", &v, f, indent)?; + self.write_container("Strong", v, f, indent)?; } RenderNodeInfo::Strikeout(v) => { - self.write_container("Strikeout", &v, f, indent)?; + self.write_container("Strikeout", v, f, indent)?; } RenderNodeInfo::Code(v) => { - self.write_container("Code", &v, f, indent)?; + self.write_container("Code", v, f, indent)?; } RenderNodeInfo::Img(src, title) => { writeln!(f, "{:indent$}Img src={:?} title={:?}:", "", src, title)?; } RenderNodeInfo::Block(v) => { - self.write_container("Block", &v, f, indent)?; + self.write_container("Block", v, f, indent)?; } RenderNodeInfo::Header(depth, v) => { - self.write_container(&format!("Header({})", depth), &v, f, indent)?; + self.write_container(&format!("Header({})", depth), v, f, indent)?; } RenderNodeInfo::Div(v) => { - self.write_container("Div", &v, f, indent)?; + self.write_container("Div", v, f, indent)?; } RenderNodeInfo::BlockQuote(v) => { - self.write_container("BlockQuote", &v, f, indent)?; + self.write_container("BlockQuote", v, f, indent)?; } RenderNodeInfo::Ul(v) => { - self.write_container("Ul", &v, f, indent)?; + self.write_container("Ul", v, f, indent)?; } RenderNodeInfo::Ol(start, v) => { - self.write_container(&format!("Ol({})", start), &v, f, indent)?; + self.write_container(&format!("Ol({})", start), v, f, indent)?; } RenderNodeInfo::Dl(v) => { - self.write_container("Dl", &v, f, indent)?; + self.write_container("Dl", v, f, indent)?; } RenderNodeInfo::Dt(v) => { - self.write_container("Dt", &v, f, indent)?; + self.write_container("Dt", v, f, indent)?; } RenderNodeInfo::Dd(v) => { - self.write_container("Dd", &v, f, indent)?; + self.write_container("Dd", v, f, indent)?; } RenderNodeInfo::Break => { writeln!(f, "{:indent$}Break", "", indent = indent)?; @@ -942,10 +942,10 @@ impl RenderNode { writeln!(f, "{:indent$}FragStart({}):", "", frag)?; } RenderNodeInfo::ListItem(v) => { - self.write_container("ListItem", &v, f, indent)?; + self.write_container("ListItem", v, f, indent)?; } RenderNodeInfo::Sup(v) => { - self.write_container("Sup", &v, f, indent)?; + self.write_container("Sup", v, f, indent)?; } } Ok(()) @@ -2764,6 +2764,7 @@ where } /// Reads HTML from `input`, and returns text wrapped to `width` columns. +/// /// The text is returned as a `Vec>`; the annotations are vectors /// of `RichAnnotation`. The "outer" annotation comes first in the `Vec`. pub fn from_read_rich(input: R, width: usize) -> Result>>> diff --git a/src/markup5ever_rcdom.rs b/src/markup5ever_rcdom.rs index dfdccd9..ef3ea24 100644 --- a/src/markup5ever_rcdom.rs +++ b/src/markup5ever_rcdom.rs @@ -151,7 +151,7 @@ impl Node { /// Return the element type (if an element) pub fn element_name(&self) -> Option { if let NodeData::Element { ref name, .. } = self.data { - Some(format!("{}", &*name.local_name())) + Some(format!("{}", name.local_name())) } else { None } From 52055fb1baefbe3c74431edfa6e064748e10084c Mon Sep 17 00:00:00 2001 From: c Date: Tue, 10 Dec 2024 11:47:07 +0100 Subject: [PATCH 02/15] Express fn parse_with_context() with the help of fn parse_html() --- src/lib.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b546477..0cb51a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,7 +71,6 @@ use render::{Renderer, RichDecorator, TextDecorator}; use html5ever::driver::ParseOpts; use html5ever::parse_document; -use html5ever::tendril::TendrilSink; use html5ever::tree_builder::TreeBuilderOpts; mod markup5ever_rcdom; pub use markup5ever_rcdom::RcDom; @@ -2722,17 +2721,8 @@ impl RenderedText { } } -fn parse_with_context(mut input: impl io::Read, context: &mut HtmlContext) -> Result { - let opts = ParseOpts { - tree_builder: TreeBuilderOpts { - drop_doctype: true, - ..Default::default() - }, - ..Default::default() - }; - let dom = parse_document(RcDom::default(), opts) - .from_utf8() - .read_from(&mut input)?; +fn parse_with_context(input: impl io::Read, context: &mut HtmlContext) -> Result { + let dom = config::plain().parse_html(input)?; let render_tree = dom_to_render_tree_with_context(dom.document.clone(), &mut io::sink(), context)? .ok_or(Error::Fail)?; From b29ec277560da1984dbde3610eb9ce058acaf28c Mon Sep 17 00:00:00 2001 From: c Date: Tue, 10 Dec 2024 11:48:38 +0100 Subject: [PATCH 03/15] Express configs with default constructor fn with_decorator --- src/lib.rs | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0cb51a7..71a56c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2601,38 +2601,12 @@ pub mod config { /// Return a Config initialized with a `RichDecorator`. pub fn rich() -> Config { - Config { - decorator: RichDecorator::new(), - #[cfg(feature = "css")] - style: Default::default(), - #[cfg(feature = "css")] - use_doc_css: false, - max_wrap_width: None, - pad_block_width: false, - allow_width_overflow: false, - min_wrap_width: MIN_WIDTH, - raw: false, - draw_borders: true, - wrap_links: true, - } + with_decorator(RichDecorator::new()) } /// Return a Config initialized with a `PlainDecorator`. pub fn plain() -> Config { - Config { - decorator: PlainDecorator::new(), - #[cfg(feature = "css")] - style: Default::default(), - #[cfg(feature = "css")] - use_doc_css: false, - max_wrap_width: None, - pad_block_width: false, - allow_width_overflow: false, - min_wrap_width: MIN_WIDTH, - raw: false, - draw_borders: true, - wrap_links: true, - } + with_decorator(PlainDecorator::new()) } /// Return a Config initialized with a custom decorator. From cfdadd9265b84e3d6d4b0be6b384c20e3e316b41 Mon Sep 17 00:00:00 2001 From: c Date: Tue, 10 Dec 2024 12:58:53 +0100 Subject: [PATCH 04/15] Derive PartialEq, Eq impls --- src/css.rs | 14 +++++++------- src/lib.rs | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/css.rs b/src/css.rs index 219ed73..68256e9 100644 --- a/src/css.rs +++ b/src/css.rs @@ -16,7 +16,7 @@ use crate::{ use self::parser::Importance; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum SelectorComponent { Class(String), Element(String), @@ -46,7 +46,7 @@ impl std::fmt::Display for SelectorComponent { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct Selector { // List of components, right first so we match from the leaf. components: Vec, @@ -189,7 +189,7 @@ impl Selector { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum Display { /// display: none None, @@ -198,7 +198,7 @@ pub(crate) enum Display { ExtRawDom, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum Style { Colour(Colour), BgColour(Colour), @@ -206,7 +206,7 @@ pub(crate) enum Style { WhiteSpace(WhiteSpace), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct StyleDecl { style: Style, importance: Importance, @@ -230,7 +230,7 @@ impl std::fmt::Display for StyleDecl { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] struct Ruleset { selector: Selector, styles: Vec, @@ -248,7 +248,7 @@ impl std::fmt::Display for Ruleset { } /// Stylesheet data which can be used while building the render tree. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Default, Debug, PartialEq, Eq)] pub(crate) struct StyleData { agent_rules: Vec, user_rules: Vec, diff --git a/src/lib.rs b/src/lib.rs index 71a56c7..05502a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ use std::io; use std::io::Write; use std::iter::{once, repeat}; -#[derive(Debug, Copy, Clone, Default, PartialEq)] +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] pub(crate) enum WhiteSpace { #[default] Normal, @@ -1306,7 +1306,7 @@ where } } -#[derive(Default, Debug)] +#[derive(Default, Debug, PartialEq, Eq)] struct HtmlContext { #[cfg(feature = "css")] style_data: css::StyleData, From 0019a6a97711e13ca6c59f5035cb970fe720336c Mon Sep 17 00:00:00 2001 From: c Date: Tue, 10 Dec 2024 13:56:26 +0100 Subject: [PATCH 05/15] Express fn from_read_coloured() with fn coloured() --- src/ansi_colours.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/ansi_colours.rs b/src/ansi_colours.rs index edf8da4..5c9a19e 100644 --- a/src/ansi_colours.rs +++ b/src/ansi_colours.rs @@ -4,7 +4,7 @@ //! can be achieved using inline characters sent to the terminal such as //! underlining in some terminals). -use crate::{parse, RichAnnotation, RichDecorator}; +use crate::RichAnnotation; use std::io; /// Reads HTML from `input`, and returns text wrapped to `width` columns. @@ -25,16 +25,5 @@ where R: io::Read, FMap: Fn(&[RichAnnotation], &str) -> String, { - let lines = parse(input)? - .render(width, RichDecorator::new())? - .into_lines()?; - - let mut result = String::new(); - for line in lines { - for ts in line.tagged_strings() { - result.push_str(&colour_map(&ts.tag, &ts.s)); - } - result.push('\n'); - } - Ok(result) + super::config::rich().coloured(input, width, colour_map) } From 8285e5f4a5e4effb82d31952283bcfc92c41c7ca Mon Sep 17 00:00:00 2001 From: c Date: Mon, 16 Dec 2024 12:23:00 +0100 Subject: [PATCH 06/15] Less indexing, less unwraps --- src/css/parser.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/css/parser.rs b/src/css/parser.rs index 83886dd..5e33bfa 100644 --- a/src/css/parser.rs +++ b/src/css/parser.rs @@ -390,6 +390,10 @@ pub(crate) fn parse_color_attribute( parse_color(&value.tokens).or_else(|e| parse_faulty_color(e, text)) } +fn parse_color_part(text: &str, index: std::ops::Range) -> Option { + u8::from_str_radix(text.get(index)?, 16).ok() +} + // Both Firefox and Chromium accept "00aabb" as a bgcolor - I'm not sure this has ever been legal, // but regrettably I've had e-mails which were unreadable without doing this. fn parse_faulty_color( @@ -397,10 +401,10 @@ fn parse_faulty_color( text: &str, ) -> Result>> { let text = text.trim(); - if text.chars().all(|c| c.is_hex_digit()) && text.len() == 6 { - let r = u8::from_str_radix(&text[0..2], 16).unwrap(); - let g = u8::from_str_radix(&text[2..4], 16).unwrap(); - let b = u8::from_str_radix(&text[4..6], 16).unwrap(); + let r = parse_color_part(text, 0..2); + let g = parse_color_part(text, 2..4); + let b = parse_color_part(text, 4..6); + if let (Some(r), Some(g), Some(b)) = (r, g, b) { return Ok(Colour::Rgb(r, g, b)); } Err(e) @@ -618,7 +622,7 @@ fn parse_string_token(text: &str) -> IResult<&str, Token> { loop { match chars.next() { - None => return Ok((&text[text.len()..], Token::String(s.into()))), + None => return Ok(("", Token::String(s.into()))), Some((i, c)) if c == end_char => { return Ok((&text[i + 1..], Token::String(s.into()))); } From 0e176c63eb2a187025cc890cf2e3c2bac84b43b2 Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 16:00:26 +0100 Subject: [PATCH 07/15] Do not need &mut inside fn do_parse() --- src/lib.rs | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 05502a7..3ce10a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,7 +67,7 @@ pub mod render; use render::text_renderer::{ RenderLine, RenderOptions, RichAnnotation, SubRenderer, TaggedLine, TextRenderer, }; -use render::{Renderer, RichDecorator, TextDecorator}; +use render::{Renderer, TextDecorator}; use html5ever::driver::ParseOpts; use html5ever::parse_document; @@ -2371,11 +2371,7 @@ pub mod config { } } /// Parse with context. - fn do_parse( - &mut self, - context: &mut HtmlContext, - input: R, - ) -> Result { + fn do_parse(&self, context: &mut HtmlContext, input: R) -> Result { super::parse_with_context(input, context) } @@ -2438,11 +2434,7 @@ pub mod config { /// Reads HTML from `input`, and returns a `String` with text wrapped to /// `width` columns. - pub fn string_from_read( - mut self, - input: R, - width: usize, - ) -> Result { + pub fn string_from_read(self, input: R, width: usize) -> Result { let mut context = self.make_context(); let s = self .do_parse(&mut context, input)? @@ -2456,7 +2448,7 @@ pub mod config { /// of the provided text decorator's `Annotation`. The "outer" annotation comes first in /// the `Vec`. pub fn lines_from_read( - mut self, + self, input: R, width: usize, ) -> Result>>> { @@ -2548,12 +2540,7 @@ pub mod config { /// a list of `RichAnnotation` and some text, and returns the text /// with any terminal escapes desired to indicate those annotations /// (such as colour). - pub fn coloured( - mut self, - input: R, - width: usize, - colour_map: FMap, - ) -> Result + pub fn coloured(self, input: R, width: usize, colour_map: FMap) -> Result where R: std::io::Read, FMap: Fn(&[RichAnnotation], &str) -> String, From f1ab39b538a716c3d8f60eea8d8a41b2a53a389f Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 16:20:01 +0100 Subject: [PATCH 08/15] Express fn coloured() with fn render_coloured() --- src/lib.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3ce10a0..ffe7d3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2546,19 +2546,8 @@ pub mod config { FMap: Fn(&[RichAnnotation], &str) -> String, { let mut context = self.make_context(); - let lines = self - .do_parse(&mut context, input)? - .render_with_context(&mut context, width, self.decorator)? - .into_lines()?; - - let mut result = String::new(); - for line in lines { - for ts in line.tagged_strings() { - result.push_str(&colour_map(&ts.tag, &ts.s)); - } - result.push('\n'); - } - Ok(result) + let render_tree = self.do_parse(&mut context, input)?; + self.render_coloured(render_tree, width, colour_map) } /// Return coloured text from a RenderTree. `colour_map` is a function which takes a list From 8e80accc569341d41528b17c2e01a1078130aa1a Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 16:25:39 +0100 Subject: [PATCH 09/15] Express HtmlContext::default() as config::plain().make_context() Note that it does not hold that HtmlContext::default() == config::plain().make_context() but the relevant fields used by fn parse_with_context() are the same. This is a bit unclear, this change makes this more obvious. --- src/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ffe7d3c..268079f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1306,7 +1306,7 @@ where } } -#[derive(Default, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] struct HtmlContext { #[cfg(feature = "css")] style_data: css::StyleData, @@ -2354,7 +2354,7 @@ pub mod config { impl Config { /// Make the HtmlContext from self. - fn make_context(&self) -> HtmlContext { + pub(crate) fn make_context(&self) -> HtmlContext { HtmlContext { #[cfg(feature = "css")] style_data: self.style.clone(), @@ -2646,7 +2646,8 @@ impl RenderTree { /// Render this document using the given `decorator` and wrap it to `width` columns. fn render(self, width: usize, decorator: D) -> Result> { - self.render_with_context(&mut Default::default(), width, decorator) + let mut context = config::plain().make_context(); + self.render_with_context(&mut context, width, decorator) } } @@ -2681,7 +2682,8 @@ fn parse_with_context(input: impl io::Read, context: &mut HtmlContext) -> Result /// Reads and parses HTML from `input` and prepares a render tree. pub fn parse(input: impl io::Read) -> Result { - parse_with_context(input, &mut Default::default()) + let mut context = config::plain().make_context(); + parse_with_context(input, &mut context) } /// Reads HTML from `input`, decorates it using `decorator`, and From f4e09f0f16ca7cf99096fc4bfe2fff993776a64f Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 16:32:19 +0100 Subject: [PATCH 10/15] Express fn parse() with fn do_parse() --- src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 268079f..f1b9483 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2371,7 +2371,10 @@ pub mod config { } } /// Parse with context. - fn do_parse(&self, context: &mut HtmlContext, input: R) -> Result { + pub(crate) fn do_parse(&self, context: &mut HtmlContext, input: R) -> Result + where + R: io::Read, + { super::parse_with_context(input, context) } @@ -2682,8 +2685,8 @@ fn parse_with_context(input: impl io::Read, context: &mut HtmlContext) -> Result /// Reads and parses HTML from `input` and prepares a render tree. pub fn parse(input: impl io::Read) -> Result { - let mut context = config::plain().make_context(); - parse_with_context(input, &mut context) + let cfg = config::plain(); + cfg.do_parse(&mut cfg.make_context(), input) } /// Reads HTML from `input`, decorates it using `decorator`, and From 1ccc463a3367c05aabd02bb29a41fba1e5e46449 Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 16:39:14 +0100 Subject: [PATCH 11/15] Inline fn parse_with_context() into callsites --- src/lib.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f1b9483..5929f60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2375,7 +2375,14 @@ pub mod config { where R: io::Read, { - super::parse_with_context(input, context) + let dom = plain().parse_html(input)?; + let render_tree = super::dom_to_render_tree_with_context( + dom.document.clone(), + &mut io::sink(), + context, + )? + .ok_or(Error::Fail)?; + Ok(RenderTree(render_tree)) } /// Parse the HTML into a DOM structure. @@ -2675,14 +2682,6 @@ impl RenderedText { } } -fn parse_with_context(input: impl io::Read, context: &mut HtmlContext) -> Result { - let dom = config::plain().parse_html(input)?; - let render_tree = - dom_to_render_tree_with_context(dom.document.clone(), &mut io::sink(), context)? - .ok_or(Error::Fail)?; - Ok(RenderTree(render_tree)) -} - /// Reads and parses HTML from `input` and prepares a render tree. pub fn parse(input: impl io::Read) -> Result { let cfg = config::plain(); From 0636efa9dbe634566f7866a286fbec34a81321ea Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 16:52:32 +0100 Subject: [PATCH 12/15] Inline fn render() into test callsites --- src/lib.rs | 6 ------ src/tests.rs | 7 ++++--- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5929f60..14bfa5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2653,12 +2653,6 @@ impl RenderTree { render_tree_to_string(context, builder, &test_decorator, self.0, &mut io::sink())?; Ok(RenderedText(builder)) } - - /// Render this document using the given `decorator` and wrap it to `width` columns. - fn render(self, width: usize, decorator: D) -> Result> { - let mut context = config::plain().make_context(); - self.render_with_context(&mut context, width, decorator) - } } /// A rendered HTML document. diff --git a/src/tests.rs b/src/tests.rs index c06c12c..4ca68c6 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1529,11 +1529,11 @@ fn test_finalise() { TestDecorator } } - + let mut context = config::plain().make_context(); assert_eq!( crate::parse("test".as_bytes()) .unwrap() - .render(80, TestDecorator) + .render_with_context(&mut context, 80, TestDecorator) .unwrap() .into_lines() .unwrap(), @@ -1936,7 +1936,8 @@ fn test_issue_93_x() { ]; let _local0 = crate::parse(&data[..]).unwrap(); let d1 = TrivialDecorator::new(); - let _local1 = crate::RenderTree::render(_local0, 1, d1); + let mut context = config::plain().make_context(); + let _local1 = _local0.render_with_context(&mut context, 1, d1); } #[test] From 11e537d000c8d2f2ceba48b1e2417a2d739d3e56 Mon Sep 17 00:00:00 2001 From: c Date: Fri, 3 Jan 2025 17:00:38 +0100 Subject: [PATCH 13/15] Inline fn parse() into test --- src/tests.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests.rs b/src/tests.rs index 4ca68c6..c8c4f86 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1529,9 +1529,10 @@ fn test_finalise() { TestDecorator } } - let mut context = config::plain().make_context(); + let cfg = config::plain(); + let mut context = cfg.make_context(); assert_eq!( - crate::parse("test".as_bytes()) + cfg.do_parse(&mut context, "test".as_bytes()) .unwrap() .render_with_context(&mut context, 80, TestDecorator) .unwrap() From 61f8567c195b351fb7616480806d2ccfa92fb672 Mon Sep 17 00:00:00 2001 From: c Date: Sun, 5 Jan 2025 12:31:10 +0100 Subject: [PATCH 14/15] Express test with higher-level function --- src/tests.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/tests.rs b/src/tests.rs index c8c4f86..3787b49 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1529,14 +1529,9 @@ fn test_finalise() { TestDecorator } } - let cfg = config::plain(); - let mut context = cfg.make_context(); assert_eq!( - cfg.do_parse(&mut context, "test".as_bytes()) - .unwrap() - .render_with_context(&mut context, 80, TestDecorator) - .unwrap() - .into_lines() + config::with_decorator(TestDecorator) + .lines_from_read("test".as_bytes(), 80) .unwrap(), vec![ TaggedLine::from_string("test".to_owned(), &Vec::new()), @@ -1935,10 +1930,9 @@ fn test_issue_93_x() { 114, 104, 60, 47, 101, 109, 62, 60, 99, 99, 172, 97, 97, 58, 60, 119, 99, 64, 126, 118, 104, 100, 100, 107, 105, 60, 120, 98, 255, 255, 255, 0, 60, 255, 127, 46, 60, 113, 127, ]; - let _local0 = crate::parse(&data[..]).unwrap(); - let d1 = TrivialDecorator::new(); - let mut context = config::plain().make_context(); - let _local1 = _local0.render_with_context(&mut context, 1, d1); + config::with_decorator(TrivialDecorator::new()) + .string_from_read(&data[..], 1) + .unwrap_err(); } #[test] From edfd1a0aca8124a01c1d76a611a1aed1b5ea924f Mon Sep 17 00:00:00 2001 From: c Date: Sun, 5 Jan 2025 14:37:07 +0100 Subject: [PATCH 15/15] Use the config provided by self instead of plain() --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 14bfa5e..9861f07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2375,7 +2375,7 @@ pub mod config { where R: io::Read, { - let dom = plain().parse_html(input)?; + let dom = self.parse_html(input)?; let render_tree = super::dom_to_render_tree_with_context( dom.document.clone(), &mut io::sink(),