diff options
| author | Trim Bresilla | 2024-12-03 11:33:58 +0100 |
|---|---|---|
| committer | lukeflo | 2024-12-23 21:03:19 +0100 |
| commit | 0c32c96fcfb8daa1c5061596542f76d355f27acd (patch) | |
| tree | 57dfb779c1f2708a27364699e542c6cd69b51099 /src/bibiman.rs | |
| parent | beb276008bec86537234c3d7a697b7bda02341e2 (diff) | |
| download | bibiman-0c32c96fcfb8daa1c5061596542f76d355f27acd.tar.gz bibiman-0c32c96fcfb8daa1c5061596542f76d355f27acd.zip | |
feat: enhance BibTeX entry formatting and file handling
- Remove the documentation comment for the `append_to_file` function.
- Format the content before writing it to the file in the `append_to_file` function.
- Add a new function `format_bibtex_entry` to enhance the readability of raw BibTeX entries.
- Implement logic to properly parse and format BibTeX entries in the `format_bibtex_entry` function.
Diffstat (limited to 'src/bibiman.rs')
| -rw-r--r-- | src/bibiman.rs | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/src/bibiman.rs b/src/bibiman.rs index e176bfa..778048f 100644 --- a/src/bibiman.rs +++ b/src/bibiman.rs @@ -421,7 +421,6 @@ impl Bibiman { Ok(()) } - /// Appends a string to the appropriate BibLaTeX file. pub fn append_to_file(&mut self, args: &CLIArgs, content: &str) -> Result<()> { // Determine the file path to append to let file_path = args.files.first().unwrap(); @@ -429,13 +428,86 @@ impl Bibiman { let mut file = OpenOptions::new().append(true).open(file_path).unwrap(); // Optionally, add a newline before the content file.write_all(b"\n")?; - // Write the content to the file - file.write_all(content.as_bytes())?; + // Format the content + let formatted_content = Self::format_bibtex_entry(content); + // Write the formatted content to the file + file.write_all(formatted_content.as_bytes())?; // Update the database and the lists to reflect the new content self.update_lists(args); Ok(()) } + /// Formats a raw BibTeX entry string for better readability. + pub fn format_bibtex_entry(entry: &str) -> String { + let mut formatted = String::new(); + // Find the position of the first '{' + if let Some(start_brace_pos) = entry.find('{') { + // Copy the preamble (e.g., '@article{') + let preamble = &entry[..start_brace_pos + 1]; + formatted.push_str(preamble); + formatted.push('\n'); // Add newline + // Now get the content inside the braces + let rest = &entry[start_brace_pos + 1..]; + // Remove the last '}' at the end + let rest = rest.trim_end(); + let rest = if rest.ends_with('}') { + &rest[..rest.len() - 1] + } else { + rest + }; + // Now we need to split the rest by commas, but commas can be inside braces or quotes + // We'll parse the fields properly + let mut fields = Vec::new(); + let mut current_field = String::new(); + let mut brace_level = 0; + let mut in_quotes = false; + for c in rest.chars() { + match c { + '{' if !in_quotes => { + brace_level += 1; + current_field.push(c); + } + '}' if !in_quotes => { + brace_level -= 1; + current_field.push(c); + } + '"' => { + in_quotes = !in_quotes; + current_field.push(c); + } + ',' if brace_level == 0 && !in_quotes => { + // Outside of braces and quotes, comma separates fields + fields.push(current_field.trim().to_string()); + current_field.clear(); + } + _ => { + current_field.push(c); + } + } + } + // Add the last field + if !current_field.trim().is_empty() { + fields.push(current_field.trim().to_string()); + } + + // Now reconstruct the entry with proper indentation + for (i, field) in fields.iter().enumerate() { + formatted.push_str(" "); + formatted.push_str(field); + // Add a comma if it's not the last field + if i < fields.len() - 1 { + formatted.push(','); + } + formatted.push('\n'); + } + formatted.push('}'); // Close the entry + formatted + } else { + // No opening brace found, return the entry as is + entry.to_string() + } + } + // Search entry list pub fn search_entries(&mut self) { // Use snapshot of entry list saved when starting the search |
