use super::core::parse_inline_text;
use crate::options::ParserOptions;
use crate::syntax::SyntaxKind;
use rowan::GreenNodeBuilder;
pub fn try_parse_strikeout(text: &str) -> Option<(usize, &str)> {
let bytes = text.as_bytes();
if bytes.len() < 4 || bytes[0] != b'~' || bytes[1] != b'~' {
return None;
}
if bytes.get(2) == Some(&b'~') {
return None;
}
let mut pos = 2;
let mut found_close = false;
while pos + 1 < bytes.len() {
if bytes[pos] == b'~' && bytes[pos + 1] == b'~' {
if pos + 2 < bytes.len() && bytes[pos + 2] == b'~' {
pos += 1;
continue;
}
found_close = true;
break;
}
pos += 1;
}
if !found_close {
return None;
}
let content = &text[2..pos];
if content.trim().is_empty() {
return None;
}
if content.starts_with(char::is_whitespace) || content.ends_with(char::is_whitespace) {
return None;
}
let total_len = pos + 2; Some((total_len, content))
}
pub fn emit_strikeout(builder: &mut GreenNodeBuilder, inner_text: &str, config: &ParserOptions) {
builder.start_node(SyntaxKind::STRIKEOUT.into());
builder.start_node(SyntaxKind::STRIKEOUT_MARKER.into());
builder.token(SyntaxKind::STRIKEOUT_MARKER.into(), "~~");
builder.finish_node();
parse_inline_text(builder, inner_text, config, false);
builder.start_node(SyntaxKind::STRIKEOUT_MARKER.into());
builder.token(SyntaxKind::STRIKEOUT_MARKER.into(), "~~");
builder.finish_node();
builder.finish_node();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple_strikeout() {
assert_eq!(try_parse_strikeout("~~hello~~"), Some((9, "hello")));
}
#[test]
fn test_strikeout_with_spaces() {
assert_eq!(
try_parse_strikeout("~~hello world~~"),
Some((15, "hello world"))
);
}
#[test]
fn test_no_whitespace_inside_delimiters() {
assert_eq!(try_parse_strikeout("~~ hello~~"), None);
assert_eq!(try_parse_strikeout("~~hello ~~"), None);
}
#[test]
fn test_empty_content() {
assert_eq!(try_parse_strikeout("~~~~"), None);
assert_eq!(try_parse_strikeout("~~ ~~"), None);
}
#[test]
fn test_not_enough_tildes() {
assert_eq!(try_parse_strikeout("~hello~"), None);
}
#[test]
fn test_too_many_tildes() {
assert_eq!(try_parse_strikeout("~~~hello~~~"), None);
}
#[test]
fn test_no_closing() {
assert_eq!(try_parse_strikeout("~~hello"), None);
assert_eq!(try_parse_strikeout("~~hello world"), None);
}
#[test]
fn test_strikeout_with_other_content_after() {
assert_eq!(try_parse_strikeout("~~hello~~ world"), Some((9, "hello")));
}
#[test]
fn test_strikeout_in_middle() {
assert_eq!(try_parse_strikeout("~~text~~"), Some((8, "text")));
}
}