aboutsummaryrefslogtreecommitdiff
path: root/src/bibiman.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bibiman.rs')
-rw-r--r--src/bibiman.rs105
1 files changed, 32 insertions, 73 deletions
diff --git a/src/bibiman.rs b/src/bibiman.rs
index 3158d73..392ae95 100644
--- a/src/bibiman.rs
+++ b/src/bibiman.rs
@@ -16,22 +16,23 @@
/////
use crate::app::expand_home;
+use crate::bibiman::citekeys::CitekeyFormatting;
use crate::bibiman::entries::EntryTableColumn;
use crate::bibiman::{bibisetup::*, search::BibiSearch};
use crate::cliargs::CLIArgs;
use crate::config::BibiConfig;
-use crate::tui::popup::{PopupArea, PopupItem, PopupKind};
use crate::tui::Tui;
+use crate::tui::popup::{PopupArea, PopupItem, PopupKind};
use crate::{app, cliargs};
use crate::{bibiman::entries::EntryTable, bibiman::keywords::TagList};
use arboard::Clipboard;
-use color_eyre::eyre::{Context, Error, Result};
+use biblatex::Bibliography;
+use color_eyre::eyre::{Context, Error, Result, eyre};
use crossterm::event::KeyCode;
use editor_command::EditorBuilder;
use ratatui::widgets::ScrollbarState;
-use regex::Regex;
use std::ffi::OsStr;
-use std::fs::{self, read_to_string};
+use std::fs::{self};
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::PathBuf;
@@ -190,7 +191,9 @@ impl Bibiman {
self.popup_area.popup_message = message.unwrap().to_owned();
Ok(())
} else {
- Err(Error::msg("You need to past at least a message via Some(&str) to create a message popup"))
+ Err(Error::msg(
+ "You need to past at least a message via Some(&str) to create a message popup",
+ ))
}
}
PopupKind::MessageError => {
@@ -202,7 +205,9 @@ impl Bibiman {
self.popup_area.popup_message = message.unwrap().to_owned();
Ok(())
} else {
- Err(Error::msg("You need to past at least a message via Some(&str) to create a message popup"))
+ Err(Error::msg(
+ "You need to past at least a message via Some(&str) to create a message popup",
+ ))
}
}
PopupKind::OpenRes => {
@@ -680,23 +685,32 @@ impl Bibiman {
// Index of selected popup field
let popup_idx = self.popup_area.popup_state.selected().unwrap();
- // regex pattern to match citekey in fetched bibtexstring
- let pattern = Regex::new(r"\{([^\{\},]*),").unwrap();
+ let new_bib_entry = Bibliography::parse(&self.popup_area.popup_sel_item)
+ .map_err(|e| eyre!("Couldn't parse downloaded bib entry: {}", e.to_string()))?;
- let citekey = pattern
- .captures(&self.popup_area.popup_sel_item)
- .unwrap()
- .get(1)
- .unwrap()
- .as_str()
- .to_string();
+ let formatted_struct =
+ if let Some(formatter) = CitekeyFormatting::new(cfg, new_bib_entry.clone()) {
+ Some(formatter.do_formatting())
+ } else {
+ None
+ };
+
+ let (new_citekey, entry_string) = if let Some(mut formatter) = formatted_struct {
+ (
+ formatter.get_citekey_pair(0).unwrap().1,
+ formatter.print_updated_bib_as_string(),
+ )
+ } else {
+ let keys = new_bib_entry.keys().collect::<Vec<&str>>();
+ (keys[0].to_string(), new_bib_entry.to_biblatex_string())
+ };
// Check if new file or existing file was choosen
let mut file = if self.popup_area.popup_list[popup_idx]
.0
.contains("Create new file")
{
- let citekey = PathBuf::from(&citekey);
+ let citekey = PathBuf::from(&new_citekey);
// Get path of current files
let path: PathBuf = if self.main_bibfiles[0].is_file() {
self.main_bibfiles[0].parent().unwrap().to_owned()
@@ -714,45 +728,18 @@ impl Bibiman {
} else {
let file_path = &self.main_bibfiles[popup_idx - 1];
- // Check if similar citekey already exists
- let file_string = read_to_string(&file_path).unwrap();
-
- // If choosen file contains entry with fetched citekey, append an
- // char to the citekey so no dublettes are created
- if file_string.contains(&citekey) {
- let mut new_citekey = String::new();
-
- // Loop over ASCII alpabetic chars and check again if citekey with
- // appended char exists. If yes, move to next char and test again.
- // If the citekey is free, use it and break the loop
- for c in b'a'..=b'z' {
- let append_char = (c as char).to_string();
- new_citekey = citekey.clone() + &append_char;
- if !file_string.contains(&new_citekey) {
- break;
- }
- }
-
- let new_entry_string_clone = self.popup_area.popup_sel_item.clone();
-
- // Replace the double citekey with newly created
- self.popup_area.popup_sel_item = pattern
- .replace(&new_entry_string_clone, format!("{{{},", &new_citekey))
- .to_string();
- }
-
OpenOptions::new().append(true).open(file_path).unwrap()
};
// Optionally, add a newline before the content
file.write_all(b"\n")?;
// Write content to file
- file.write_all(self.popup_area.popup_sel_item.as_bytes())?;
+ file.write_all(entry_string.as_bytes())?;
// Update the database and the lists to reflect the new content
self.update_lists(cfg);
self.close_popup();
// Select newly created entry
- self.select_entry_by_citekey(&citekey);
+ self.select_entry_by_citekey(&new_citekey);
Ok(())
}
@@ -1285,38 +1272,10 @@ impl Bibiman {
#[cfg(test)]
mod tests {
- use regex::Captures;
-
- use super::*;
-
#[test]
fn citekey_pattern() {
let citekey = format!("{{{},", "a_key_2001");
assert_eq!(citekey, "{a_key_2001,")
}
-
- #[test]
- fn regex_capture_citekey() {
- let re = Regex::new(r"\{([^\{\},]*),").unwrap();
-
- let bibstring = String::from("@article{citekey77_2001:!?, author = {Hanks, Tom}, title = {A great book}, year = {2001}}");
-
- let citekey = re.captures(&bibstring).unwrap().get(1).unwrap().as_str();
-
- assert_eq!(citekey, "citekey77_2001:!?");
-
- if bibstring.contains(&citekey) {
- let append_char = "a";
- let new_entry_string_clone = bibstring.clone();
-
- let updated_bibstring = re
- .replace(&new_entry_string_clone, |caps: &Captures| {
- format!("{{{}{},", &caps[1], &append_char)
- })
- .to_string();
-
- assert_eq!(updated_bibstring, "@article{citekey77_2001:!?a, author = {Hanks, Tom}, title = {A great book}, year = {2001}}")
- }
- }
}