diff options
| author | SavagePeanut <sourcehut@lazytapir.com> | 2023-09-03 20:40:20 -0500 |
|---|---|---|
| committer | SavagePeanut <sourcehut@lazytapir.com> | 2023-09-03 20:40:20 -0500 |
| commit | f4b6a50903ec6d82daf414a448e0175d79293efb (patch) | |
| tree | b00247bc04fcb1b6cde8fcdb7d98ebc97cef9123 /src | |
| parent | 788f64389f5479fcd23844740e7401a8a7870294 (diff) | |
fix newlines for matrix
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 8 | ||||
| -rw-r--r-- | src/matrix.rs | 68 | ||||
| -rw-r--r-- | src/telegram.rs | 2 |
3 files changed, 75 insertions, 3 deletions
@@ -3,7 +3,10 @@ use pyo3::prelude::*; mod parser; mod telegram; -use telegram::parse_for_telegram; +use telegram::format_for_telegram; + +mod matrix; +use matrix::format_for_matrix; mod general; use general::format_body; @@ -11,6 +14,7 @@ use general::format_body; #[pymodule] fn slidge_style_parser(_py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(format_body, m)?)?; - m.add_function(wrap_pyfunction!(parse_for_telegram, m)?)?; + m.add_function(wrap_pyfunction!(format_for_matrix, m)?)?; + m.add_function(wrap_pyfunction!(format_for_telegram, m)?)?; Ok(()) } diff --git a/src/matrix.rs b/src/matrix.rs new file mode 100644 index 0000000..92d2eb8 --- /dev/null +++ b/src/matrix.rs @@ -0,0 +1,68 @@ +use pyo3::prelude::*; + +use crate::parser::parse_with_limits; + +const MATRIX_FORMATS: &[(&'static str, (&'static str, &'static str))] = &[ + ("_", ("<em>", "</em>")), + ("*", ("<strong>", "</strong>")), + ("~", ("<strike>", "</strike>")), + ("`", ("<code>", "</code>")), + ("```", ("<pre><code>", "</code></pre>")), + ("```language", ("<pre><code class=\"language-{}\">", "</code></pre>")), + (">", ("<blockquote>", "</blockquote>")), + ("||", ("<span data-mx-spoiler>", "</span>")), +]; + +#[pyfunction] +pub fn format_for_matrix(body: String) -> PyResult<String> { + let mut chars: Vec<char> = body.chars().collect(); + if chars.len() < 1 { + return Ok(body); + } + let styles: Vec<(String, usize, usize, usize, usize)> = parse_with_limits(&chars, 0, chars.len() - 1, 0); + + let mut tags: Vec<(usize, String, usize)> = Vec::with_capacity(styles.len() * 2); + for (keyword, start, remove_start, end, remove_end) in styles { + if MATRIX_FORMATS.iter().any(|&(k, _)| k == keyword) { + let opening_tag = if keyword == "```language" { + MATRIX_FORMATS.iter().find(|&&(k, _)| k == keyword).unwrap().1.0.clone() + .replace("{}", &chars[start+3..remove_start-1] + .into_iter() + .collect::<String>()) + } else { + MATRIX_FORMATS.iter().find(|&&(k, _)| k == keyword).unwrap().1.0.clone().to_string() + }; + tags.push((start, opening_tag, remove_start)); + tags.push((end, MATRIX_FORMATS.iter().find(|&&(k, _)| k == keyword).unwrap().1.1.clone().to_string(), remove_end)); + } else if keyword == ">>" || keyword == "```>" || keyword == "\\" { + tags.push((start, "".to_string(), start+1)); + } + } + + tags.sort_by(|a, b| b.0.cmp(&a.0)); + + let mut replace_newlines_to = chars.len(); + for (index, tag, end) in tags { + if tag == "</code></pre>" { + // index is at \n, add 1 to skip that one + let substring = chars[index + 1..replace_newlines_to].into_iter().collect::<String>(); + chars = [&chars[..index + 1], &substring.replace('\n', "<br>").chars().collect::<Vec<char>>()[..]].concat(); + } else if tag == "<pre><code>" { + replace_newlines_to = index; + } + + let tag: Vec<char> = tag.chars().collect(); + chars = [chars[..index].to_vec(), tag.clone(), chars[end..].to_vec()].concat(); + + let offset: isize = index as isize - end as isize + tag.len() as isize; + replace_newlines_to = if offset > 0 { + replace_newlines_to + offset as usize + } else { + replace_newlines_to - offset.abs() as usize + }; + } + let substring = chars[..replace_newlines_to].into_iter().collect::<String>(); + let text = [substring.replace('\n', "<br>"), chars[replace_newlines_to..].into_iter().collect::<String>()].concat(); + + Ok(text) +} diff --git a/src/telegram.rs b/src/telegram.rs index 0774143..b215885 100644 --- a/src/telegram.rs +++ b/src/telegram.rs @@ -15,7 +15,7 @@ const TELEGRAM_STYLES: &[(&'static str, &'static str)] = &[ ]; #[pyfunction] -pub fn parse_for_telegram(body: String) -> PyResult<(String, Vec<(String, usize, usize, String)>)> { +pub fn format_for_telegram(body: String) -> PyResult<(String, Vec<(String, usize, usize, String)>)> { let mut chars: Vec<char> = body.chars().collect(); if chars.len() < 1 { return Ok((body, Vec::with_capacity(0))); |
