[librsvg: 3/5] XmlSpaceNormalize: new enum to specify how to trim spaces in xml_space_normalize()



commit 571f06a8e7f0036a80691ce43b8bf825b7944034
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Oct 23 14:54:58 2018 -0500

    XmlSpaceNormalize: new enum to specify how to trim spaces in xml_space_normalize()

 rsvg_internals/src/space.rs | 94 +++++++++++++++++++++++++++++++++++++--------
 rsvg_internals/src/text.rs  | 14 ++++++-
 2 files changed, 91 insertions(+), 17 deletions(-)
---
diff --git a/rsvg_internals/src/space.rs b/rsvg_internals/src/space.rs
index 20ffb326..4350db28 100644
--- a/rsvg_internals/src/space.rs
+++ b/rsvg_internals/src/space.rs
@@ -1,15 +1,24 @@
 use itertools::Itertools;
-use state::XmlSpace;
+
+pub struct NormalizeDefault {
+    pub has_element_before: bool,
+    pub has_element_after: bool,
+}
+
+pub enum XmlSpaceNormalize {
+    Default(NormalizeDefault),
+    Preserve,
+}
 
 /// Implements `xml:space` handling per the SVG spec
 ///
 /// Normalizes a string as it comes out of the XML parser's handler
 /// for character data according to the SVG rules in
 /// <https://www.w3.org/TR/SVG/text.html#WhiteSpace>
-pub fn xml_space_normalize(mode: XmlSpace, s: &str) -> String {
+pub fn xml_space_normalize(mode: XmlSpaceNormalize, s: &str) -> String {
     match mode {
-        XmlSpace::Default => normalize_default(s),
-        XmlSpace::Preserve => normalize_preserve(s),
+        XmlSpaceNormalize::Default(d) => normalize_default(d, s),
+        XmlSpaceNormalize::Preserve => normalize_preserve(s),
     }
 }
 
@@ -21,9 +30,18 @@ pub fn xml_space_normalize(mode: XmlSpace, s: &str) -> String {
 // characters into space characters. Then, it will strip off all
 // leading and trailing space characters. Then, all contiguous space
 // characters will be consolidated.
-fn normalize_default(s: &str) -> String {
-    s.trim()
-        .chars()
+fn normalize_default(elements: NormalizeDefault, s: &str) -> String {
+    let mut s = s;
+
+    if !elements.has_element_before {
+        s = s.trim_left();
+    }
+
+    if !elements.has_element_after {
+        s = s.trim_right();
+    }
+
+    s.chars()
         .filter(|ch| *ch != '\n')
         .map(|ch| match ch {
             '\t' => ' ',
@@ -64,54 +82,100 @@ mod tests {
     fn xml_space_default() {
         assert_eq!(
             xml_space_normalize(
-                XmlSpace::Default,
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: false,
+                }),
                 "\n    WS example\n    indented lines\n  "
             ),
             "WS example indented lines"
         );
         assert_eq!(
             xml_space_normalize(
-                XmlSpace::Default,
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: false,
+                }),
                 "\n  \t  \tWS \t\t\texample\n  \t  indented lines\t\t  \n  "
             ),
             "WS example indented lines"
         );
         assert_eq!(
             xml_space_normalize(
-                XmlSpace::Default,
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: false,
+                }),
                 "\n  \t  \tWS \t\t\texample\n  \t  duplicate letters\t\t  \n  "
             ),
             "WS example duplicate letters"
         );
         assert_eq!(
-            xml_space_normalize(XmlSpace::Default, "\nWS example\nnon-indented lines\n  "),
+            xml_space_normalize(
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: false,
+                }),
+                "\nWS example\nnon-indented lines\n  "
+            ),
             "WS examplenon-indented lines"
         );
         assert_eq!(
-            xml_space_normalize(XmlSpace::Default, "\nWS example\tnon-indented lines\n  "),
+            xml_space_normalize(
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: false,
+                }),
+                "\nWS example\tnon-indented lines\n  "
+            ),
             "WS example non-indented lines"
         );
     }
 
+    #[test]
+    fn xml_space_default_with_elements() {
+        assert_eq!(
+            xml_space_normalize(
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: true,
+                    has_element_after: false,
+                }),
+                " foo \n\t  bar "
+            ),
+            " foo bar"
+        );
+
+        assert_eq!(
+            xml_space_normalize(
+                XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: true,
+                }),
+                " foo   \nbar "
+            ),
+            "foo bar "
+        );
+    }
+
     #[test]
     fn xml_space_preserve() {
         assert_eq!(
             xml_space_normalize(
-                XmlSpace::Preserve,
+                XmlSpaceNormalize::Preserve,
                 "\n    WS example\n    indented lines\n  "
             ),
             "     WS example     indented lines   "
         );
         assert_eq!(
             xml_space_normalize(
-                XmlSpace::Preserve,
+                XmlSpaceNormalize::Preserve,
                 "\n  \t  \tWS \t\t\texample\n  \t  indented lines\t\t  \n  "
             ),
             "       WS    example      indented lines       "
         );
         assert_eq!(
             xml_space_normalize(
-                XmlSpace::Preserve,
+                XmlSpaceNormalize::Preserve,
                 "\n  \t  \tWS \t\t\texample\n  \t  duplicate letters\t\t  \n  "
             ),
             "       WS    example      duplicate letters       "
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 05cb4331..6bf9f0d7 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -13,7 +13,7 @@ use length::*;
 use node::{boxed_node_new, CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
 use parsers::parse;
 use property_bag::PropertyBag;
-use space::xml_space_normalize;
+use space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
 use state::{
     ComputedValues,
     Direction,
@@ -23,6 +23,7 @@ use state::{
     TextAnchor,
     UnicodeBidi,
     WritingMode,
+    XmlSpace,
 };
 
 /// In SVG text elements, we use `NodeChars` to store character data.  For example,
@@ -70,7 +71,16 @@ impl NodeChars {
         let mut normalized = self.space_normalized.borrow_mut();
 
         if (*normalized).is_none() {
-            *normalized = Some(xml_space_normalize(values.xml_space, &self.string.borrow()));
+            let mode = match values.xml_space {
+                XmlSpace::Default => XmlSpaceNormalize::Default(NormalizeDefault {
+                    has_element_before: false,
+                    has_element_after: false,
+                }),
+
+                XmlSpace::Preserve => XmlSpaceNormalize::Preserve,
+            };
+
+            *normalized = Some(xml_space_normalize(mode, &self.string.borrow()));
         }
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]