[librsvg: 3/5] XmlSpaceNormalize: new enum to specify how to trim spaces in xml_space_normalize()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/5] XmlSpaceNormalize: new enum to specify how to trim spaces in xml_space_normalize()
- Date: Wed, 24 Oct 2018 13:14:44 +0000 (UTC)
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]