From: Max Value Date: Sun, 18 May 2025 14:19:43 +0000 (+0100) Subject: Fixed subtract overflow bugs X-Git-Url: https://git.ozva.co.uk/?a=commitdiff_plain;ds=sidebyside;p=gn-parser Fixed subtract overflow bugs ~ fixed name list inline render bug --- diff --git a/Cargo.toml b/Cargo.toml index 9aa00a2..5785fa7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,5 @@ edition = "2021" [dependencies] chrono = "0.4.41" -regex = "1" +regex = "1.11" serde_json = "1" diff --git a/src/parser.rs b/src/parser.rs index 7780d8a..fc6ccaf 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -121,8 +121,8 @@ pub fn parse_body (string: String, metadata: Metadata, reference_list: Option { - let re = Regex::new(r"!\[(?[\d\w (\\\[)]*)\]\[(?[\d\w\.\/]*)\]").unwrap(); - match re.captures_at(line, 0) { + let re = Regex::new(r"^!\[(?[\d\w (\\\[)]*)\]\[(?[\d\w\./]*)\]").unwrap(); + match re.captures(line) { Some(captures) => { let caption = captures.name("caption").unwrap().as_str().to_string(); let path = captures.name("path").unwrap().as_str().to_string(); diff --git a/src/types/contents.rs b/src/types/contents.rs index 31c025a..bcbfb71 100644 --- a/src/types/contents.rs +++ b/src/types/contents.rs @@ -33,7 +33,7 @@ impl Renderable for Contents { let plaintext = element.render_plaintext(); let anchor: String = plaintext.to_lowercase().split_whitespace().map(|s| s.chars().chain(['-'])).flatten().collect(); - let anchor = &anchor[..anchor.len()-1]; + let anchor = &anchor[..anchor.len().saturating_sub(1)]; let counter_text = counters[..element.level] .iter() .map(|s| s .to_string() diff --git a/src/types/heading.rs b/src/types/heading.rs index b12b056..664b0d5 100644 --- a/src/types/heading.rs +++ b/src/types/heading.rs @@ -24,7 +24,7 @@ impl Renderable for Heading { fn render_html (&self) -> String { let text = parse_inline_html(self.text.trim()); let anchor: String = text.to_lowercase().split_whitespace().map(|s| s.chars().chain(['-'])).flatten().collect(); - let anchor = &anchor[..anchor.len()-1]; + let anchor = &anchor[..anchor.len().saturating_sub(1)]; let section = match self.level { 1 => "h2", 2 => "h3", diff --git a/src/types/image.rs b/src/types/image.rs index 9929aa4..390d12f 100644 --- a/src/types/image.rs +++ b/src/types/image.rs @@ -27,7 +27,7 @@ impl Renderable for Image { path = self.path, caption = self.caption, count = self.count, - anchor = &anchor[..anchor.len()-1]) + anchor = &anchor[..anchor.len().saturating_sub(1)]) } fn render_gemtext(&self) -> String { format!("\ diff --git a/src/types/reference_list.rs b/src/types/reference_list.rs index 0d6a3e8..86c687b 100644 --- a/src/types/reference_list.rs +++ b/src/types/reference_list.rs @@ -26,7 +26,9 @@ impl ReferenceList { if &string[mat.start()-2..mat.start()-1] == "\\" {false} else {true} }, - None => false + None => { + false + } } { let new_reference = Reference { id: capture.name("id").map_or( @@ -85,7 +87,7 @@ impl ReferenceList { let mut new_string = string.to_string(); let re = Regex::new(r"\[[\d\w]+\]").unwrap(); for mat in re.find_iter(&string).collect::>().iter().rev() { - if !(&string[mat.start()-1..mat.start()] == "\\") { + if !(&string[mat.start().saturating_sub(1)..mat.start()] == "\\") { let inline_id = &string[mat.start()+1..mat.end()-1].trim(); for reference in &self.list { if &reference.id == inline_id { diff --git a/src/types/reference_list/name_list.rs b/src/types/reference_list/name_list.rs index 119c4d8..00c9a6b 100644 --- a/src/types/reference_list/name_list.rs +++ b/src/types/reference_list/name_list.rs @@ -18,21 +18,25 @@ impl NameList { pub fn render_full(&self) -> String { let mut names: Vec = Vec::new(); for name in self.string.split(" and ") { - if &name[0..1] == "{" { + if !name.is_empty() && &name[0..1] == "{" { // the case for dealing with organisations names.push(String::from(&name[1..name.len()-1])); } else { // the case for dealing with people with an indeterminate // amount of names - let last_name = name.split_whitespace().last().unwrap(); - let mut full_name = String::from(last_name) + ", "; - name.split_whitespace() - .filter(|n| n != &last_name) - .for_each(|n| { - let initial = format!("{}. ", &n[0..1]); - full_name.push_str(&initial) - }); - names.push(full_name); + match name.split_whitespace().last() { + Some(last_name) => { + let mut full_name = String::from(last_name) + ", "; + name.split_whitespace() + .filter(|n| n != &last_name) + .for_each(|n| { + let initial = format!("{}. ", &n[0..1]); + full_name.push_str(&initial) + }); + names.push(full_name); + } + None => () + } } } let mut all_names = String::new(); @@ -51,24 +55,25 @@ impl NameList { pub fn render_inline(&self) -> String { let mut names: Vec<&str> = Vec::new(); for name in self.string.split(" and ") { - if &name[0..1] == "{" { + if !name.is_empty() && &name[0..1] == "{" { // the case for dealing with organisations names.push(&name[1..name.len()-1]); } else { - let last_name = name.split_whitespace().last().unwrap(); - names.push(last_name); + match name.split_whitespace().last() { + Some(last_name) => {names.push(last_name)} + None => () + } + } } - let mut all_names = String::new(); names.sort_by(|a, b| a.cmp(b)); // et al. if more than 3 - if names.len() > 3 { - names = names[0..4].to_vec(); - names.push("et al."); + match names.len() { + 0 => {String::new()} + 1 => {names[0].to_string()} + 2 => {format!("{} & {}", names[0], names[1])} + _ => {format!("{} et al.", names[0])} } - - for name in names {all_names.push_str(&name)}; - all_names } }