my fork of dmp
More docs
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/dmp.rs | 257 | ||||
| -rw-r--r-- | src/html.rs | 149 | ||||
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | tests/test.rs | 46 |
5 files changed, 412 insertions, 43 deletions
@@ -13,7 +13,6 @@ categories = ["algorithms", "text-synchronization"] [dependencies] chrono = "0" percent-encoding = "2" -urlencoding = "2" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] @@ -3,7 +3,7 @@ use std::{char, collections::HashMap, fmt::Display}; use chrono::{NaiveTime, TimeDelta, Utc}; -use crate::{errors::Error, DType, PatchInput}; +use crate::{errors::Error, html::HtmlConfig, DType, PatchInput}; /// Enum representing the different ops of diff #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -2543,7 +2543,7 @@ impl DiffMatchPatch { /// Vec of changes (Diff). /// # Example /// ``` - /// use diff_match_patch_rs::{DiffMatchPatch, Error, Efficient}; + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Efficient}; /// /// # fn main() -> Result<(), Error> { /// let mut dmp = DiffMatchPatch::new(); @@ -2579,7 +2579,6 @@ impl DiffMatchPatch { Self::cleanup_semantic(diffs) } - /// <div class="warning">Not Implemented</div> /// This function is similar to diff_cleanupSemantic, except that instead of optimising a diff to be human-readable, it optimises the diff to be efficient for machine processing. /// The results of both cleanup types are often the same. /// @@ -2616,10 +2615,31 @@ impl DiffMatchPatch { } /// Takes a diff array and returns a pretty HTML sequence. This function is mainly intended as an example from which to write ones own display functions. - /// TODO: html config + /// + /// # Example + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Efficient, HtmlConfig}; + /// # fn main() -> Result<(), Error> { + /// let dmp = DiffMatchPatch::new(); + /// + /// let diffs = dmp.diff_main::<Efficient>("The old man and the new house?", "The old man and the old dog!")?; + /// let htmlcfg = HtmlConfig::new(); + /// + /// let pretty = dmp.diff_pretty_html(&diffs, &htmlcfg)?; + /// // Should print: "<span>The old man and the </span><del>new house?</del><ins>old dog!</ins>" + /// println!("{pretty}"); + /// + /// # Ok(()) + /// # } + /// ``` + /// + /// Check out [`HtmlConfig`] options for ways to control the generated html. + /// + /// [`HtmlConfig`]: html/struct.HtmlConfig.html pub fn diff_pretty_html<T: DType>( &self, diffs: &[Diff<T>], + html_cfg: &HtmlConfig ) -> Result<String, crate::errors::Error> { let mut diffs = diffs.to_vec(); DiffMatchPatch::cleanup_semantic(&mut diffs); @@ -2631,11 +2651,18 @@ impl DiffMatchPatch { .iter() .filter_map(|diff| { let txt = match T::to_string(diff.data()) { - Ok(txt) => txt + Ok(txt) => { + let mut txt = txt .replace("&", "&") .replace("<", "<") - .replace(">", ">") - .replace("\n", "¶<br>"), + .replace(">", ">"); + + if html_cfg.nltobr() { + txt = txt.replace('\n', "<br>") + } + + txt + } Err(e) => { eprintln!("{e:?}"); is_err = true; @@ -2648,9 +2675,33 @@ impl DiffMatchPatch { } match diff.op() { - Ops::Insert => Some(format!("<ins style=\"background:#e6ffe6;\">{txt}</ins>")), - Ops::Delete => Some(format!("<del style=\"background:#ffe6e6;\">{txt}</del>")), - Ops::Equal => Some(format!("<span>{txt}</span>")), + Ops::Insert => Some( + format!( + "<{}{}{}>{txt}</{}>", + html_cfg.insert_tag(), + if let Some(cl) = html_cfg.insert_class() { format!(" class=\"{cl}\"") } else { String::new() }, + if let Some(st) = html_cfg.insert_style() { format!(" style=\"{st}\"") } else { String::new() }, + html_cfg.insert_tag() + ) + ), + Ops::Delete => Some( + format!( + "<{}{}{}>{txt}</{}>", + html_cfg.delete_tag(), + if let Some(cl) = html_cfg.delete_class() { format!(" class=\"{cl}\"") } else { String::new() }, + if let Some(st) = html_cfg.delete_style() { format!(" style=\"{st}\"") } else { String::new() }, + html_cfg.delete_tag() + ) + ), + Ops::Equal => Some( + format!( + "<{}{}{}>{txt}</{}>", + html_cfg.equality_tag(), + if let Some(cl) = html_cfg.equality_class() { format!(" class=\"{cl}\"") } else { String::new() }, + if let Some(st) = html_cfg.equality_style() { format!(" style=\"{st}\"") } else { String::new() }, + html_cfg.equality_tag() + ) + ), } }) .collect::<Vec<_>>() @@ -2686,9 +2737,38 @@ impl DiffMatchPatch { self.match_internal(text.as_bytes(), pattern.as_bytes(), loc) } - /// Given two texts, or an already computed list of differences, return an array of patch objects. - /// The third form PatchInput::TextDiffs(...) is preferred, use it if you happen to have that data available, otherwise this function will compute the missing pieces. - /// TODO: add example + /// Given two texts, or an already computed list of differences (`diffs`), return an array of patch objects. + /// + /// # Example + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Efficient, PatchInput}; + /// + /// # fn main() -> Result<(), Error> { + /// let dmp = DiffMatchPatch::new(); + /// + /// // You can also make patches from the old and new string directly + /// let patches = dmp.patch_make::<Efficient>(PatchInput::new_text_text("Apples are a fruit.", "Bananas are also fruit"))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "Apples are a fruit.")?; + /// assert_eq!("Bananas are also fruit", new_from_old); + /// + /// // Or, create some diffs in `Efficient` or `Compact` mode + /// let diffs = dmp.diff_main::<Efficient>("Apples are a fruit.", "Bananas are also fruit")?; + /// // Now, lets convert the diffs to a bunch of patches - you can use an existing set of diffs to create patches + /// let patches = dmp.patch_make(PatchInput::new_diffs(&diffs))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "Apples are a fruit.")?; + /// assert_eq!("Bananas are also fruit", new_from_old); + /// + /// // Or, from the source texts and diffs + /// let patches = dmp.patch_make(PatchInput::new_text_diffs("Apples are a fruit.", &diffs))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "Apples are a fruit.")?; + /// assert_eq!("Bananas are also fruit", new_from_old); + /// # Ok(()) + /// # } + /// ``` + /// + /// The [`PatchInput::new_text_diffs`] method is preferred, use it if you happen to have that data available, otherwise this function will compute the missing pieces. + /// + /// pub fn patch_make<T: DType>( &self, input: PatchInput<T>, @@ -2721,13 +2801,60 @@ impl DiffMatchPatch { } /// Reduces an array of patch objects to a block of text which looks extremely similar to the standard GNU diff/patch format. This text may be stored or transmitted. - /// TODO: add example + /// + /// # Example + /// + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Compat, PatchInput}; + /// + /// # fn main() -> Result<(), Error> { + /// let dmp = DiffMatchPatch::new(); + /// + /// // Making patches from source and edited text - both in `Efficient` and `Compat` mode + /// let patches = dmp.patch_make::<Compat>(PatchInput::new_text_text("Apples are fruit!", "Bananas are also fruit!"))?; + /// let patch_to_text = dmp.patch_to_text(&patches); + /// + /// // Prints patches in GNU diff/ patch format + /// // You can use this format for transmission and/ or storage. + /// println!("{patch_to_text}"); + /// + /// # Ok(()) + /// # } + /// ``` + /// + /// Check out the [`diff_to_delta`] and [`diff_from_delta`] methods for a more compact way of representing diffs. + /// + /// [`diff_to_delta`]: ./method.diff_to_delta + /// [`diff_from_delta`]: ./method.diff_from_delta + /// pub fn patch_to_text<T: DType>(&self, patches: &Patches<T>) -> String { patches.iter().map(|p| p.to_string()).collect::<String>() } - /// Parses a block of text (which was presumably created by the patch_toText function) and returns an array of patch objects. - /// TODO: add example + /// Parses a block of text (which was presumably created by the [`patch_to_text`] method) and returns an array of patch objects. + /// + /// # Example + /// + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Compat, PatchInput}; + /// + /// # fn main() -> Result<(), Error> { + /// let dmp = DiffMatchPatch::new(); + /// + /// // Making patches from source and edited text - both in `Efficient` and `Compat` mode + /// let patches = dmp.patch_make::<Compat>(PatchInput::new_text_text("Apples are fruit!", "Bananas are also fruit!"))?; + /// let patch_to_text = dmp.patch_to_text(&patches); + /// + /// // let's create patches back from text + /// let patches_recreated = dmp.patch_from_text::<Compat>(&patch_to_text)?; + /// + /// // Now you can `patch_apply` the `patches_recreated` to your source text + /// + /// # Ok(()) + /// # } + /// ``` + /// + /// [`patch_to_text`]: ./method.patch_to_text pub fn patch_from_text<T: DType>(&self, text: &str) -> Result<Patches<T>, Error> { if text.is_empty() { return Ok(vec![]); @@ -2816,6 +2943,33 @@ impl DiffMatchPatch { Ok(patches) } + + /// Crush the diff into an encoded string which describes the operations required to transform text_old into text_new. + /// E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'. + /// Operations are tab-separated. Inserted text is escaped using %xx notation. + /// + /// # Example + /// + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Compat, PatchInput}; + /// # fn main() -> Result<(), Error> { + /// + /// let dmp = DiffMatchPatch::new(); + /// + /// // let's create some diffs + /// let diffs = dmp.diff_main::<Compat>("The old house and the new dog!", "The old man and the new dog!")?; + /// // now, you can create a `delta` string which can be used to re-create the diffs + /// let delta = dmp.diff_to_delta(&diffs)?; + /// println!("{delta:?}"); + /// // You should see something like the following + /// // "=8\t-5\t+man\t=17" + /// + /// // now you can use the `diff_from_delta()` to recover the diffs + /// let diffs_later = dmp.diff_from_delta::<Compat>("The old house and the new dog!", &delta); + /// + /// # Ok(()) + /// # } + /// ``` pub fn diff_to_delta<T: DType>(&self, diffs: &[Diff<T>]) -> Result<String, crate::Error> { let mut data = diffs .iter() @@ -2845,6 +2999,38 @@ impl DiffMatchPatch { T::to_string(&data) } + + /// Given the original text `old`, and an encoded string which describes the + /// operations required to transform text1 into text2, compute the full diff. + /// + /// # Example + /// + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Compat, PatchInput}; + /// # fn main() -> Result<(), Error> { + /// + /// let dmp = DiffMatchPatch::new(); + /// + /// // let's create some diffs + /// let diffs = dmp.diff_main::<Compat>("The old house and the new dog!", "The old man and the new dog!")?; + /// // now, you can create a `delta` string which can be used to re-create the diffs + /// let delta = dmp.diff_to_delta(&diffs)?; + /// println!("{delta:?}"); + /// // You should see something like the following + /// // "=8\t-5\t+man\t=17" + /// + /// // now you can use the `diff_from_delta()` to recover the diffs + /// let diffs_later = dmp.diff_from_delta::<Compat>("The old house and the new dog!", &delta); + /// // Now, you can use these diffs to apply patches to the source text + /// let patches = dmp.patch_make(PatchInput::new_text_diffs("The old house and the new dog!", &diffs))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "The old house and the new dog!")?; + /// + /// + /// assert_eq!("The old man and the new dog!", &new_from_old); + /// + /// # Ok(()) + /// # } + /// ``` pub fn diff_from_delta<T: DType>( &self, old: &str, @@ -2903,17 +3089,44 @@ impl DiffMatchPatch { Ok(diffs) } - /// Applies a list of patches to text1. The first element of the return value is the newly patched text. + /// Applies a list of patches to `source_txt`. The first element of the return value is the newly patched text. /// The second element is an array of true/false values indicating which of the patches were successfully applied. /// [Note that this second element is not too useful since large patches may get broken up internally, resulting in a longer results list than the input with no way to figure out which patch succeeded or failed. /// A more informative API is in development.] /// /// The `match_distance` and `match_threshold` properties are used to evaluate patch application on text which does not match exactly. - /// In addition, the diff_match_patch.patch_delete_threshold property determines how closely the text within a major (~64 character) delete needs to match the expected text. - /// If patch_delete_threshold is closer to 0, then the deleted text must match the expected text more closely. - /// If patch_delete_threshold is closer to 1, then the deleted text may contain anything. - /// In most use cases Patch_DeleteThreshold should just be set to the same value as match_threshold. - /// TODO: add example + /// In addition, the `DiffMatchPatch.delete_threshold` property determines how closely the text within a major (~64 character) delete needs to match the expected text. + /// If `delete_threshold` is closer to 0, then the deleted text must match the expected text more closely. + /// If `delete_threshold` is closer to 1, then the deleted text may contain anything. + /// In most use cases `delete_threshold` should just be set to the same value as `match_threshold`. Both values default to `0.5` + /// + /// # Example + /// # Example + /// ``` + /// # use diff_match_patch_rs::{DiffMatchPatch, Error, Efficient, PatchInput}; + /// + /// # fn main() -> Result<(), Error> { + /// let dmp = DiffMatchPatch::new(); + /// + /// // You can also make patches from the old and new string directly + /// let patches = dmp.patch_make::<Efficient>(PatchInput::new_text_text("Apples are a fruit.", "Bananas are also fruit"))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "Apples are a fruit.")?; + /// assert_eq!("Bananas are also fruit", new_from_old); + /// + /// // Or, create some diffs in `Efficient` or `Compact` mode + /// let diffs = dmp.diff_main::<Efficient>("Apples are a fruit.", "Bananas are also fruit")?; + /// // Now, lets convert the diffs to a bunch of patches - you can use an existing set of diffs to create patches + /// let patches = dmp.patch_make(PatchInput::new_diffs(&diffs))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "Apples are a fruit.")?; + /// assert_eq!("Bananas are also fruit", new_from_old); + /// + /// // Or, from the source texts and diffs + /// let patches = dmp.patch_make(PatchInput::new_text_diffs("Apples are a fruit.", &diffs))?; + /// let (new_from_old, _) = dmp.patch_apply(&patches, "Apples are a fruit.")?; + /// assert_eq!("Bananas are also fruit", new_from_old); + /// # Ok(()) + /// # } + /// ``` pub fn patch_apply<T: DType>( &self, patches: &Patches<T>, diff --git a/src/html.rs b/src/html.rs new file mode 100644 index 0000000..b312991 --- /dev/null +++ b/src/html.rs @@ -0,0 +1,149 @@ +/// A struct representing some properties to control the [`pretty_html`] generation. +/// The `insert_tag`, `delete_tag` and `equality_tag` represents the `html` tag to wrap the part of the text being inserted, deleted or equality. +/// +/// E.g. if `insert_tag` is set to `span`, the text to be inserted will be wrapped around with `<span>some text to insert</span>`. +/// `insert_tag` defaults to the `ins` tag, `delete_tag` defaults to the `del` tag and `equality_tag` defaults to `span`. +/// +/// `nltobr` switch enables or disables replacing of `\n` in the text with a `<br>` element. Defaults to `true` +/// +/// `insert_class`, `delete_class` or `equality_class` if set will be added as a `class="your css class"`. Defaults to `None` +/// +/// `insert_style`, `delete_style` and `equality_style` would add css style property to the output. +/// E.g. if `insert_style: Some("background: yellow; color: purple")` is set the +/// `insert` part of the pretty html would look like `<ins style="background: yellow; color: purple">insert text</ins>` +pub struct HtmlConfig<'a> { + insert_tag: &'a str, + delete_tag: &'a str, + equality_tag: &'a str, + nltobr: bool, + insert_class: Option<&'a str>, + delete_class: Option<&'a str>, + equality_class: Option<&'a str>, + insert_style: Option<&'a str>, + delete_style: Option<&'a str>, + equality_style: Option<&'a str> +} + +impl <'a>Default for HtmlConfig<'a> { + fn default() -> Self { + Self { + insert_tag: "ins", + delete_tag: "del", + equality_tag: "span", + nltobr: true, + insert_class: None, + delete_class: None, + equality_class: None, + insert_style: None, + delete_style: None, + equality_style: None + } + } +} + +impl <'a>HtmlConfig<'a> { + /// Creates a new instance of the struct with some defaults. + /// + /// `insert_tag` defaults to "ins". + /// + /// `delete_tag` defaults to "del" + /// + /// `equality_tag` defaults to "span" + /// + /// `nltobr` defaults to `true` + /// + /// Other fields defaults to `None` + pub fn new() -> Self { + Self::default() + } + + pub(crate) fn insert_tag(&self) -> &str { + self.insert_tag + } + + /// Set the HTML tag to be used for text inserted + pub fn set_insert_tag(&mut self, tag: &'a str) { + self.insert_tag = tag; + } + + pub(crate) fn delete_tag(&self) -> &str { + self.delete_tag + } + + /// Set the HTML tag to be used for text deleted + pub fn set_delete_tag(&mut self, tag: &'a str) { + self.delete_tag = tag; + } + + pub(crate) fn equality_tag(&self) -> &str { + self.equality_tag + } + + /// Set the HTML tag to be used for text that has not changed + pub fn set_equality_tag(&mut self, tag: &'a str) { + self.equality_tag = tag; + } + + pub(crate) fn nltobr(&self) -> bool { + self.nltobr + } + + /// Switch to control if `\nl` should be replaced with `<br>` + pub fn set_nl_to_br(&mut self, nltobr: bool) { + self.nltobr = nltobr + } + + pub(crate) fn insert_class(&self) -> Option<&'a str> { + self.insert_class + } + + /// Set the css class for the text inserted + pub fn set_insert_class(&mut self, class: Option<&'a str>) { + self.insert_class = class; + } + + pub(crate) fn delete_class(&self) -> Option<&'a str> { + self.delete_class + } + + /// Set the delete class for text deleted + pub fn set_delete_class(&mut self, class: Option<&'a str>) { + self.delete_class = class; + } + + pub(crate) fn equality_class(&self) -> Option<&'a str> { + self.equality_class + } + + /// Set the css class for text that has not changed + pub fn set_equality_class(&mut self, class: Option<&'a str>) { + self.equality_class = class; + } + + pub(crate) fn insert_style(&self) -> Option<&'a str> { + self.insert_style + } + + /// Set the css style property for text inserted + pub fn set_insert_style(&mut self, style: Option<&'a str>) { + self.insert_style = style; + } + + pub(crate) fn delete_style(&self) -> Option<&'a str> { + self.delete_style + } + + /// Set the css style property for text deleted + pub fn set_delete_style(&mut self, style: Option<&'a str>) { + self.delete_style = style; + } + + pub(crate) fn equality_style(&self) -> Option<&'a str> { + self.equality_style + } + + /// Set the css style for text that has not changed + pub fn set_equality_style(&mut self, style: Option<&'a str>) { + self.equality_style = style; + } +}
\ No newline at end of file @@ -3,11 +3,13 @@ pub mod dmp; pub mod errors; pub mod fuzz; +pub mod html; pub mod patch_input; pub mod traits; pub use dmp::{DiffMatchPatch, Ops, Patch, Patches}; pub use errors::Error; +pub use html::HtmlConfig; pub use patch_input::PatchInput; pub(crate) use traits::DType; pub use traits::{Compat, Efficient}; diff --git a/tests/test.rs b/tests/test.rs index 4f86462..286200e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -4,6 +4,7 @@ use chrono::Utc; use diff_match_patch_rs::dmp::Diff; +use diff_match_patch_rs::html::HtmlConfig; use diff_match_patch_rs::{Compat, DiffMatchPatch, Efficient, Error, Ops, PatchInput}; #[test] @@ -64,13 +65,18 @@ fn test_diff_bisect() -> Result<(), Error> { #[test] fn test_diff_pretty_html() -> Result<(), Error> { let dmp = DiffMatchPatch::new(); + let mut html_cfg = HtmlConfig::new(); + + html_cfg.set_insert_style(Some("background:#e6ffe6;")); + html_cfg.set_delete_style(Some("background:#ffe6e6;")); + // Basic let diffs = [ Diff::equal(b"a\n"), Diff::delete(b"<B>b</B>"), Diff::insert(b"c&d"), ]; - assert_eq!("<span>a¶<br></span><del style=\"background:#ffe6e6;\"><B>b</B></del><ins style=\"background:#e6ffe6;\">c&d</ins>", dmp.diff_pretty_html(&diffs)?); + assert_eq!("<span>a<br></span><del style=\"background:#ffe6e6;\"><B>b</B></del><ins style=\"background:#e6ffe6;\">c&d</ins>", dmp.diff_pretty_html(&diffs, &html_cfg)?); // Monkey busiess around Emoticons and extended utf-8 ðĪŠðĪĐðĪ // This gave me a lot of heart-burn @@ -83,7 +89,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ðĪŠ</del><ins style=\"background:#e6ffe6;\">ðĪ</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Now Case 1. but with some text before and after @@ -92,7 +98,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<span>I'm puzzled</span><del style=\"background:#ffe6e6;\">ðĪŠ</del><ins style=\"background:#e6ffe6;\">ðĪ</ins><span> or </span><del style=\"background:#ffe6e6;\">am I?</del><ins style=\"background:#e6ffe6;\">thinking I guess!</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 2. Emoticons with the third position different @@ -101,7 +107,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Now Case 2. but with some text, lets complicate this @@ -110,7 +116,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð, a</del><ins style=\"background:#e6ffe6;\">A</ins><span>ah orange</span><del style=\"background:#ffe6e6;\"> </del><ins style=\"background:#e6ffe6;\">!ð</ins><span>is the new </span><del style=\"background:#ffe6e6;\">black!</del><ins style=\"background:#e6ffe6;\">ð</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 3. with second and third different, but lets complicate this with an equality @@ -119,7 +125,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<ins style=\"background:#e6ffe6;\">ð </ins><del style=\"background:#ffe6e6;\">ð </del>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 3. but let there be a swap @@ -128,7 +134,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð </del><ins style=\"background:#e6ffe6;\">ð </ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 4. swap at the last 2 positions @@ -137,7 +143,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Let's do this with a slightly longish string @@ -146,8 +152,8 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Efficient>(old, new)?; assert_eq!( - "<del style=\"background:#ffe6e6;\">Now, let's explore some emotional extreme</del><ins style=\"background:#e6ffe6;\">Let's start with some basic</ins><span>s </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.¶<br>We've got your </span><del style=\"background:#ffe6e6;\">ec</del><span>sta</span><del style=\"background:#ffe6e6;\">tic</del><ins style=\"background:#e6ffe6;\">ndard smiley</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪĐ</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, your </span><del style=\"background:#ffe6e6;\">devastate</del><ins style=\"background:#e6ffe6;\">sa</ins><span>d face </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">âđïļ</ins><span>, and your </span><del style=\"background:#ffe6e6;\">utterly confused</del><ins style=\"background:#e6ffe6;\">angry</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪŊ</del><ins style=\"background:#e6ffe6;\">ð </ins><span>. But </span><del style=\"background:#ffe6e6;\">that's not all</del><ins style=\"background:#e6ffe6;\">wait, there's more</ins><span>! </span><del style=\"background:#ffe6e6;\">ðĪ</del><ins style=\"background:#e6ffe6;\">ðĪĐ</ins><span> We've also got some </span><del style=\"background:#ffe6e6;\">subt</del><ins style=\"background:#e6ffe6;\">more comp</ins><span>le</span><ins style=\"background:#e6ffe6;\">x</ins><span> emotions like </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð, ðĪĪ, and ð. And let's not forget about the classics: ð</ins><span>, </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, and </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.</span>", - dmp.diff_pretty_html(&diffs)? + "<del style=\"background:#ffe6e6;\">Now, let's explore some emotional extreme</del><ins style=\"background:#e6ffe6;\">Let's start with some basic</ins><span>s </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.<br>We've got your </span><del style=\"background:#ffe6e6;\">ec</del><span>sta</span><del style=\"background:#ffe6e6;\">tic</del><ins style=\"background:#e6ffe6;\">ndard smiley</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪĐ</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, your </span><del style=\"background:#ffe6e6;\">devastate</del><ins style=\"background:#e6ffe6;\">sa</ins><span>d face </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">âđïļ</ins><span>, and your </span><del style=\"background:#ffe6e6;\">utterly confused</del><ins style=\"background:#e6ffe6;\">angry</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪŊ</del><ins style=\"background:#e6ffe6;\">ð </ins><span>. But </span><del style=\"background:#ffe6e6;\">that's not all</del><ins style=\"background:#e6ffe6;\">wait, there's more</ins><span>! </span><del style=\"background:#ffe6e6;\">ðĪ</del><ins style=\"background:#e6ffe6;\">ðĪĐ</ins><span> We've also got some </span><del style=\"background:#ffe6e6;\">subt</del><ins style=\"background:#e6ffe6;\">more comp</ins><span>le</span><ins style=\"background:#e6ffe6;\">x</ins><span> emotions like </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð, ðĪĪ, and ð. And let's not forget about the classics: ð</ins><span>, </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, and </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.</span>", + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Compat mode @@ -157,7 +163,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { Diff::delete(&"<B>b</B>".chars().collect::<Vec<_>>()[..]), Diff::insert(&"c&d".chars().collect::<Vec<_>>()[..]), ]; - assert_eq!("<span>a¶<br></span><del style=\"background:#ffe6e6;\"><B>b</B></del><ins style=\"background:#e6ffe6;\">c&d</ins>", dmp.diff_pretty_html(&diffs)?); + assert_eq!("<span>a<br></span><del style=\"background:#ffe6e6;\"><B>b</B></del><ins style=\"background:#e6ffe6;\">c&d</ins>", dmp.diff_pretty_html(&diffs, &html_cfg)?); // `Compat` mode shouldn't require monkey business atall @@ -169,7 +175,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ðĪŠ</del><ins style=\"background:#e6ffe6;\">ðĪ</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Now Case 1. but with some text before and after @@ -178,7 +184,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<span>I'm puzzled</span><del style=\"background:#ffe6e6;\">ðĪŠ</del><ins style=\"background:#e6ffe6;\">ðĪ</ins><span> or </span><del style=\"background:#ffe6e6;\">am I?</del><ins style=\"background:#e6ffe6;\">thinking I guess!</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 2. Emoticons with the third position different @@ -187,7 +193,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Now Case 2. but with some text, lets complicate this @@ -196,7 +202,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð, a</del><ins style=\"background:#e6ffe6;\">A</ins><span>ah orange</span><del style=\"background:#ffe6e6;\"> </del><ins style=\"background:#e6ffe6;\">!ð</ins><span>is the new </span><del style=\"background:#ffe6e6;\">black!</del><ins style=\"background:#e6ffe6;\">ð</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 3. with second and third different, but lets complicate this with an equality @@ -205,7 +211,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð </del><ins style=\"background:#e6ffe6;\">ð </ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 3. but let there be a swap @@ -214,7 +220,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð </del><ins style=\"background:#e6ffe6;\">ð </ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Case 4. swap at the last 2 positions @@ -223,7 +229,7 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( "<del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins>", - dmp.diff_pretty_html(&diffs)? + dmp.diff_pretty_html(&diffs, &html_cfg)? ); // Let's do this with a slightly longish string @@ -232,8 +238,8 @@ fn test_diff_pretty_html() -> Result<(), Error> { let diffs = dmp.diff_main::<Compat>(old, new)?; assert_eq!( - "<del style=\"background:#ffe6e6;\">Now, let's explore some emotional extreme</del><ins style=\"background:#e6ffe6;\">Let's start with some basic</ins><span>s </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.¶<br>We've got your </span><del style=\"background:#ffe6e6;\">ec</del><span>sta</span><del style=\"background:#ffe6e6;\">tic</del><ins style=\"background:#e6ffe6;\">ndard smiley</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪĐ</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, your </span><del style=\"background:#ffe6e6;\">devastate</del><ins style=\"background:#e6ffe6;\">sa</ins><span>d face </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">âđïļ</ins><span>, and your </span><del style=\"background:#ffe6e6;\">utterly confused</del><ins style=\"background:#e6ffe6;\">angry</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪŊ</del><ins style=\"background:#e6ffe6;\">ð </ins><span>. But </span><del style=\"background:#ffe6e6;\">that's not all</del><ins style=\"background:#e6ffe6;\">wait, there's more</ins><span>! </span><del style=\"background:#ffe6e6;\">ðĪ</del><ins style=\"background:#e6ffe6;\">ðĪĐ</ins><span> We've also got some </span><del style=\"background:#ffe6e6;\">subt</del><ins style=\"background:#e6ffe6;\">more comp</ins><span>le</span><ins style=\"background:#e6ffe6;\">x</ins><span> emotions like </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð, ðĪĪ, and ð. And let's not forget about the classics: ð</ins><span>, </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, and </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.</span>", - dmp.diff_pretty_html(&diffs)? + "<del style=\"background:#ffe6e6;\">Now, let's explore some emotional extreme</del><ins style=\"background:#e6ffe6;\">Let's start with some basic</ins><span>s </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.<br>We've got your </span><del style=\"background:#ffe6e6;\">ec</del><span>sta</span><del style=\"background:#ffe6e6;\">tic</del><ins style=\"background:#e6ffe6;\">ndard smiley</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪĐ</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, your </span><del style=\"background:#ffe6e6;\">devastate</del><ins style=\"background:#e6ffe6;\">sa</ins><span>d face </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">âđïļ</ins><span>, and your </span><del style=\"background:#ffe6e6;\">utterly confused</del><ins style=\"background:#e6ffe6;\">angry</ins><span> face </span><del style=\"background:#ffe6e6;\">ðĪŊ</del><ins style=\"background:#e6ffe6;\">ð </ins><span>. But </span><del style=\"background:#ffe6e6;\">that's not all</del><ins style=\"background:#e6ffe6;\">wait, there's more</ins><span>! </span><del style=\"background:#ffe6e6;\">ðĪ</del><ins style=\"background:#e6ffe6;\">ðĪĐ</ins><span> We've also got some </span><del style=\"background:#ffe6e6;\">subt</del><ins style=\"background:#e6ffe6;\">more comp</ins><span>le</span><ins style=\"background:#e6ffe6;\">x</ins><span> emotions like </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð, ðĪĪ, and ð. And let's not forget about the classics: ð</ins><span>, </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>, and </span><del style=\"background:#ffe6e6;\">ð</del><ins style=\"background:#e6ffe6;\">ð</ins><span>.</span>", + dmp.diff_pretty_html(&diffs, &html_cfg)? ); Ok(()) |