Skip to content

Commit

Permalink
fix: added suggestions from PR
Browse files Browse the repository at this point in the history
escaped inline formatting, tests for inline formatting, documentation
minor grammar changes
  • Loading branch information
piragi committed Jan 10, 2022
1 parent 8d66522 commit c31ecee
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 93 deletions.
208 changes: 122 additions & 86 deletions src/backend/inline_formatting.rs
Original file line number Diff line number Diff line change
@@ -1,183 +1,211 @@
use std::{collections::VecDeque, fmt::Debug};

use pest::iterators::Pair;
use pest::Parser;

use crate::{
frontend::{
parser::{Rule},
}};
use crate::backend::UmError;
use crate::frontend::parser::{Rule, UnimarkupParser};

use super::Render;
/// [`Plain`] is one of the inline formatting types, which contains the raw text as String.
#[derive(Debug)]
pub struct Plain {
pub content: String
content: String,
}
/// [`Bold`] is one of the inline formatting types
#[derive(Debug)]
pub struct Bold {
pub content: VecDeque<FormatTypes>
content: VecDeque<FormatTypes>,
}
/// [`Italic`] is one of the inline formatting types.
#[derive(Debug)]
pub struct Italic {
pub content: VecDeque<FormatTypes>
content: VecDeque<FormatTypes>,
}
/// [`Subscript`] is one of the inline formatting types.
#[derive(Debug)]
pub struct Subscript {
pub content: VecDeque<FormatTypes>
content: VecDeque<FormatTypes>,
}
/// [`Superscript`] is one of the inline formatting types.
#[derive(Debug)]
pub struct Superscript {
pub content: VecDeque<FormatTypes>
content: VecDeque<FormatTypes>,
}
/// [`Verbatim`] is one of the inline formatting types.
#[derive(Debug)]
pub struct Verbatim {
pub content: String
}
#[derive(Debug)]
pub struct Raw {
pub content: String
content: String,
}
/// [`FormatTypes`] is an enum of all the inline formatting types.
#[derive(Debug)]
pub enum FormatTypes {
/// Represents the [`Bold`] FormatType
Bold(Bold),
/// Represents the [`Italic`] FormatType
Italic(Italic),
/// Represents the [`Subscript`] FormatType
Subscript(Subscript),
/// Represents the [`Superscript`] FormatType
Superscript(Superscript),
/// Represents the [`Verbatim`] FormatType
Verbatim(Verbatim),
/// Represents the [`Plain`] FormatType
Plain(Plain),
}

