From 4d1f0052476ad1bb2fa9797d36db833c3a732521 Mon Sep 17 00:00:00 2001 From: Elisabeth Henry Date: Sun, 25 Sep 2016 01:37:14 +0200 Subject: [PATCH] Escape nb spaces with html entities when html.escape_nb_spaces is true --- src/bin/{main.rs => real_main.rs} | 0 src/lib/bookoptions.rs | 2 +- src/lib/escape.rs | 26 ++++++++++---------------- src/lib/html.rs | 3 ++- src/lib/html_dir.rs | 7 +++++-- src/lib/html_single.rs | 9 ++++++--- templates/epub/stylesheet.css | 19 ++++++++++++++++++- 7 files changed, 42 insertions(+), 24 deletions(-) rename src/bin/{main.rs => real_main.rs} (100%) diff --git a/src/bin/main.rs b/src/bin/real_main.rs similarity index 100% rename from src/bin/main.rs rename to src/bin/real_main.rs diff --git a/src/lib/bookoptions.rs b/src/lib/bookoptions.rs index ff7d2d8..1b3a6be 100644 --- a/src/lib/bookoptions.rs +++ b/src/lib/bookoptions.rs @@ -52,7 +52,7 @@ html.highlight_code:bool:true # Provides syntax highlighting for code bloc html.highlight.js:tpl # Set another highlight.js version than the bundled one html.highlight.css:tpl # Set another highlight.js CSS theme than the default one html.side_notes:bool:false # Display footnotes as side notes in HTML/Epub (experimental) - +html.escape_nb_spaces:bool:true # Replace unicode non breaking spaces with HTML entities and CSS # Standalone HTML options html_single.one_chapter:bool:false # Display only one chapter at a time (with a button to display all) diff --git a/src/lib/escape.rs b/src/lib/escape.rs index 66611e3..5b9f72b 100644 --- a/src/lib/escape.rs +++ b/src/lib/escape.rs @@ -24,28 +24,22 @@ const NB_CHAR_NARROW:char = '\u{202F}'; // narrow non breaking space const NB_CHAR_EM:char = '\u{2002}'; // demi em space -/// Escape non breaking spaces for HTML, so they are visible. -#[doc(hidden)] +/// Escape non breaking spaces for HTML, so there is no problem for displaying them if the font or browser +/// doesn't know what to do with them pub fn escape_nb_spaces<'a, S: Into>>(input: S) -> Cow<'a, str> { let input = input.into(); - if input.contains(|c| match c { + if let Some(first) = input.chars().position(|c| match c { NB_CHAR | NB_CHAR_NARROW | NB_CHAR_EM => true, _ => false }) { - let mut output = String::with_capacity(input.len()); - for c in input.chars() { + let mut chars = input.chars().collect::>(); + let rest = chars.split_off(first); + let mut output = chars.into_iter().collect::(); + for c in rest { match c { - NB_CHAR_NARROW - | NB_CHAR_EM - | NB_CHAR - => output.push_str(&format!("{}", - match c { - NB_CHAR => "#ffff66", - NB_CHAR_NARROW => "#9999ff", - NB_CHAR_EM => "#ff9999", - _ => unreachable!() - }, - c)), + NB_CHAR_NARROW => output.push_str(r#""#), + NB_CHAR_EM => output.push_str(r#""#), + NB_CHAR => output.push_str(r#" "#), _ => output.push(c), } } diff --git a/src/lib/html.rs b/src/lib/html.rs index d1c41bf..21c13ac 100644 --- a/src/lib/html.rs +++ b/src/lib/html.rs @@ -390,7 +390,8 @@ impl<'a> HtmlRenderer<'a> { } else { content }; - if this.as_ref().book.options.get_bool("proofread.nb_spaces").unwrap() { + + if this.as_ref().book.options.get_bool("html.escape_nb_spaces").unwrap() { content = escape_nb_spaces(content); } Ok(content.into_owned()) diff --git a/src/lib/html_dir.rs b/src/lib/html_dir.rs index ec82636..b1a75be 100644 --- a/src/lib/html_dir.rs +++ b/src/lib/html_dir.rs @@ -279,8 +279,11 @@ impl<'a> HtmlDirRenderer<'a> { let template_css = try!(compile_str(try!(self.html.book.get_template("html.css")).as_ref(), &self.html.book.source, "could not compile template 'html.css")); - let data = try!(self.html.book.get_metadata(|s| Ok(s.to_owned()))) - .build(); + let mut data = try!(self.html.book.get_metadata(|s| Ok(s.to_owned()))); + if self.html.book.options.get_bool("proofread.nb_spaces").unwrap() { + data = data.insert_bool("display_spaces", true); + } + let data = data.build(); let mut res:Vec = vec!(); template_css.render_data(&mut res, &data); let css = String::from_utf8_lossy(&res); diff --git a/src/lib/html_single.rs b/src/lib/html_single.rs index 870dcf9..85f9d0e 100644 --- a/src/lib/html_single.rs +++ b/src/lib/html_single.rs @@ -163,9 +163,12 @@ impl<'a> HtmlSingleRenderer<'a> { let template_css = try!(compile_str(try!(self.html.book.get_template("html.css")).as_ref(), &self.html.book.source, "could not compile template 'html.css'")); - let data = try!(self.html.book.get_metadata(|s| self.render_vec(&try!(Parser::new().parse_inline(s))))) - .insert_bool(self.html.book.options.get_str("lang").unwrap(), true) - .build(); + let mut data = try!(self.html.book.get_metadata(|s| self.render_vec(&try!(Parser::new().parse_inline(s))))) + .insert_bool(self.html.book.options.get_str("lang").unwrap(), true); + if self.html.book.options.get_bool("proofread.nb_spaces").unwrap() { + data = data.insert_bool("display_spaces", true); + } + let data = data.build(); let mut res:Vec = vec!(); template_css.render_data(&mut res, &data); let css = String::from_utf8_lossy(&res); diff --git a/templates/epub/stylesheet.css b/templates/epub/stylesheet.css index 5f2c0aa..5326114 100644 --- a/templates/epub/stylesheet.css +++ b/templates/epub/stylesheet.css @@ -174,4 +174,21 @@ p.first-para { text-indent: 0; } - \ No newline at end of file +/* Use this for escape narrow space so it is non-breaking */ +.nnbsp { + white-space: nowrap; +} + +{{#display_spaces}} +.nnbsp { + background-color: #9999ff; +} + +.ensp { + background-color: #ff9999; +} + +.nbsp { + background-color: #ffff66; +} +{{/display_spaces}} \ No newline at end of file