From cfc02b8da77903b091b79d79473c0b2282ad310b Mon Sep 17 00:00:00 2001 From: trivernis Date: Mon, 1 Jun 2020 17:42:48 +0200 Subject: [PATCH] Add centered text --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 8 +++++++ src/format/assets/style.css | 4 ++++ src/format/html.rs | 9 +++++++- src/parsing/elements.rs | 6 +++++ src/parsing/parser.rs | 44 ++++++++++++++++++++++++++++++------- src/parsing/tokens.rs | 6 +++-- 8 files changed, 68 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8af28e4..21c3f1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "snekdown" -version = "0.6.0" +version = "0.7.0" dependencies = [ "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 54be35d..6a28e19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "snekdown" -version = "0.6.0" +version = "0.7.0" authors = ["trivernis "] edition = "2018" license-file = "LICENSE" diff --git a/README.md b/README.md index 328e3aa..f72e3e5 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Header with rows ### Placeholders Placeholders can be used to insert special elements in a specific place. +Placeholders are always case insensitive. ```md Insert the table of contents @@ -138,4 +139,11 @@ Set the source of a quote Set options for placeholders [[toc]][ordered] +``` + +### Centered Text + +``` +|| These two lines +|| are centered ``` \ No newline at end of file diff --git a/src/format/assets/style.css b/src/format/assets/style.css index 14af537..bde8b94 100644 --- a/src/format/assets/style.css +++ b/src/format/assets/style.css @@ -116,4 +116,8 @@ blockquote { display: block; color: #444; font-style: italic; +} + +.centered { + text-align: center; } \ No newline at end of file diff --git a/src/format/html.rs b/src/format/html.rs index 9faff09..2f9a820 100644 --- a/src/format/html.rs +++ b/src/format/html.rs @@ -36,6 +36,7 @@ impl ToHtml for Line { Line::Text(text) => text.to_html(), Line::Ruler(ruler) => ruler.to_html(), Line::Anchor(anchor) => anchor.to_html(), + Line::Centered(centered) => centered.to_html(), } } } @@ -147,7 +148,7 @@ impl ToHtml for Paragraph { .elements .iter() .fold("".to_string(), |a, b| combine_with_lb!(a, b)); - format!("

{}

", inner) + format!("
{}
", inner) } } @@ -414,3 +415,9 @@ impl ToHtml for InlineMetadata { } } } + +impl ToHtml for Centered { + fn to_html(&self) -> String { + format!("
{}
", self.line.to_html()) + } +} diff --git a/src/parsing/elements.rs b/src/parsing/elements.rs index 3c88c3a..66809ba 100644 --- a/src/parsing/elements.rs +++ b/src/parsing/elements.rs @@ -57,6 +57,7 @@ pub enum Line { Text(TextLine), Ruler(Ruler), Anchor(Anchor), + Centered(Centered), } #[derive(Clone, Debug)] @@ -220,6 +221,11 @@ pub struct Anchor { pub(crate) reference: String, } +#[derive(Clone, Debug)] +pub struct Centered { + pub(crate) line: TextLine, +} + // implementations impl Document { diff --git a/src/parsing/parser.rs b/src/parsing/parser.rs index af4451d..110206e 100644 --- a/src/parsing/parser.rs +++ b/src/parsing/parser.rs @@ -650,7 +650,6 @@ impl Parser { self.seek_whitespace(); while let Ok(row) = self.parse_row() { table.add_row(row); - self.seek_whitespace(); } Ok(table) @@ -662,23 +661,39 @@ impl Parser { self.seek_inline_whitespace(); self.assert_special(&PIPE, start_index)?; self.skip_char(); + if self.check_special(&PIPE) { + return Err(self.revert_with_error(start_index)); + } self.inline_break_at.push(PIPE); self.seek_inline_whitespace(); let mut row = Row::new(); - while let Ok(element) = self.parse_line() { - row.add_cell(Cell { text: element }); - if self.check_special(&PIPE) { - if self.next_char() == None { + loop { + let mut element = TextLine::new(); + while let Ok(inline) = self.parse_inline() { + element.subtext.push(inline); + if self.check_linebreak() || self.check_special(&PIPE) { break; } } + row.add_cell(Cell { + text: Line::Text(element), + }); + if self.check_special(&PIPE) { + self.skip_char(); + } if self.check_linebreak() { break; } self.seek_inline_whitespace(); } self.inline_break_at.clear(); + if self.check_special(&PIPE) { + self.skip_char(); + self.skip_char(); + } else { + self.skip_char(); + } if row.cells.len() > 0 { Ok(row) @@ -693,14 +708,27 @@ impl Parser { Err(ParseError::new(self.index)) } else { if let Ok(ruler) = self.parse_ruler() { - return Ok(Line::Ruler(ruler)); + Ok(Line::Ruler(ruler)) + } else if let Ok(centered) = self.parse_centered() { + Ok(Line::Centered(centered)) } else if let Ok(text) = self.parse_text_line() { - return Ok(Line::Text(text)); + Ok(Line::Text(text)) + } else { + Err(ParseError::new(self.index)) } - return Err(ParseError::new(self.index)); } } + /// parses centered text + fn parse_centered(&mut self) -> Result { + let start_index = self.index; + self.assert_special_sequence(&SQ_CENTERED_START, start_index)?; + self.skip_char(); + let line = self.parse_text_line()?; + + Ok(Centered { line }) + } + /// parses a placeholder element pub(crate) fn parse_placeholder(&mut self) -> Result>, ParseError> { let start_index = self.index; diff --git a/src/parsing/tokens.rs b/src/parsing/tokens.rs index c0ef6d1..8772651 100644 --- a/src/parsing/tokens.rs +++ b/src/parsing/tokens.rs @@ -52,15 +52,16 @@ pub(crate) const BOLD: [char; 2] = [ASTERISK, ASTERISK]; pub(crate) const QUOTES: [char; 2] = [SINGLE_QUOTE, DOUBLE_QUOTE]; -pub(crate) const BLOCK_SPECIAL_CHARS: [&[char]; 8] = [ +pub(crate) const BLOCK_SPECIAL_CHARS: [&[char]; 9] = [ &[HASH], &[HASH, META_OPEN], &[MINUS, SPACE], - &[BACKTICK, BACKTICK, BACKTICK], + &SQ_CODE_BLOCK, &[PIPE], &[QUOTE_START], &[META_OPEN], &[IMPORT_START, IMPORT_OPEN], + &SQ_CENTERED_START, ]; pub(crate) const INLINE_SPECIAL_CHARS: [char; 8] = [ @@ -77,6 +78,7 @@ pub(crate) const SQ_CODE_BLOCK: [char; 3] = [BACKTICK, BACKTICK, BACKTICK]; pub(crate) const SQ_RULER: [char; 5] = [MINUS, SPACE, MINUS, SPACE, MINUS]; pub(crate) const SQ_PHOLDER_START: [char; 2] = [PHOLDER_OPEN, PHOLDER_OPEN]; pub(crate) const SQ_PHOLDER_STOP: [char; 2] = [PHOLDER_CLOSE, PHOLDER_CLOSE]; +pub(crate) const SQ_CENTERED_START: [char; 2] = [PIPE, PIPE]; // expressions