diff --git a/specs/rtjson.spec b/specs/rtjson.spec index a9f3dc40..1d0020b7 100644 --- a/specs/rtjson.spec +++ b/specs/rtjson.spec @@ -35,15 +35,17 @@ This post has a paragraph in the middle. // TODO: This utilizes one of the breaks. ```````````````````````````````` example ->Line proceeding; this line has a [link](https://reddit.com) and a r/redditlink +>Line proceeding; this line has a [link](https://reddit.com) and a r/redditlink. +> >Line preceding; no line proceeding > >No line preceding; no line proceeding > ->No line preceding; line proceeding +>No line preceding; line proceeding +> >Line preceding . -{"document":[{"e":"blockquote","c":[{"e":"par","c":[{"e":"text","t":"Line proceeding; this line has a "},{"e":"link","u":"https://reddit.com","t":"link"},{"e":"text","t":" and a "},{"e":"link","u":"/r/redditlink","t":"r/redditlink"},{"e":"br"},{"e":"text","t":"Line preceding; no line proceeding"}]},{"e":"par","c":[{"e":"text","t":"No line preceding; no line proceeding"}]},{"e":"par","c":[{"e":"br"},{"e":"text","t":"No line preceding; line proceedingLine preceding"}]}]}]}```````````````````````````````` +{"document":[{"e":"blockquote","c":[{"e":"par","c":[{"e":"text","t":"Line proceeding; this line has a "},{"e":"link","u":"https://reddit.com","t":"link"},{"e":"text","t":" and a "},{"e":"link","u":"/r/redditlink","t":"r/redditlink"},{"e":"text","t":"."}]},{"e":"par","c":[{"e":"text","t":"Line preceding; no line proceeding"}]},{"e":"par","c":[{"e":"text","t":"No line preceding; no line proceeding"}]},{"e":"par","c":[{"e":"text","t":"No line preceding; line proceeding"}]},{"e":"par","c":[{"e":"text","t":"Line preceding"}]}]}]}```````````````````````````````` ```````````````````````````````` example >This post ends with a blockquote\n\nwith embedded newlines. @@ -53,7 +55,7 @@ This post has a paragraph in the middle. ```````````````````````````````` example Hello, **this is bold**, *this is italic*, ***this is both***. And this is a u/username and a r/subreddit. . -{"document":[{"e":"par","c":[{"e":"text","t":"Hello, this is bold, this is italic, this is both. And this is a ","f":[[1, 7, 12], [2, 21, 14], [3, 37, 12], [2, 49, 16]]},{"e":"link","u":"/u/username","t":"u/username"},{"e":"text","t":" and a "},{"e":"link","u":"/r/subreddit","t":"r/subreddit"},{"e":"text","t":"."}]}]}```````````````````````````````` +{"document":[{"e":"par","c":[{"e":"text","t":"Hello, this is bold, this is italic, this is both. And this is a ","f":[[1, 7, 12], [2, 21, 14], [3, 37, 12]]},{"e":"link","u":"/u/username","t":"u/username"},{"e":"text","t":" and a "},{"e":"link","u":"/r/subreddit","t":"r/subreddit"},{"e":"text","t":"."}]}]}```````````````````````````````` ```````````````````````````````` example Below this is a list: @@ -79,9 +81,9 @@ Above this is a list. ```````````````````````````````` example |Col 1|Col 2|Col 3| |:-|:-:|-:| -|a |**bold*****bold+italic****italic*|a | +|a |**bold**​***bold+italic***​*italic*|a | . -{"document":[{"e":"table","h":[[{"a":"L","e":"text","t":"Col 1"},{"a":"C","e":"text","t":"Col 2"},{"a":"R","e":"text","t":"Col 3"}]],"c":[,[{"c":[{"e":"text","t":"a"}]},{"c":[{"e":"text","t":"boldbold+italic**italic","f":[[1, 0, 4], [3, 4, 11], [2, 15, 8]]}]},{"c":[{"e":"text","t":"a"}]}]]}]}```````````````````````````````` +{"document":[{"e":"table","h":[{"a":"L","c":[{"e":"text","t":"Col 1"}]},{"a":"C","c":[{"e":"text","t":"Col 2"}]},{"a":"R","c":[{"e":"text","t":"Col 3"}]}],"c":[[{"c":[{"e":"text","t":"a"}]},{"c":[{"e":"text","t":"bold​bold+italic​italic","f":[[1, 0, 4], [3, 7, 11], [2, 21, 6]]}]},{"c":[{"e":"text","t":"a"}]}]]}]}```````````````````````````````` ```````````````````````````````` example These are two tables: @@ -94,7 +96,7 @@ These are two tables: |:-|:-| |c1:r2|c2:r2| . -{"document":[{"e":"par","c":[{"e":"text","t":"These are two tables:"}]},{"e":"table","h":[[{"a":"L","e":"text","t":"Table"},{"a":"L","e":"text","t":"1"}]],"c":[,[{"c":[{"e":"text","t":"c1:r1"}]},{"c":[{"e":"text","t":"c2:r1"}]}]]},{"e":"table","h":[[{"a":"L","e":"text","t":"Table"},{"a":"L","e":"text","t":"2"}]],"c":[,[{"c":[{"e":"text","t":"c1:r2"}]},{"c":[{"e":"text","t":"c2:r2"}]}]]}]}```````````````````````````````` +{"document":[{"e":"par","c":[{"e":"text","t":"These are two tables:"}]},{"e":"table","h":[{"a":"L","c":[{"e":"text","t":"Table"}]},{"a":"L","c":[{"e":"text","t":"1"}]}],"c":[[{"c":[{"e":"text","t":"c1:r1"}]},{"c":[{"e":"text","t":"c2:r1"}]}]]},{"e":"table","h":[{"a":"L","c":[{"e":"text","t":"Table"}]},{"a":"L","c":[{"e":"text","t":"2"}]}],"c":[[{"c":[{"e":"text","t":"c1:r2"}]},{"c":[{"e":"text","t":"c2:r2"}]}]]}]}```````````````````````````````` ```````````````````````````````` example Hello reddit, \*\***this should be bold,**\*\* the stars around it should not be. @@ -154,3 +156,12 @@ www.thisisalink.com } . {"document":[{"e":"code","c":[{"e":"raw","t":"function test() {"},{"e":"raw","t":" console.log("notice the blank line before this function?");"},{"e":"raw","t":"}"},{"e":"raw","t":""}]}]}```````````````````````````````` + +Say I have many formats nested in one format range. We would want to keep that +overall format through the whole thing, while also getting rid of the old format +each time we went on. + +```````````````````````````````` example +*__bold__ ~underline~ ~~strikethrough~~* +. +{"document":[{"e":"par","c":[{"e":"text","t":"bold underline strikethrough","f":[[3, 0, 4], [2, 4, 1], [6, 5, 9], [2, 14, 1], [10, 15, 13]]}]}]}```````````````````````````````` diff --git a/src/lib.rs b/src/lib.rs index ff8e270d..13e56ace 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,9 +103,6 @@ extern crate libc; #[macro_use] extern crate cpython; use cpython::{PyResult, Python}; -use libc::c_char; -use std::ffi::{CStr, CString}; -use nodes::AstNode; /// Render Markdown to HTML. /// diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5ae2097f..bf0633d7 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1208,16 +1208,6 @@ impl<'a, 'o> Parser<'a, 'o> { format_ranges.push(new_range); } unformatted_text.push_str(text); - if node.same_node(node.parent().unwrap().last_child().unwrap()){ - match node.parent().unwrap().data.borrow().value { - NodeValue::Strong => *current_format -= 1, - NodeValue::Emph => *current_format -= 2, - NodeValue::Underline => *current_format -= 4, - NodeValue::Strikethrough => *current_format -= 8, - NodeValue::Superscript => *current_format -= 32, - _ => () - } - } }, NodeValue::Link(_) => { if !unformatted_text.is_empty() { @@ -1264,6 +1254,15 @@ impl<'a, 'o> Parser<'a, 'o> { format_ranges ); } + + match node.data.borrow().value { + NodeValue::Strong => *current_format -= 1, + NodeValue::Emph => *current_format -= 2, + NodeValue::Underline => *current_format -= 4, + NodeValue::Strikethrough => *current_format -= 8, + NodeValue::Superscript => *current_format -= 32, + _ => () + } if node.data.borrow_mut().value.contains_inlines() { match node.data.borrow_mut().value { diff --git a/src/rtjson.rs b/src/rtjson.rs index 7b2faf02..4aa53d5b 100644 --- a/src/rtjson.rs +++ b/src/rtjson.rs @@ -200,11 +200,7 @@ impl<'o> RTJsonFormatter<'o> { } NodeValue::HtmlBlock(_) => unreachable!(), NodeValue::ThematicBreak | NodeValue::LineBreak | - NodeValue:: SoftBreak => { - if entering { - self.s += r#"{"e":"br"}"# - } - } + NodeValue:: SoftBreak => (), NodeValue::Code(_) => { if entering { self.s += r#"{"e":"error code"}"#; @@ -231,7 +227,7 @@ impl<'o> RTJsonFormatter<'o> { NodeValue::Image(_) => self.s += self.escape(literal).as_str(), NodeValue::Text(ref literal) | NodeValue::Code(ref literal) => self.s += self.escape(literal).as_str(), - NodeValue::LineBreak | NodeValue::SoftBreak | NodeValue::ThematicBreak => self.s += r#"{"e":"br"},"#, + NodeValue::LineBreak | NodeValue::SoftBreak | NodeValue::ThematicBreak => (), NodeValue::Heading(_) | NodeValue::CodeBlock(_) => { self.s += format!(r#"{{"e":"raw","t":"{}"}}"#, self.escape(literal)).as_str(); } @@ -239,16 +235,7 @@ impl<'o> RTJsonFormatter<'o> { self.s += format!(r#"{{"e":"text","t":"{}"}}"#, self.escape(literal)).as_str(); } NodeValue::TableCell => { - let row = &node.parent().unwrap().parent().unwrap().data.borrow().value; - let in_header = match *row { - NodeValue::TableRow(header) => header, - _ => panic!(), - }; - if in_header { - self.s += format!( r#""e":"text","t":"{}"}}"#, self.escape(literal)).as_str(); - } else { - self.s += format!( r#"{{"e":"text","t":"{}"}}"#, self.escape(literal)).as_str(); - } + self.s += format!( r#"{{"e":"text","t":"{}"}}"#, self.escape(literal)).as_str(); } NodeValue::Document | NodeValue::Strong | NodeValue::Emph | NodeValue::Underline | NodeValue::Superscript | @@ -264,22 +251,13 @@ impl<'o> RTJsonFormatter<'o> { if entering { match node.parent().unwrap().data.borrow().value { NodeValue::TableCell => { - let row = &node.parent().unwrap().parent().unwrap().data.borrow().value; - let in_header = match *row { - NodeValue::TableRow(header) => header, - _ => panic!(), - }; - if in_header { - self.s += format!( r#""e":"text","t":"{}","f":{:?}}}"#, self.escape(literal), format_ranges).as_str(); - } else { - self.s += format!( r#"{{"e":"text","t":"{}","f":{:?}}}"#, self.escape(literal), format_ranges).as_str(); - } + self.s += format!( r#"{{"e":"text","t":"{}","f":{:?}}}"#, self.escape(literal), format_ranges).as_str(); }, NodeValue::Link(_) => self.s += self.escape(literal).as_str(), NodeValue::Image(_) => self.s += self.escape(literal).as_str(), NodeValue::Text(ref literal) | NodeValue::Code(ref literal) => self.s += self.escape(literal).as_str(), - NodeValue::LineBreak | NodeValue::SoftBreak | NodeValue::ThematicBreak => self.s += r#"{"e":"br"},"#, + NodeValue::LineBreak | NodeValue::SoftBreak | NodeValue::ThematicBreak => (), NodeValue::Heading(_) | NodeValue::CodeBlock(_) => { self.s += format!(r#"{{"e":"raw","t":"{}"}}"#, self.escape(literal)).as_str(); }, @@ -311,18 +289,11 @@ impl<'o> RTJsonFormatter<'o> { self.s += format!(r#"{{"e":"link","u":"{}","t":"{}"}}"#, self.escape_href(&nl.url), self.escape(&nl.title)).as_str(); } } - NodeValue::Link(ref nl) => { - if entering { - self.s += format!(r#"{{"e":"link","u":"{}","t":"{}"}}"#, self.escape_href(&nl.url), self.escape(&nl.title)).as_str(); - self.append_comma(node); - } - } NodeValue::Image(ref nl) => { if entering { self.s += format!(r#"{{"e":"link","u":"{}","t":""#, self.escape_href(&nl.url)).as_str(); } else { self.s += r#""}"#; - self.append_comma(node); } } NodeValue::Table(..) => { @@ -341,15 +312,16 @@ impl<'o> RTJsonFormatter<'o> { if entering { if header { self.s += r#""h":["#; + } else { + self.s += "["; } - self.s += "["; } else { self.s += "]"; if node.next_sibling().is_some() && !header { self.s += ","; } if header { - self.s += "],"; + self.s += ","; self.s += r#""c":["#; } } @@ -382,8 +354,8 @@ impl<'o> RTJsonFormatter<'o> { start = start.next_sibling().unwrap(); } + self.s += "{"; if in_header { - self.s += "{"; match alignments[i] { TableAlignment::Left => self.s += r#""a":"L","#, @@ -391,17 +363,24 @@ impl<'o> RTJsonFormatter<'o> { TableAlignment::Center => self.s += r#""a":"C","#, TableAlignment::None => (), } - } else { - self.s += r#"{"c":["#; } - - } else if !in_header { + + self.s += r#""c":["#; + } else { self.s += "]}"; } } } - if !entering { - self.append_comma(node); + + match node.data.borrow().value { + NodeValue::TableRow(..) | + NodeValue::LineBreak | NodeValue::SoftBreak | + NodeValue::ThematicBreak => (), + _ => { + if !entering { + self.append_comma(node); + } + } } false } diff --git a/src/scanners.rs b/src/scanners.rs index bd4305fa..55a853da 100644 --- a/src/scanners.rs +++ b/src/scanners.rs @@ -118,10 +118,6 @@ lazy_static! { static ref ATTRIBUTE: String = format!( r"(?:{}+{}{}?)", *SPACE_CHAR, *ATTRIBUTE_NAME, *ATTRIBUTE_VALUE_SPEC); static ref OPEN_TAG: String = format!(r"(?:{}{}*{}*/?>)", *TAG_NAME, *ATTRIBUTE, *SPACE_CHAR); - static ref HTML_COMMENT: &'static str = r"(?:!---->|!---?[^\x00>-](-?[^\x00-])*-->)"; - static ref PROCESSING_INSTRUCTION: &'static str = r"\?([^?>\x00]+|\?[^>\x00]|>)*\?>"; - static ref DECLARATION: String = format!(r"![A-Z]+{}+[^>\x00]*>", *SPACE_CHAR); - static ref CDATA: &'static str = r"!\[CDATA\[([^\]\x00]+|\][^\]\x00]|\]\][^>\x00])*\]\]>"; } pub fn html_block_start_7(line: &str) -> Option {