summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJovansonlee Cesar <ivanceras@gmail.com>2020-11-04 16:23:14 +0800
committerJovansonlee Cesar <ivanceras@gmail.com>2020-11-04 16:23:14 +0800
commit10fe6ee719747d9652aa56736e10d31d7ddce3c6 (patch)
tree591f8662eb7b39d6d8528d978940d09634e6b9af
parent146d1d5eb09e1d192a4a59b717bab82b2b204398 (diff)
Add escape_line for escaping non-drawing characters with double quotes
-rw-r--r--svgbob/src/buffer/cell_buffer.rs42
-rw-r--r--svgbob/src/util.rs37
2 files changed, 78 insertions, 1 deletions
diff --git a/svgbob/src/buffer/cell_buffer.rs b/svgbob/src/buffer/cell_buffer.rs
index 4383cfc..fc1afd0 100644
--- a/svgbob/src/buffer/cell_buffer.rs
+++ b/svgbob/src/buffer/cell_buffer.rs
@@ -38,6 +38,7 @@ pub struct CellBuffer {
/// .class { styles }
/// ```
css_styles: Vec<(String, String)>,
+ escaped_text: Vec<(Cell, String)>,
}
impl Deref for CellBuffer {
@@ -59,6 +60,7 @@ impl CellBuffer {
CellBuffer {
map: BTreeMap::new(),
css_styles: vec![],
+ escaped_text: vec![],
}
}
@@ -426,6 +428,28 @@ impl CellBuffer {
)],
)
}
+
+ /// returns a (Cell, escaped string), and the strings that are not part of the escape string
+ fn escape_line(line: usize, raw: &str) -> (Vec<(Cell, String)>, String) {
+ let mut no_escaped_text = String::new();
+
+ let mut index = 0;
+ let mut escaped_text = vec![];
+ let input_chars: Vec<char> = raw.chars().collect();
+ let char_locs = parser::line_parse()
+ .parse(&input_chars)
+ .expect("should parse");
+ for (start, end) in char_locs.iter() {
+ let escaped = raw[*start + 1..*end].to_string();
+ let cell = Cell::new(*start as i32, line as i32);
+ escaped_text.push((cell, escaped));
+
+ no_escaped_text.push_str(&raw[index..*start]);
+ no_escaped_text.push_str(&" ".repeat(end + 1 - start));
+ index = end + 1;
+ }
+ (escaped_text, no_escaped_text)
+ }
}
impl fmt::Display for CellBuffer {
@@ -479,6 +503,24 @@ mod tests {
use super::*;
#[test]
+ fn test_escape_line() {
+ let raw = r#"The "qu/i/ck" brown "fox\"s" jumps over the lazy "do|g""#;
+ let ex2 = r#"The brown jumps over the lazy "#;
+ let (escaped, unescaped) = CellBuffer::escape_line(0, raw);
+ println!("escaped: {:#?}", escaped);
+ println!("unescaped: {}", unescaped);
+ assert_eq!(
+ vec![
+ (Cell::new(4, 0), "qu/i/ck".to_string()),
+ (Cell::new(20, 0), r#"fox\"s"#.to_string()),
+ (Cell::new(49, 0), "do|g".to_string())
+ ],
+ escaped
+ );
+ assert_eq!(ex2, unescaped);
+ }
+
+ #[test]
fn test_simple_adjacents() {
let art = r#"
.. ._.
diff --git a/svgbob/src/util.rs b/svgbob/src/util.rs
index e05b038..2a50fab 100644
--- a/svgbob/src/util.rs
+++ b/svgbob/src/util.rs
@@ -72,12 +72,17 @@ pub fn is_collinear(a: &Point, b: &Point, c: &Point) -> bool {
}
pub fn pad(v: f32) -> f32 {
- if v > 0.0 { v.ceil() } else { v.floor() }
+ if v > 0.0 {
+ v.ceil()
+ } else {
+ v.floor()
+ }
}
/// this is parser module which provides parsing for identifier for
/// extracting the css tag of inside of a shape fragment
pub mod parser {
+ use crate::Cell;
use pom::parser::{call, end, is_a, list, none_of, one_of, sym, tag, Parser};
use std::iter::FromIterator;
@@ -224,11 +229,41 @@ pub mod parser {
css_legend_with_padding().parse(input)
}
+ fn escape_string<'a>() -> pom::parser::Parser<'a, char, (usize, usize)> {
+ let escape_sequence = sym('\\') * sym('"'); //escape sequence \"
+ let char_string = escape_sequence | none_of("\"");
+ let escaped_string_end = sym('"') * char_string.repeat(0..).pos() - sym('"');
+ none_of("\"").repeat(0..).pos() + escaped_string_end - none_of("\"").repeat(0..).discard()
+ }
+
+ pub(crate) fn line_parse<'a>() -> pom::parser::Parser<'a, char, Vec<(usize, usize)>> {
+ escape_string().repeat(0..)
+ }
+
#[cfg(test)]
mod tests {
use super::*;
#[test]
+ fn test_escaped_string() {
+ let raw = r#"The "qu/i/ck" brown "fox\"s" jumps over the lazy "do|g""#;
+ let input_chars: Vec<char> = raw.chars().collect();
+ let char_locs = line_parse().parse(&input_chars).expect("should parse");
+ println!("output3: {:?}", char_locs);
+ let mut escaped = vec![];
+ let mut cleaned = vec![];
+ for (start, end) in char_locs.iter() {
+ escaped.push(&raw[*start..=*end]);
+ cleaned.push(&raw[*start + 1..*end]);
+ }
+ println!("{:#?}", escaped);
+ let expected = vec![r#""qu/i/ck""#, r#""fox\"s""#, r#""do|g""#];
+ assert_eq!(expected, escaped);
+ let expected_cleaned = vec![r#"qu/i/ck"#, r#"fox\"s"#, r#"do|g"#];
+ assert_eq!(expected_cleaned, cleaned);
+ }
+
+ #[test]
fn test_css_styles() {
let input = "{fill:blue; stroke:red;}";
let input_chars: Vec<char> = input.chars().collect();