From ead1969a7cbfe8022c13cc2677c22780424b5f98 Mon Sep 17 00:00:00 2001 From: kellda <59569234+kellda@users.noreply.github.com> Date: Sun, 7 Jun 2020 07:52:30 +0000 Subject: [PATCH 1/2] Rename code blocks to ignore block This way structs / functions names still sinificant if we ignore commands in other blocks (e.g. quotes) --- parser/src/command.rs | 12 ++-- parser/src/{code_block.rs => ignore_block.rs} | 68 ++++++++++--------- parser/src/lib.rs | 2 +- parser/src/mentions.rs | 6 +- 4 files changed, 46 insertions(+), 42 deletions(-) rename parser/src/{code_block.rs => ignore_block.rs} (55%) diff --git a/parser/src/command.rs b/parser/src/command.rs index 7edde0f60..5ee4f1a07 100644 --- a/parser/src/command.rs +++ b/parser/src/command.rs @@ -1,5 +1,5 @@ -use crate::code_block::ColorCodeBlocks; use crate::error::Error; +use crate::ignore_block::IgnoreBlocks; use crate::token::{Token, Tokenizer}; pub mod assign; @@ -33,7 +33,7 @@ pub enum Command<'a> { pub struct Input<'a> { all: &'a str, parsed: usize, - code: ColorCodeBlocks, + ignore: IgnoreBlocks, // A list of possible bot names. bot: Vec<&'a str>, @@ -64,7 +64,7 @@ impl<'a> Input<'a> { Input { all: input, parsed: 0, - code: ColorCodeBlocks::new(input), + ignore: IgnoreBlocks::new(input), bot, } } @@ -141,11 +141,11 @@ impl<'a> Input<'a> { } if self - .code - .overlaps_code((self.parsed)..(self.parsed + tok.position())) + .ignore + .overlaps_ignore((self.parsed)..(self.parsed + tok.position())) .is_some() { - log::info!("command overlaps code; code: {:?}", self.code); + log::info!("command overlaps ignored block; ignore: {:?}", self.ignore); return None; } diff --git a/parser/src/code_block.rs b/parser/src/ignore_block.rs similarity index 55% rename from parser/src/code_block.rs rename to parser/src/ignore_block.rs index d9732bcda..48fa22579 100644 --- a/parser/src/code_block.rs +++ b/parser/src/ignore_block.rs @@ -2,36 +2,36 @@ use pulldown_cmark::{Event, Parser, Tag}; use std::ops::Range; #[derive(Debug)] -pub struct ColorCodeBlocks { - code: Vec>, +pub struct IgnoreBlocks { + ignore: Vec>, } -impl ColorCodeBlocks { - pub fn new(s: &str) -> ColorCodeBlocks { - let mut code = Vec::new(); +impl IgnoreBlocks { + pub fn new(s: &str) -> IgnoreBlocks { + let mut ignore = Vec::new(); let mut parser = Parser::new(s).into_offset_iter(); while let Some((event, range)) = parser.next() { if let Event::Start(Tag::CodeBlock(_)) = event { let start = range.start; while let Some((event, range)) = parser.next() { if let Event::End(Tag::CodeBlock(_)) = event { - code.push(start..range.end); + ignore.push(start..range.end); break; } } } else if let Event::Code(_) = event { - code.push(range); + ignore.push(range); } } - ColorCodeBlocks { code } + IgnoreBlocks { ignore } } - pub fn overlaps_code(&self, region: Range) -> Option> { - for code in &self.code { + pub fn overlaps_ignore(&self, region: Range) -> Option> { + for ignore in &self.ignore { // See https://stackoverflow.com/questions/3269434. - if code.start <= region.end && region.start <= code.end { - return Some(code.clone()); + if ignore.start <= region.end && region.start <= ignore.end { + return Some(ignore.clone()); } } None @@ -40,27 +40,27 @@ impl ColorCodeBlocks { #[cfg(test)] #[derive(Debug, PartialEq, Eq)] -enum Code<'a> { +enum Ignore<'a> { Yes(&'a str), No(&'a str), } #[cfg(test)] -fn bodies(s: &str) -> Vec> { +fn bodies(s: &str) -> Vec> { let mut bodies = Vec::new(); - let cbs = ColorCodeBlocks::new(s); + let cbs = IgnoreBlocks::new(s); let mut previous = 0..0; - for range in &cbs.code { + for range in &cbs.ignore { let range = range.clone(); if previous.end != range.start { - bodies.push(Code::No(&s[previous.end..range.start])); + bodies.push(Ignore::No(&s[previous.end..range.start])); } - bodies.push(Code::Yes(&s[range.clone()])); + bodies.push(Ignore::Yes(&s[range.clone()])); previous = range.clone(); } - if let Some(range) = cbs.code.last() { + if let Some(range) = cbs.ignore.last() { if range.end != s.len() { - bodies.push(Code::No(&s[range.end..])); + bodies.push(Ignore::No(&s[range.end..])); } } bodies @@ -70,7 +70,7 @@ fn bodies(s: &str) -> Vec> { fn cbs_1() { assert_eq!( bodies("`hey you`bar me too"), - [Code::Yes("`hey you`"), Code::No("bar me too")] + [Ignore::Yes("`hey you`"), Ignore::No("bar me too")] ); } @@ -78,7 +78,7 @@ fn cbs_1() { fn cbs_2() { assert_eq!( bodies("`hey you` me too"), - [Code::Yes("`hey you`"), Code::No(" me too")] + [Ignore::Yes("`hey you`"), Ignore::No(" me too")] ); } @@ -86,7 +86,7 @@ fn cbs_2() { fn cbs_3() { assert_eq!( bodies(r"`hey you\` `me too"), - [Code::Yes(r"`hey you\`"), Code::No(" `me too")] + [Ignore::Yes(r"`hey you\`"), Ignore::No(" `me too")] ); } @@ -103,9 +103,9 @@ nope " ), [ - Code::No("\n"), - Code::Yes("```language_spec\ntesting\n```"), - Code::No("\n\nnope\n") + Ignore::No("\n"), + Ignore::Yes("```language_spec\ntesting\n```"), + Ignore::No("\n\nnope\n") ], ); } @@ -121,8 +121,8 @@ testing " " )), [ - Code::No("\n"), - Code::Yes("``` tag_after_space\ntesting\n``` "), + Ignore::No("\n"), + Ignore::Yes("``` tag_after_space\ntesting\n``` "), ], ); } @@ -137,8 +137,8 @@ fn cbs_6() { " ), [ - Code::No("\n "), - Code::Yes("this is indented\n this is indented too\n"), + Ignore::No("\n "), + Ignore::Yes("this is indented\n this is indented too\n"), ], ); } @@ -152,7 +152,7 @@ fn cbs_7() { testing unclosed " ), - [Code::No("\n"), Code::Yes("```\ntesting unclosed\n"),], + [Ignore::No("\n"), Ignore::Yes("```\ntesting unclosed\n"),], ); } @@ -160,6 +160,10 @@ testing unclosed fn cbs_8() { assert_eq!( bodies("`one` not `two`"), - [Code::Yes("`one`"), Code::No(" not "), Code::Yes("`two`")] + [ + Ignore::Yes("`one`"), + Ignore::No(" not "), + Ignore::Yes("`two`") + ] ); } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index fda2ffd67..b7fae2668 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -1,6 +1,6 @@ -mod code_block; pub mod command; pub mod error; +mod ignore_block; mod mentions; mod token; diff --git a/parser/src/mentions.rs b/parser/src/mentions.rs index 95d81d18a..ab0a15500 100644 --- a/parser/src/mentions.rs +++ b/parser/src/mentions.rs @@ -6,7 +6,7 @@ /// /// Note that the `@` is skipped in the final output. pub fn get_mentions(input: &str) -> Vec<&str> { - let code_regions = crate::code_block::ColorCodeBlocks::new(input); + let ignore_regions = crate::ignore_block::IgnoreBlocks::new(input); let mut mentions = Vec::new(); for (idx, _) in input.match_indices('@') { @@ -41,8 +41,8 @@ pub fn get_mentions(input: &str) -> Vec<&str> { if username.is_empty() { continue; } - if code_regions - .overlaps_code(idx..idx + username.len()) + if ignore_regions + .overlaps_ignore(idx..idx + username.len()) .is_some() { continue; From 9c0bbc4506f4389d2cca1f6e9dafd85cd2ee7c09 Mon Sep 17 00:00:00 2001 From: kellda <59569234+kellda@users.noreply.github.com> Date: Mon, 13 Sep 2021 16:32:55 +0000 Subject: [PATCH 2/2] Ignore commands in citations --- parser/src/ignore_block.rs | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/parser/src/ignore_block.rs b/parser/src/ignore_block.rs index 48fa22579..250273e42 100644 --- a/parser/src/ignore_block.rs +++ b/parser/src/ignore_block.rs @@ -19,6 +19,20 @@ impl IgnoreBlocks { break; } } + } else if let Event::Start(Tag::BlockQuote) = event { + let start = range.start; + let mut count = 1; + while let Some((event, range)) = parser.next() { + if let Event::Start(Tag::BlockQuote) = event { + count += 1; + } else if let Event::End(Tag::BlockQuote) = event { + count -= 1; + if count == 0 { + ignore.push(start..range.end); + break; + } + } + } } else if let Event::Code(_) = event { ignore.push(range); } @@ -167,3 +181,61 @@ fn cbs_8() { ] ); } + +#[test] +fn cbs_9() { + assert_eq!( + bodies( + " +some text +> testing citations +still in citation + +more text +" + ), + [ + Ignore::No("\nsome text\n"), + Ignore::Yes("> testing citations\nstill in citation\n"), + Ignore::No("\nmore text\n") + ], + ); +} + +#[test] +fn cbs_10() { + assert_eq!( + bodies( + " +# abc + +> multiline +> citation + +lorem ipsum +" + ), + [ + Ignore::No("\n# abc\n\n"), + Ignore::Yes("> multiline\n> citation\n"), + Ignore::No("\nlorem ipsum\n") + ], + ); +} + +#[test] +fn cbs_11() { + assert_eq!( + bodies( + " +> some +> > nested +> citations +" + ), + [ + Ignore::No("\n"), + Ignore::Yes("> some\n> > nested\n> citations\n"), + ], + ); +}