aboutsummaryrefslogtreecommitdiff
path: root/src/bibiman.rs
diff options
context:
space:
mode:
authorTrim Bresilla2024-12-03 11:33:58 +0100
committerlukeflo2024-12-23 21:03:19 +0100
commit0c32c96fcfb8daa1c5061596542f76d355f27acd (patch)
tree57dfb779c1f2708a27364699e542c6cd69b51099 /src/bibiman.rs
parentbeb276008bec86537234c3d7a697b7bda02341e2 (diff)
downloadbibiman-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.rs78
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