aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukeflo2024-10-17 23:02:06 +0200
committerlukeflo2024-10-17 23:02:06 +0200
commit1fb272e563aca3b90a82fcbef68ed1c28cb7b212 (patch)
tree8dc10dd07d80556d53ce7276cfddf47de1fec496
parent5abdd1822a1d388feb36b0d4e62316b4671bf406 (diff)
downloadbibiman-1fb272e563aca3b90a82fcbef68ed1c28cb7b212.tar.gz
bibiman-1fb272e563aca3b90a82fcbef68ed1c28cb7b212.zip
Implement sorting and remove unneccessary struct
- Implement sorting of list (by authors for now) - Remove hole BibiData struct - Create entry table content directly through iterator
-rw-r--r--src/backend/bib.rs55
-rw-r--r--src/frontend/app.rs6
-rw-r--r--src/frontend/entries.rs126
-rw-r--r--src/frontend/handler.rs3
-rw-r--r--src/frontend/ui.rs27
5 files changed, 78 insertions, 139 deletions
diff --git a/src/backend/bib.rs b/src/backend/bib.rs
index 8539ab3..aca08b3 100644
--- a/src/backend/bib.rs
+++ b/src/backend/bib.rs
@@ -113,61 +113,6 @@ impl BibiMain {
keyword_list.dedup();
keyword_list
}
-}
-
-#[derive(Debug)]
-pub struct BibiData {
- pub entry_list: BibiDataSets,
-}
-
-impl BibiData {
- pub fn new(biblio: &Bibliography, citekeys: &Vec<String>) -> Self {
- Self {
- entry_list: {
- let bibentries = citekeys
- .into_iter()
- .map(|citekey| BibiEntry::new(&citekey, &biblio))
- .collect();
- BibiDataSets { bibentries }
- },
- }
- }
-}
-
-// Parent struct which keeps the Vector of all bibentries
-// Necessary for implementing FromIterator
-#[derive(Debug)]
-pub struct BibiDataSets {
- pub bibentries: Vec<Vec<String>>,
-}
-
-// Struct which has to be created for every entry of bibdatabase
-#[derive(Debug)]
-pub struct BibiEntry {
- pub authors: String,
- pub title: String,
- pub year: String,
- pub pubtype: String,
- pub keywords: String,
- pub citekey: String,
- pub weblink: String,
- pub filepath: String,
-}
-
-impl BibiEntry {
- pub fn new(citekey: &str, biblio: &Bibliography) -> Vec<String> {
- vec![
- Self::get_authors(&citekey, &biblio),
- Self::get_title(&citekey, &biblio),
- Self::get_year(&citekey, &biblio),
- Self::get_pubtype(&citekey, &biblio),
- Self::get_keywords(&citekey, &biblio),
- citekey.to_string(),
- Self::get_abstract(&citekey, &biblio),
- Self::get_weblink(&citekey, &biblio),
- Self::get_filepath(&citekey, &biblio),
- ]
- }
pub fn get_authors(citekey: &str, biblio: &Bibliography) -> String {
if biblio.get(&citekey).unwrap().author().is_ok() {
diff --git a/src/frontend/app.rs b/src/frontend/app.rs
index a035231..10cfa9b 100644
--- a/src/frontend/app.rs
+++ b/src/frontend/app.rs
@@ -53,8 +53,6 @@ pub struct App {
pub main_bibfile: PathBuf,
// main bibliography
pub main_biblio: BibiMain,
- // bibliographic data
- pub biblio_data: BibiData,
// search struct:
pub search_struct: BibiSearch,
// tag list
@@ -76,7 +74,6 @@ impl App {
let running = true;
let main_bibfile = args.bibfilearg;
let main_biblio = BibiMain::new(main_bibfile.clone());
- let biblio_data = BibiData::new(&main_biblio.bibliography, &main_biblio.citekeys);
let tag_list = TagList::new(main_biblio.keyword_list.clone());
let search_struct = BibiSearch::default();
let entry_table = EntryTable::new(&main_biblio.citekeys, &main_biblio.bibliography);
@@ -85,7 +82,6 @@ impl App {
running,
main_bibfile,
main_biblio,
- biblio_data,
tag_list,
search_struct,
entry_table,
@@ -129,8 +125,6 @@ impl App {
pub fn update_lists(&mut self) {
self.main_biblio = BibiMain::new(self.main_bibfile.clone());
- self.biblio_data =
- BibiData::new(&self.main_biblio.bibliography, &self.main_biblio.citekeys);
// self.tag_list = TagList::from_iter(self.main_biblio.keyword_list.clone());
self.tag_list = TagList::new(self.main_biblio.keyword_list.clone());
self.entry_table =
diff --git a/src/frontend/entries.rs b/src/frontend/entries.rs
index fb80b46..38b1852 100644
--- a/src/frontend/entries.rs
+++ b/src/frontend/entries.rs
@@ -17,12 +17,11 @@
use super::app::App;
use super::tui::Tui;
-use crate::backend::{bib::BibiEntry, search::BibiSearch};
+use crate::backend::{bib::BibiMain, search::BibiSearch};
use biblatex::Bibliography;
use color_eyre::eyre::{Context, Ok, Result};
use core::panic;
use editor_command::EditorBuilder;
-use itertools::Itertools;
use ratatui::widgets::{ScrollbarState, TableState};
use std::process::{Command, Stdio};
@@ -31,69 +30,82 @@ use std::process::{Command, Stdio};
pub struct EntryTable {
pub entry_table_items: Vec<EntryTableItem>,
pub entry_table_at_search_start: Vec<EntryTableItem>,
+ pub entry_table_reversed_sort: bool,
pub entry_table_state: TableState,
pub entry_scroll_state: ScrollbarState,
pub entry_info_scroll: u16,
pub entry_info_scroll_state: ScrollbarState,
}
-// impl FromIterator<Vec<String>> for EntryTable {
-// fn from_iter<T: IntoIterator<Item = Vec<String>>>(iter: T) -> Self {
-// let entry_table_items: Vec<EntryTableItem> = iter
-// .into_iter()
-// .sorted()
-// // 0: authors, 1: title, 2: date, 3: pubtype, 4: keywords, 5: citekey
-// // 6: abstract, 7: doi/url, 8: pdf filepath
-// // See backend/bib.rs BibiEntry impl
-// .map(|i| {
-// EntryTableItem::new(
-// &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7], &i[8],
-// )
-// })
-// .collect();
-// let entry_table_state = TableState::default().with_selected(0);
-// let entry_scroll_state = ScrollbarState::new(entry_table_items.len());
-// let entry_info_scroll_state = ScrollbarState::default();
-// Self {
-// entry_table_items,
-// entry_table_at_search_start: Vec::new(),
-// entry_table_state,
-// entry_scroll_state,
-// entry_info_scroll: 0,
-// entry_info_scroll_state,
-// }
-// }
-// }
-
impl EntryTable {
pub fn new(citekeys: &Vec<String>, biblio: &Bibliography) -> Self {
- let entry_table_items: Vec<EntryTableItem> = citekeys
- .into_iter()
- .sorted()
- .map(|key| EntryTableItem {
- authors: BibiEntry::get_authors(&key, &biblio),
- title: BibiEntry::get_title(&key, &biblio),
- year: BibiEntry::get_year(&key, &biblio),
- pubtype: BibiEntry::get_pubtype(&key, &biblio),
- keywords: BibiEntry::get_keywords(&key, &biblio),
- citekey: key.clone(),
- abstract_text: BibiEntry::get_abstract(&key, &biblio),
- doi_url: BibiEntry::get_weblink(&key, &biblio),
- filepath: BibiEntry::get_filepath(&key, &biblio),
- })
- .collect();
+ let entry_table_items = Self::set_entry_table(&citekeys, &biblio);
let entry_table_state = TableState::default().with_selected(0);
let entry_scroll_state = ScrollbarState::new(entry_table_items.len());
let entry_info_scroll_state = ScrollbarState::default();
Self {
entry_table_items,
entry_table_at_search_start: Vec::new(),
+ entry_table_reversed_sort: false,
entry_table_state,
entry_scroll_state,
entry_info_scroll: 0,
entry_info_scroll_state,
}
}
+
+ pub fn set_entry_table(citekeys: &Vec<String>, biblio: &Bibliography) -> Vec<EntryTableItem> {
+ let mut entry_table: Vec<EntryTableItem> = citekeys
+ .into_iter()
+ .map(|key| EntryTableItem {
+ authors: BibiMain::get_authors(&key, &biblio),
+ title: BibiMain::get_title(&key, &biblio),
+ year: BibiMain::get_year(&key, &biblio),
+ pubtype: BibiMain::get_pubtype(&key, &biblio),
+ keywords: BibiMain::get_keywords(&key, &biblio),
+ citekey: key.to_owned(),
+ abstract_text: BibiMain::get_abstract(&key, &biblio),
+ doi_url: BibiMain::get_weblink(&key, &biblio),
+ filepath: BibiMain::get_filepath(&key, &biblio),
+ })
+ .collect();
+
+ entry_table.sort_by(|a, b| a.authors.to_lowercase().cmp(&b.authors.to_lowercase()));
+ entry_table
+ }
+
+ // Sort entry table by specific column.
+ // Toggle sorting by hitting same key again
+ pub fn sort_entry_table(&mut self, sorting: &str) {
+ if self.entry_table_reversed_sort {
+ match sorting {
+ "author" => self
+ .entry_table_items
+ .sort_by(|a, b| a.authors.to_lowercase().cmp(&b.authors.to_lowercase())),
+ "title" => self
+ .entry_table_items
+ .sort_by(|a, b| a.title.to_lowercase().cmp(&b.title.to_lowercase())),
+ "year" => self
+ .entry_table_items
+ .sort_by(|a, b| a.year.to_lowercase().cmp(&b.year.to_lowercase())),
+ _ => {}
+ }
+ } else if !self.entry_table_reversed_sort {
+ match sorting {
+ "author" => self
+ .entry_table_items
+ .sort_by(|a, b| b.authors.to_lowercase().cmp(&a.authors.to_lowercase())),
+ "title" => self
+ .entry_table_items
+ .sort_by(|a, b| b.title.to_lowercase().cmp(&a.title.to_lowercase())),
+ "year" => self
+ .entry_table_items
+ .sort_by(|a, b| b.year.to_lowercase().cmp(&a.year.to_lowercase())),
+ _ => {}
+ }
+ }
+ self.entry_table_reversed_sort = !self.entry_table_reversed_sort;
+ }
}
// Define contents of each entry table row
@@ -111,30 +123,6 @@ pub struct EntryTableItem {
}
impl EntryTableItem {
- // pub fn new(
- // authors: String,
- // title: String,
- // year: String,
- // pubtype: String,
- // keywords: String,
- // citekey: String,
- // abstract_text: String,
- // doi_url: String,
- // filepath: String,
- // ) -> Self {
- // Self {
- // authors,
- // title,
- // year,
- // pubtype,
- // keywords,
- // citekey,
- // abstract_text,
- // doi_url,
- // filepath,
- // }
- // }
-
// This functions decides which fields are rendered in the entry table
// Fields which should be usable but not visible can be left out
pub fn ref_vec(&self) -> Vec<&String> {
diff --git a/src/frontend/handler.rs b/src/frontend/handler.rs
index c2cacf5..70ba5c7 100644
--- a/src/frontend/handler.rs
+++ b/src/frontend/handler.rs
@@ -121,6 +121,9 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App, tui: &mut Tui) -> R
KeyCode::Char('G') | KeyCode::End => {
app.select_last_entry();
}
+ KeyCode::Char('s') => {
+ app.entry_table.sort_entry_table("author");
+ }
KeyCode::Char('y') => {
App::yank_text(&app.get_selected_citekey());
}
diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs
index 08cebcb..1767cea 100644
--- a/src/frontend/ui.rs
+++ b/src/frontend/ui.rs
@@ -47,6 +47,8 @@ const SELECTED_STYLE: Style = Style::new()
.add_modifier(Modifier::REVERSED);
const TEXT_FG_COLOR: Color = Color::Indexed(252);
const TEXT_UNSELECTED_FG_COLOR: Color = Color::Indexed(245);
+const SORTED_ENTRIES: &str = "▼";
+const SORTED_ENTRIES_REVERSED: &str = "▲";
const SCROLLBAR_UPPER_CORNER: Option<&str> = Some("┓");
const SCROLLBAR_LOWER_CORNER: Option<&str> = Some("┛");
@@ -259,15 +261,22 @@ impl App {
let header_style = Style::default().bold().fg(TEXT_FG_COLOR);
- let header = [
- "Authors".underlined(),
- "Title".underlined(),
- "Year".underlined(),
- "Type".underlined(),
- ]
- .into_iter()
- .map(Cell::from)
- .collect::<Row>()
+ let header = Row::new(vec![
+ Cell::from(Line::from(vec![
+ Span::raw("Author").underlined(),
+ Span::raw(format!(
+ " {}",
+ if self.entry_table.entry_table_reversed_sort {
+ SORTED_ENTRIES_REVERSED
+ } else {
+ SORTED_ENTRIES
+ }
+ )),
+ ])),
+ Cell::from("Title".to_string().underlined()),
+ Cell::from("Year".to_string().underlined()),
+ Cell::from("Type".to_string().underlined()),
+ ])
.style(header_style)
.height(1);