[librsvg] space.rs: New file to deal with xml:space normalization



commit c9c01b5b1ef4e6898b1492df64755de31f54ebb2
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Dec 7 08:39:02 2017 -0600

    space.rs: New file to deal with xml:space normalization

 Makefile.am       |    1 +
 rust/src/lib.rs   |    1 +
 rust/src/space.rs |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 9e05c09..a60a2cb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -94,6 +94,7 @@ RUST_SOURCES =                                        \
        rust/src/pattern.rs                     \
        rust/src/property_bag.rs                \
        rust/src/shapes.rs                      \
+       rust/src/space.rs                       \
        rust/src/state.rs                       \
        rust/src/stop.rs                        \
        rust/src/structure.rs                   \
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 76a3e2c..e39726e 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -169,6 +169,7 @@ mod path_parser;
 mod pattern;
 mod property_bag;
 mod shapes;
+mod space;
 mod state;
 mod stop;
 mod structure;
diff --git a/rust/src/space.rs b/rust/src/space.rs
new file mode 100644
index 0000000..8f364ed
--- /dev/null
+++ b/rust/src/space.rs
@@ -0,0 +1,92 @@
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum XmlSpace {
+    Default,
+    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 {
+    match mode {
+        XmlSpace::Default => normalize_default(s),
+        XmlSpace::Preserve => normalize_preserve(s)
+    }
+}
+
+fn normalize_default(s: &str) -> String {
+    #[derive(PartialEq)]
+    enum State {
+        SpacesAtStart,
+        NonSpace,
+        SpacesAtMiddle
+    }
+
+    let mut result = String::new();
+    let mut state = State::SpacesAtStart;
+
+    for ch in s.chars() {
+        match ch {
+            '\n' => continue,
+            '\t' | ' ' => {
+                match state {
+                    State::SpacesAtStart  => continue,
+                    State::NonSpace       => { state = State::SpacesAtMiddle; },
+                    State::SpacesAtMiddle => continue,
+                }
+            },
+
+            _ => {
+                if state == State::SpacesAtMiddle {
+                    result.push(' ');
+                }
+
+                result.push(ch);
+                state = State::NonSpace;
+            }
+        }
+    }
+
+    result
+}
+
+fn normalize_preserve(s: &str) -> String {
+    let mut result = String::new();
+
+    for ch in s.chars() {
+        match ch {
+            '\n' | '\t' => result.push(' '),
+
+            _ => result.push(ch),
+        }
+    }
+
+    result
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn xml_space_default() {
+        assert_eq!(xml_space_normalize(XmlSpace::Default, "\n    WS example\n    indented lines\n  "),
+                   "WS example indented lines");
+        assert_eq!(xml_space_normalize(XmlSpace::Default, "\n  \t  \tWS \t\t\texample\n  \t  indented 
lines\t\t  \n  "),
+                   "WS example indented lines");
+
+        assert_eq!(xml_space_normalize(XmlSpace::Default, "\nWS example\nnon-indented lines\n  "),
+                   "WS examplenon-indented lines");
+    }
+
+    #[test]
+    fn xml_space_preserve() {
+        assert_eq!(xml_space_normalize(XmlSpace::Preserve, "\n    WS example\n    indented lines\n  "),
+                   "     WS example     indented lines   ");
+        assert_eq!(xml_space_normalize(XmlSpace::Preserve, "\n  \t  \tWS \t\t\texample\n  \t  indented 
lines\t\t  \n  "),
+                   "       WS    example      indented lines       ");
+
+    }
+}


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