pub fn create_format_types(pair: Pair<Rule>) -> VecDeque<FormatTypes> {
get_nested_inline(pair)
/// [`parse_inline`] parses through the content of a [`UnimarkupBlock`] and returns a VecDeque of Formattypes
pub fn parse_inline(source: &str) -> Result<VecDeque<FormatTypes>, UmError> {
let mut rule_pairs =
UnimarkupParser::parse(Rule::inline_format, source).map_err(|err| UmError::General {
msg: String::from("Could not parse string!"),
error: Box::new(err),
})?;

let mut inline_format = VecDeque::<FormatTypes>::new();

println!("{:#?}", rule_pairs);

if let Some(inline) = rule_pairs.next() {
inline_format.append(&mut pair_into_format_types(inline));
}

Ok(inline_format)
}

fn get_nested_inline(pair: Pair<Rule>) -> VecDeque<FormatTypes> {
fn create_format_types(pair: Pair<Rule>) -> VecDeque<FormatTypes> {
let mut content: VecDeque<FormatTypes> = VecDeque::<FormatTypes>::new();

match pair.as_rule() {

Rule::text => {
let plain = Plain { content: pair.as_str().to_string(),};
Rule::plain => {
let plain = Plain {
content: pair.as_str().to_string(),
};
content.push_back(FormatTypes::Plain(plain));
},
Rule::italic => {
let inner = pair.into_inner();
let mut vector = VecDeque::new();

for pair in inner {
vector.append(&mut get_nested_inline(pair));
}
let italic = Italic{content: vector};
}
Rule::italic_inline => {
let italic = Italic {
content: pair_into_format_types(pair),
};
content.push_back(FormatTypes::Italic(italic));
},
Rule::subscript => {
let inner = pair.into_inner();
let mut vector = VecDeque::new();

for pair in inner {
vector.append(&mut get_nested_inline(pair));
}
let subscript = Subscript{content: vector};
}
Rule::subscript_inline => {
let subscript = Subscript {
content: pair_into_format_types(pair),
};
content.push_back(FormatTypes::Subscript(subscript));
},
Rule::superscript => {
let inner = pair.into_inner();
let mut vector = VecDeque::new();

for pair in inner {
vector.append(&mut get_nested_inline(pair));
}
let superscript = Superscript{content: vector};
}
Rule::superscript_inline => {
let superscript = Superscript {
content: pair_into_format_types(pair),
};
content.push_back(FormatTypes::Superscript(superscript));
},
Rule::bold => {
let inner = pair.into_inner();
let mut vector = VecDeque::new();

for pair in inner {
vector.append(&mut get_nested_inline(pair));
}
let bold = Bold{content: vector};
}
Rule::bold_inline => {
let bold = Bold {
content: pair_into_format_types(pair),
};
content.push_back(FormatTypes::Bold(bold));
},
Rule::verbatim => {
let verbatim = Verbatim{content: pair.into_inner().as_str().to_string(),};
}
Rule::verbatim_inline => {
let verbatim = Verbatim {
content: pair.into_inner().as_str().to_string(),
};
content.push_back(FormatTypes::Verbatim(verbatim));
},
_ => unreachable!("No other inline types allowed.")
}
_ => unreachable!("No other inline types allowed."),
}

content
}

fn pair_into_format_types(pair: Pair<Rule>) -> VecDeque<FormatTypes> {
pair.into_inner().flat_map(create_format_types).collect()
}

impl Render for Bold {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {

fn render_html(&self) -> Result<String, UmError> {
let mut html = String::default();
html.push_str("<b>");
for element in &self.content {
html.push_str(&element.render_html().expect("At least one or more formatting types expected"));
html.push_str(
&element
.render_html()
.expect("At least one or more formatting types expected"),
);
}
html.push_str("</b>");
Ok(html)
}
}

impl Render for Italic {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {

fn render_html(&self) -> Result<String, UmError> {
let mut html = String::default();
html.push_str("<i>");
for element in &self.content {
html.push_str(&element.render_html().expect("At least one or more formatting types expected"));
html.push_str(
&element
.render_html()
.expect("At least one or more formatting types expected"),
);
}
html.push_str("</i>");
Ok(html)
}
}

impl Render for Subscript {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {

fn render_html(&self) -> Result<String, UmError> {
let mut html = String::default();
html.push_str("<sub>");
for element in &self.content {
html.push_str(&element.render_html().expect("At least one or more formatting types expected"));
html.push_str(
&element
.render_html()
.expect("At least one or more formatting types expected"),
);
}
html.push_str("</sub>");
Ok(html)
}
}

impl Render for Superscript {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {

fn render_html(&self) -> Result<String, UmError> {
let mut html = String::default();
html.push_str("<sup>");
for element in &self.content {
html.push_str(&element.render_html().expect("At least one or more formatting types expected"));
html.push_str(
&element
.render_html()
.expect("At least one or more formatting types expected"),
);
}
html.push_str("</sup>");
Ok(html)
}
}

impl Render for Verbatim {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {

fn render_html(&self) -> Result<String, UmError> {
let mut html = String::default();
html.push_str("<pre>");
html.push_str(&self.content);
html.push_str("</pre>");
Ok(html)
}
}

impl Render for Plain {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {

let mut html = String::default();
html.push_str(&self.content);
Ok(html)
fn render_html(&self) -> Result<String, UmError> {
println!("{}", self.content);
Ok(self.content.clone())
}
}

impl Render for FormatTypes {
fn render_html(&self) -> Result<String, crate::um_error::UmError> {
fn render_html(&self) -> Result<String, UmError> {
match self {
FormatTypes::Bold(content) => content.render_html(),
FormatTypes::Italic(content) => content.render_html(),
Expand All @@ -189,9 +217,17 @@ impl Render for FormatTypes {
}
}

pub fn render_inline_umblocks(html: &mut String, inline_format:VecDeque<FormatTypes>) {
impl Render for VecDeque<FormatTypes> {
fn render_html(&self) -> Result<String, UmError> {
let mut html = String::default();

for element in inline_format {
html.push_str(&element.render_html().expect("Rendered format types expected"));
for element in self {
html.push_str(
&element
.render_html()
.expect("Rendered format types expected"),
);
}
Ok(html)
}
}
}
3 changes: 2 additions & 1 deletion src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ use log::info;
use rusqlite::Connection;

mod backend_error;
mod inline_formatting;
mod loader;
mod renderer;
pub(crate) mod inline_formatting;

pub use backend_error::BackendError;
pub use inline_formatting::*;
pub use loader::ParseFromIr;
pub use renderer::*;

Expand Down
4 changes: 3 additions & 1 deletion src/grammar/unimarkup.pest
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ headings = { heading+ }
paragraph = { ANY+ }

// ****** INLINE FORMATTING ******
plain = { (!(inline_delim) ~ ANY)+ }
escaped = { "\\" }
escaped_delim = @{ escaped ~ (italic_delim | subscript_delim | superscript_delim | verbatim_delim)}
plain = @{ ((escaped_delim) | (!(inline_delim) ~ ANY))+ }
inline_format = { (inline_block | plain)+ }
inline_block = _{ bold_inline | italic_inline | subscript_inline | superscript_inline | verbatim_inline }
inline_body = _{ (!(PEEK) ~ (inline_block | plain))+ }
Expand Down
29 changes: 29 additions & 0 deletions tests/backend/inline_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use unimarkup_rs::{backend::Render, um_elements::ParagraphBlock, um_error::UmError};

#[test]

fn escaped_inline() -> Result<(), UmError> {
let id = String::from("paragraph-id");
let content = String::from("\\*23\\*3");

let mut block = ParagraphBlock {
id: id.clone(),
content,
attributes: "{}".into(),
line_nr: 0,
};

let mut expected_html = format!("<p id='{}'>\\*23\\*3</p>", id);

assert_eq!(expected_html, block.render_html()?);

block.content = "\\ *italic*\\".to_string();
expected_html = format!("<p id='{}'>\\ <i>italic</i>\\</p>", id);
assert_eq!(expected_html, block.render_html()?);

block.content = "**\\*only bold\\***".to_string();
expected_html = format!("<p id='{}'><b>\\*only bold\\*</b></p>", id);
assert_eq!(expected_html, block.render_html()?);

Ok(())
}
5 changes: 0 additions & 5 deletions tests/test_files/frontend/inline_formatting.um

This file was deleted.

1 change: 1 addition & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ mod um_elements {

mod backend {
mod backend_run;
mod inline_tests;
}

0 comments on commit c31ecee

Please sign in to comment.