mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-03 06:51:50 -06:00
refactor(ui): remove the unused list helpers from Edit text
is_bulleted, is_numbered, toggle_bullet_list and toggle_numbered_list had no caller outside their own tests: Format text shows bulleted and numbered lists as planned. Removed with their tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1a2f7b2a34
commit
2ef192b7cd
@@ -46,124 +46,6 @@ enum TextTarget {
|
||||
/// hit-testing still covers every image, so nothing becomes unselectable.
|
||||
pub(crate) const MAX_OUTLINES: usize = 250;
|
||||
|
||||
pub fn is_bulleted(text: &str) -> bool {
|
||||
let mut lines = text.lines();
|
||||
let Some(first) = lines.next() else { return false };
|
||||
first.trim_start().starts_with("• ") || first.trim_start().starts_with("- ")
|
||||
}
|
||||
|
||||
pub fn is_numbered(text: &str) -> bool {
|
||||
let mut lines = text.lines();
|
||||
let Some(first) = lines.next() else { return false };
|
||||
let t = first.trim_start();
|
||||
let num_end = t.find('.').unwrap_or(0);
|
||||
num_end > 0 && t[..num_end].chars().all(|c| c.is_ascii_digit()) && t[num_end..].starts_with(". ")
|
||||
}
|
||||
|
||||
pub fn toggle_bullet_list(text: &mut String) -> bool {
|
||||
let has_trailing_crlf = text.ends_with("\r\n");
|
||||
let has_trailing_newline = text.ends_with('\n');
|
||||
let lines: Vec<&str> = text.lines().collect();
|
||||
if lines.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let all_bulleted = lines.iter().all(|l| {
|
||||
let t = l.trim_start();
|
||||
t.is_empty() || t.starts_with("• ") || t.starts_with("- ")
|
||||
});
|
||||
let mut new_text = String::with_capacity(text.len() + 16);
|
||||
for (i, line) in lines.iter().enumerate() {
|
||||
if i > 0 {
|
||||
new_text.push('\n');
|
||||
}
|
||||
let trimmed = line.trim_start();
|
||||
let indent = &line[..line.len() - trimmed.len()];
|
||||
if all_bulleted {
|
||||
if let Some(rest) = trimmed.strip_prefix("• ").or_else(|| trimmed.strip_prefix("- ")) {
|
||||
new_text.push_str(indent);
|
||||
new_text.push_str(rest);
|
||||
} else {
|
||||
new_text.push_str(line);
|
||||
}
|
||||
} else if trimmed.is_empty() || trimmed.starts_with("• ") {
|
||||
new_text.push_str(line);
|
||||
} else {
|
||||
new_text.push_str(indent);
|
||||
new_text.push_str("• ");
|
||||
new_text.push_str(trimmed);
|
||||
}
|
||||
}
|
||||
if has_trailing_crlf {
|
||||
new_text.push_str("\r\n");
|
||||
} else if has_trailing_newline {
|
||||
new_text.push('\n');
|
||||
}
|
||||
if new_text != *text {
|
||||
*text = new_text;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_numbered_list(text: &mut String) -> bool {
|
||||
let has_trailing_crlf = text.ends_with("\r\n");
|
||||
let has_trailing_newline = text.ends_with('\n');
|
||||
let lines: Vec<&str> = text.lines().collect();
|
||||
if lines.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let is_num_line = |l: &str| {
|
||||
let t = l.trim_start();
|
||||
if t.is_empty() {
|
||||
return true;
|
||||
}
|
||||
let dot_idx = t.find('.').unwrap_or(0);
|
||||
dot_idx > 0 && t[..dot_idx].chars().all(|c| c.is_ascii_digit()) && t[dot_idx..].starts_with(". ")
|
||||
};
|
||||
let all_numbered = lines.iter().all(|l| is_num_line(l));
|
||||
let mut new_text = String::with_capacity(text.len() + 16);
|
||||
let mut num = 1;
|
||||
for (i, line) in lines.iter().enumerate() {
|
||||
if i > 0 {
|
||||
new_text.push('\n');
|
||||
}
|
||||
let t = line.trim_start();
|
||||
let indent = &line[..line.len() - t.len()];
|
||||
if all_numbered {
|
||||
if let Some(dot_idx) = t.find('.')
|
||||
&& dot_idx > 0
|
||||
&& t[..dot_idx].chars().all(|c| c.is_ascii_digit())
|
||||
&& t[dot_idx..].starts_with(". ")
|
||||
{
|
||||
new_text.push_str(indent);
|
||||
new_text.push_str(t.get(dot_idx + 2..).unwrap_or(""));
|
||||
continue;
|
||||
}
|
||||
new_text.push_str(line);
|
||||
} else if t.is_empty() {
|
||||
new_text.push_str(line);
|
||||
} else {
|
||||
use std::fmt::Write as _;
|
||||
new_text.push_str(indent);
|
||||
let _ = write!(new_text, "{num}. ");
|
||||
new_text.push_str(t);
|
||||
num += 1;
|
||||
}
|
||||
}
|
||||
if has_trailing_crlf {
|
||||
new_text.push_str("\r\n");
|
||||
} else if has_trailing_newline {
|
||||
new_text.push('\n');
|
||||
}
|
||||
if new_text != *text {
|
||||
*text = new_text;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn char_to_superscript(c: char) -> char {
|
||||
match c {
|
||||
'0' => '⁰',
|
||||
@@ -1730,46 +1612,6 @@ C", &picked
|
||||
assert_eq!(caret_color_on(DARK_EDITOR_FILL), Color32::WHITE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bullet_list_toggles_and_preserves_content() {
|
||||
let mut text = "First line\nSecond line\n\nThird line".to_string();
|
||||
assert!(!is_bulleted(&text));
|
||||
assert!(toggle_bullet_list(&mut text));
|
||||
assert!(is_bulleted(&text));
|
||||
assert_eq!(text, "• First line\n• Second line\n\n• Third line");
|
||||
|
||||
// Toggling again removes bullets
|
||||
assert!(toggle_bullet_list(&mut text));
|
||||
assert!(!is_bulleted(&text));
|
||||
assert_eq!(text, "First line\nSecond line\n\nThird line");
|
||||
|
||||
let mut indented = " First line\n Second line".to_string();
|
||||
assert!(toggle_bullet_list(&mut indented));
|
||||
assert_eq!(indented, " • First line\n • Second line");
|
||||
assert!(toggle_bullet_list(&mut indented));
|
||||
assert_eq!(indented, " First line\n Second line");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numbered_list_toggles_and_preserves_content() {
|
||||
let mut text = "Item A\nItem B\n\nItem C".to_string();
|
||||
assert!(!is_numbered(&text));
|
||||
assert!(toggle_numbered_list(&mut text));
|
||||
assert!(is_numbered(&text));
|
||||
assert_eq!(text, "1. Item A\n2. Item B\n\n3. Item C");
|
||||
|
||||
// Toggling again removes numbering
|
||||
assert!(toggle_numbered_list(&mut text));
|
||||
assert!(!is_numbered(&text));
|
||||
assert_eq!(text, "Item A\nItem B\n\nItem C");
|
||||
|
||||
let mut indented = " Item A\n Item B".to_string();
|
||||
assert!(toggle_numbered_list(&mut indented));
|
||||
assert_eq!(indented, " 1. Item A\n 2. Item B");
|
||||
assert!(toggle_numbered_list(&mut indented));
|
||||
assert_eq!(indented, " Item A\n Item B");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn superscript_and_subscript_conversion() {
|
||||
let mut ed = LineEditor {
|
||||
|
||||
Reference in New Issue
Block a user