From 467851007e1861834326deee3116aa88fe839f5a Mon Sep 17 00:00:00 2001 From: lukeflo Date: Mon, 13 Oct 2025 15:45:53 +0200 Subject: Working proof of concept of citekey formatting --- CITEKEYS.md | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 CITEKEYS.md (limited to 'CITEKEYS.md') diff --git a/CITEKEYS.md b/CITEKEYS.md new file mode 100644 index 0000000..912326a --- /dev/null +++ b/CITEKEYS.md @@ -0,0 +1,215 @@ +# Formatting Citekeys + + + +- [Formatting Citekeys](#formatting-citekeys) + - [Settings](#settings) + - [Building Patterns](#building-patterns) + - [Ignore Lists and Char Case](#ignore-lists-and-char-case) + - [General Tipps](#general-tipps) + - [Examples](#examples) + + + +`bibiman` offers the possibility to create new citekeys from the fields of +BibLaTeX entries. This is done using an easy but powerful pattern-matching +syntax. + +## Settings + +All settings for the citekey generation have to be configured in the used config +file. The regular path is `XDG_CONFIG_DIR/bibiman/bibiman.toml`. But it can be +set dynamically with the `-c`/`--config=` global option. + +Following values can be set through the config file. A detailed explanation for +all fields follows below: + +```toml +[citekey_formatter] +fields = [ "author;2;;-;_", "title;3;6;_;_", "year" ] +case = "lowercase" +ascii_only = true +ignored_chars = [ + "?", "!", "\\", "\'", ".", "-", "–", ":", ",", "[", "]", "(", ")", "{", "}", "§", "$", "%", "&", "/", "`", "´", "#", "+", "*", "=", "|", "<", ">", "^", "°", "_", "\"", +] +ignored_words = [ + "the", + "a", + "an", + "of", + "for", + "in", + "at", + "to", + "and", + "der", + "die", + "das", + "ein", + "eine", + "eines", + "des", + "auf", + "und", + "für", + "vor", +] +``` + +## Building Patterns + +The main aspect for generating citekeys are the field patterns. They can be set +through an array in the config file where every array-item represents a single +BibLaTeX field to be used for generating a part of the citekey. + +Every field pattern consists of the following five parts separated by +semicolons. The general pattern looks like this (every subfield is explained +below): + +*biblatex field name* **;** *max word count* **;** *max char count* **;** *inner delimiter* **;** *trailing delimiter* + +- **BibLaTeX field**: the first part represents the field name which value + should be used to generate the content part of the citekey. Theoretically, any + BibLaTeX field can be selected by name. But there are some fields which are + much more common than others; e.g. `author`, `editor`, `title`, `year`/`date` + or `entrytype`. Those very common fields are preprocessed; meaning that for + instance LaTeX macros are fully stripped from the strings, or that `editor` is + a fallback value for `author` if the latter is empty (however, setting + `editor` explicitly is still possible). Also using `year` will parse the + `date` field too, to ensure a year number. +- **Max Word**: Defines how many words should maximal be used from the named + field. E.g. if the title consists of five words, and the max counter is set to + `3` only the first three fields will be used. +- **Max Chars/Word**: Defines how many chars, counting from the start, of each + word will be used to build the citekey. If for instance the value is set to + `5`, only the first five chars of any word will be used. Thus, "archaeology" + would be stripped down to "archa". +- **Inner Delimiter**: Sets the delimiter char used between words from the + currently named field; e.g. to separate the words of the `title` field. +- **Trailing Delimiter**: Sets the delimiter which separates the current fields + value from the following. This delimiter is only printed if the following + field has some content. + +For example, to use the `title` field, print maximal three words and of those +only the first five chars, single words separated by underscore and the whole +field separated by equal sign, insert the following pattern field into the +`fields` array: + +`title;3;5;_;=` + +Except the BibLaTeX field name, all other parts of the pattern can be left +blank. If the field name is the only value set, semicolon delimiters are also +not necessary. But if only one of the following parts should be set, all +delimiters need to be used. E.g. those are both valid: `title` or `title;;;_;=`. +The first would print all words of the title, no matter the length, not +separated by any char. The last would also print all words of the title, but +single words separated by underscores and the whole pattern value separated from +the following by an equal sign. This is not valid: `title;;_` since `bibiman` +can't know if the underscore means a delimiter (and which) or the max char +count. + +The pattern array inside the config file takes multiple pattern fields like the +predecing. This allows an elaborated citekey pattern which takes into account +multiple fields. + +## Ignore Lists and Char Case + +Beside the field patterns there are some other options to define how citekeys +should be built. + +`ascii_only=` +: If set to `true`, which is the default, non-ascii chars are mapped to their + ascii equivalent. For example, the German `ä` would be mapped to `a`. The + Turkish `ş` or Greek `σ`/`ς` would be mapped to `s`. If set to `false` all are + kept as they are. But this could lead to errors running LaTeX on the file. + +`case=` +: If used, sets the case of the chars in the citekey. Valid values are + `uppercase`, `lowercase` or `camelcase`. Both first should be clear, the + latter means typical camel case also beginning the *first word* with an + uppercase letter; also referenced as upper camel case or Pascal case. + +`ignored_chars=` +: Defines chars which should be ignored during parsing (meaning not print them). + The default list contains 33 special chars and is part of the default config + file (in out-commented state). Be aware, setting this key will completely + overwrite the default list! + +`ignored_words=` +: A list of words which should be ignored parsing field values. The default list + contains about 20 very commonly used words in English and German; like + articles, pronouns or connector words. Like with `ignored_chars` setting this + key will completely overwrite the default list! + +## General Tipps + +- Most importantly: *always use the **`--dry-run`** option first*! This will + print a list of old and new values for all citekeys in the file without + changing anything. +- After finding a good overall pattern, *use the `--output=` option* to create a + new file and don't overwrite your existent file. Thus, your original file + isn't broken if the key formatter produces some unwanted output. +- Even very long patterns are possible, they are not encouraged, since it bloats + the bibfiles. +- The same accounts for *too short* patterns; if the pattern is to unspecific, + it bares the risk of producing doublettes (e.g. single author and year only). + But the citekey generator will not check for doublettes! +- It is possible to keep special chars and use them as delimiters. But this + might cause problems other programs and CLI tools in particular, since many + special chars are reserved for shell operations. For instance, it will very + likely break the note file feature of `bibiman` which doesn't accept many + special chars. + +## Examples + +To make the process more clear a few examples might help. Following bibfile is +assumed: + +```latex +@article{Bos2023, + title = {{LaTeX}, metadata, and publishing workflows}, + author = {Bos, Joppe W. and {McCurley}, Kevin S.}, + year = {2023}, + month = apr, + journal = {arXiv}, + number = {{arXiv}:2301.08277}, + doi = {10.48550/arXiv.2301.08277}, + url = {http://arxiv.org/abs/2301.08277}, + urldate = {2023-08-22}, + note = {type: article}, +} +@book{Bhambra2021, + title = {Colonialism and \textbf{Modern Social Theory}}, + author = {Bhambra, Gurminder K. and Holmwood, John}, + location = {Cambridge and Medford}, + publisher = {Polity Press}, + date = {2021}, + +``` + +And the following values set in the config file: + +```toml +fields = [ + # Just print the whole entrytype and a colon as trailing delimiter + "entrytype;;;;:", + # Print all author names in full length, names separated by dash, + # the whole field by underscore + "author;;;-;_", + # Print first 4 words of title, first 3 chars of every word only. Title words + # separated by equal sign, the whole field by underscore + "title;4;3;=;_", + # Print all words of location, but only first 4 chars of every word. Single words + # separated by colon, whole field by underscore + "location;;4;:;_", + # Just print the whole year + "year", +] +case = "lowercase" +ascii_only = true +``` + +The combination of those setting will produce the following citekeys: + +- **`article:bos-mccurley_lat=met=pub=wor_2023`** +- **`book:bhambra-holmwood_col=mod=soc=the_camb:medf_2021`** -- cgit v1.2.3 From 18fa9b8bcb02aa5653b976cad7ec9c3123d4f372 Mon Sep 17 00:00:00 2001 From: lukeflo Date: Tue, 14 Oct 2025 10:11:52 +0200 Subject: add dry-run example to citekeys doc --- CITEKEYS.md | 10 ++++++---- tests/test-config.toml | 9 ++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'CITEKEYS.md') diff --git a/CITEKEYS.md b/CITEKEYS.md index 912326a..165f58c 100644 --- a/CITEKEYS.md +++ b/CITEKEYS.md @@ -66,7 +66,8 @@ Every field pattern consists of the following five parts separated by semicolons. The general pattern looks like this (every subfield is explained below): -*biblatex field name* **;** *max word count* **;** *max char count* **;** *inner delimiter* **;** *trailing delimiter* +*biblatex field name* **;** *max word count* **;** *max char count* **;** *inner +delimiter* **;** *trailing delimiter* - **BibLaTeX field**: the first part represents the field name which value should be used to generate the content part of the citekey. Theoretically, any @@ -145,9 +146,10 @@ should be built. - Most importantly: *always use the **`--dry-run`** option first*! This will print a list of old and new values for all citekeys in the file without - changing anything. + changing anything. For the test file of this repo and using the pattern from + the [section below](#examples) `----dry-run` produces the following output: - After finding a good overall pattern, *use the `--output=` option* to create a - new file and don't overwrite your existent file. Thus, your original file + new file and don't overwrite your existing file. Thus, your original file isn't broken if the key formatter produces some unwanted output. - Even very long patterns are possible, they are not encouraged, since it bloats the bibfiles. @@ -155,7 +157,7 @@ should be built. it bares the risk of producing doublettes (e.g. single author and year only). But the citekey generator will not check for doublettes! - It is possible to keep special chars and use them as delimiters. But this - might cause problems other programs and CLI tools in particular, since many + might cause problems for other programs and CLI tools in particular, since many special chars are reserved for shell operations. For instance, it will very likely break the note file feature of `bibiman` which doesn't accept many special chars. diff --git a/tests/test-config.toml b/tests/test-config.toml index 8dd8014..704d8d8 100644 --- a/tests/test-config.toml +++ b/tests/test-config.toml @@ -61,7 +61,14 @@ custom_column = "series" # year_color = "135" [citekey_formatter] -fields = ["shorthand;;;;+","entrytype;;;;:", "author;2;;-;_", "title;3;6;=;_", "year", "publisher;;5;#;" ] +fields = [ + "shorthand;;;;+", + "entrytype;;;;:", + "author;2;;-;_", + "title;3;6;=;_", + "year", + "publisher;;5;#;" +] # fields = [ # CamelCase test # "author;2;;;", # "title;5;5;;", -- cgit v1.2.3 From 549f89c554ae70af28a9c7276673f0f77b488165 Mon Sep 17 00:00:00 2001 From: lukeflo Date: Tue, 14 Oct 2025 10:21:39 +0200 Subject: add personal experience to citekey docs --- CITEKEYS.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'CITEKEYS.md') diff --git a/CITEKEYS.md b/CITEKEYS.md index 165f58c..19bd497 100644 --- a/CITEKEYS.md +++ b/CITEKEYS.md @@ -148,6 +148,7 @@ should be built. print a list of old and new values for all citekeys in the file without changing anything. For the test file of this repo and using the pattern from the [section below](#examples) `----dry-run` produces the following output: + [![niri-screenshot-2025-10-14-10-11-06.png](https://i.postimg.cc/SxxRkY8K/niri-screenshot-2025-10-14-10-11-06.png)](https://postimg.cc/bs4pRJmX) - After finding a good overall pattern, *use the `--output=` option* to create a new file and don't overwrite your existing file. Thus, your original file isn't broken if the key formatter produces some unwanted output. @@ -157,9 +158,9 @@ should be built. it bares the risk of producing doublettes (e.g. single author and year only). But the citekey generator will not check for doublettes! - It is possible to keep special chars and use them as delimiters. But this - might cause problems for other programs and CLI tools in particular, since many - special chars are reserved for shell operations. For instance, it will very - likely break the note file feature of `bibiman` which doesn't accept many + might cause problems for other programs and CLI tools in particular, since + many special chars are reserved for shell operations. For instance, it will + very likely break the note file feature of `bibiman` which doesn't accept many special chars. ## Examples @@ -215,3 +216,25 @@ The combination of those setting will produce the following citekeys: - **`article:bos-mccurley_lat=met=pub=wor_2023`** - **`book:bhambra-holmwood_col=mod=soc=the_camb:medf_2021`** + +**Personal Note** + +I use the following pattern to format the citekeys of my bibfiles: + +```toml +[citekey_formatter] +fields = [ + "author;1;;;_", + "title;3;7;-;_", + "year;;;;_", + "entrytype;;;;_", + "shorthand", +] +case = "lowercase" +ascii_only = true +``` + +It produces citekeys with enough information to quickly identify the underlying +work while not being too long; at least in my opinion. The shorthand at the end +is only printed in a few cases, but shows me that the specific work might differ +from standard articles/books etc. -- cgit v1.2.3 From 3cd41cb1bc2046f1710175999305ab08508bae69 Mon Sep 17 00:00:00 2001 From: lukeflo Date: Tue, 14 Oct 2025 16:28:20 +0200 Subject: option to reformat citekey-based basenames of attachment files --- CITEKEYS.md | 8 +- src/bibiman/bibisetup.rs | 98 +++---- src/bibiman/citekeys.rs | 85 +++++- src/bibiman/citekeys/citekey_utils.rs | 17 +- tests/biblatex-test-citekeys.bib | 476 ---------------------------------- 5 files changed, 152 insertions(+), 532 deletions(-) delete mode 100644 tests/biblatex-test-citekeys.bib (limited to 'CITEKEYS.md') diff --git a/CITEKEYS.md b/CITEKEYS.md index 19bd497..828e557 100644 --- a/CITEKEYS.md +++ b/CITEKEYS.md @@ -147,11 +147,17 @@ should be built. - Most importantly: *always use the **`--dry-run`** option first*! This will print a list of old and new values for all citekeys in the file without changing anything. For the test file of this repo and using the pattern from - the [section below](#examples) `----dry-run` produces the following output: + the [section below](#examples) `--dry-run` produces the following output: [![niri-screenshot-2025-10-14-10-11-06.png](https://i.postimg.cc/SxxRkY8K/niri-screenshot-2025-10-14-10-11-06.png)](https://postimg.cc/bs4pRJmX) - After finding a good overall pattern, *use the `--output=` option* to create a new file and don't overwrite your existing file. Thus, your original file isn't broken if the key formatter produces some unwanted output. +- Its possible to update citekey based PDF and note files directly when + formatting the citekeys using the `-u`/`--update-attachments` option. Thus, + all PDFs and notes are already linked to the correct entries after updating + the citekeys. Since this operation can break things, use it with `--dry-run` + first. As with regular citekeys this will print all changes without processing + anything. - Even very long patterns are possible, they are not encouraged, since it bloats the bibfiles. - The same accounts for *too short* patterns; if the pattern is to unspecific, diff --git a/src/bibiman/bibisetup.rs b/src/bibiman/bibisetup.rs index a83a507..a817236 100644 --- a/src/bibiman/bibisetup.rs +++ b/src/bibiman/bibisetup.rs @@ -22,6 +22,7 @@ use itertools::Itertools; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::ffi::{OsStr, OsString}; +use std::path::Path; use std::{fs, path::PathBuf}; use walkdir::WalkDir; @@ -318,23 +319,27 @@ impl BibiSetup { cfg: &BibiConfig, ) -> Vec { let mut pdf_files = if cfg.general.pdf_path.is_some() { - collect_file_paths(cfg.general.pdf_path.as_ref().unwrap(), &Some(vec!["pdf"])) + collect_file_paths( + cfg.general.pdf_path.as_ref().unwrap(), + Some(vec!["pdf".into()].as_slice()), + ) + } else { + None + }; + let ext = if let Some(ext) = &cfg.general.note_extensions + && cfg.general.note_path.is_some() + { + // let mut ext: Vec<&str> = Vec::new(); + // for e in cfg.general.note_extensions.as_ref().unwrap().iter() { + // ext.push(e); + // } + Some(ext.as_slice()) } else { None }; - let ext: Option> = - if cfg.general.note_path.is_some() && cfg.general.note_extensions.is_some() { - let mut ext: Vec<&str> = Vec::new(); - for e in cfg.general.note_extensions.as_ref().unwrap().iter() { - ext.push(e); - } - Some(ext) - } else { - None - }; let mut note_files = if cfg.general.note_path.is_some() && cfg.general.note_extensions.is_some() { - collect_file_paths(cfg.general.note_path.as_ref().unwrap(), &ext) + collect_file_paths(cfg.general.note_path.as_ref().unwrap(), ext.clone()) } else { None }; @@ -369,7 +374,7 @@ impl BibiSetup { file_field: filepaths.1, subtitle: Self::get_subtitle(k, bibliography), notes: if note_files.is_some() { - Self::get_notepath(k, &mut note_files, &ext) + Self::get_notepath(k, &mut note_files, ext) } else { None }, @@ -575,18 +580,18 @@ impl BibiSetup { ) -> (Option>, bool) { if biblio.get(citekey).unwrap().file().is_ok() { ( - Some(vec![biblio - .get(citekey) - .unwrap() - .file() - .unwrap() - .trim() - .into()]), + Some(vec![ + biblio.get(citekey).unwrap().file().unwrap().trim().into(), + ]), true, ) } else if pdf_files.is_some() { ( - Self::merge_filepath_or_none_two(&citekey, pdf_files, vec!["pdf"]), + Self::merge_filepath_or_none_two( + &citekey, + pdf_files, + vec!["pdf".into()].as_slice(), + ), false, ) } else { @@ -597,10 +602,10 @@ impl BibiSetup { pub fn get_notepath( citekey: &str, note_files: &mut Option>>, - ext: &Option>, + ext: Option<&[String]>, ) -> Option> { if let Some(e) = ext { - Self::merge_filepath_or_none_two(citekey, note_files, e.to_vec()) + Self::merge_filepath_or_none_two(citekey, note_files, e) } else { None } @@ -627,7 +632,7 @@ impl BibiSetup { fn merge_filepath_or_none_two( citekey: &str, files: &mut Option>>, - extensions: Vec<&str>, + extensions: &[String], ) -> Option> { let mut file = Vec::new(); @@ -645,11 +650,7 @@ impl BibiSetup { } } - if file.is_empty() { - None - } else { - Some(file) - } + if file.is_empty() { None } else { Some(file) } } } @@ -663,15 +664,17 @@ impl BibiSetup { /// /// Passing [`None`] as argument for extensions will result in collecting all files /// from the given directory and its subdirectories! -pub fn collect_file_paths( - file_dir: &PathBuf, - extensions: &Option>, +pub fn collect_file_paths>( + file_dir: P, + extensions: Option<&[String]>, ) -> Option>> { let mut files: HashMap> = HashMap::new(); + let file_dir = file_dir.as_ref(); + // Expand tilde to /home/user let file_dir = if file_dir.starts_with("~") { - &app::expand_home(&file_dir) + &app::expand_home(&file_dir.to_path_buf()) } else { file_dir }; @@ -682,13 +685,13 @@ pub fn collect_file_paths( let f = file.unwrap().into_path(); if f.is_file() && f.extension().is_some() - && extensions.as_ref().is_some_and(|v| { + && extensions.is_some_and(|v| { v.contains( &f.extension() .unwrap_or_default() .to_ascii_lowercase() - .to_str() - .unwrap_or_default(), + .to_string_lossy() + .to_string(), ) }) { @@ -721,11 +724,7 @@ pub fn collect_file_paths( } } - if files.is_empty() { - None - } else { - Some(files) - } + if files.is_empty() { None } else { Some(files) } } #[cfg(test)] @@ -759,8 +758,11 @@ mod tests { ], ); - let matches = - BibiSetup::merge_filepath_or_none_two("citekey", &mut Some(files), vec!["md", "pdf"]); + let matches = BibiSetup::merge_filepath_or_none_two( + "citekey", + &mut Some(files), + vec!["md".into(), "pdf".into()].as_slice(), + ); assert_eq!( matches.clone().unwrap().iter().next().unwrap().to_owned(), @@ -770,9 +772,11 @@ mod tests { matches.clone().unwrap().last().unwrap().to_owned(), OsString::from("/one/other/citekey.pdf") ); - assert!(!matches - .clone() - .unwrap() - .contains(&OsString::from("/one/other/citekey2.pdf"))); + assert!( + !matches + .clone() + .unwrap() + .contains(&OsString::from("/one/other/citekey2.pdf")) + ); } } diff --git a/src/bibiman/citekeys.rs b/src/bibiman/citekeys.rs index 4516b28..8f70ab0 100644 --- a/src/bibiman/citekeys.rs +++ b/src/bibiman/citekeys.rs @@ -16,6 +16,7 @@ ///// use std::{ + ffi::OsStr, fs::OpenOptions, io::Write, path::{Path, PathBuf}, @@ -28,7 +29,10 @@ use owo_colors::OwoColorize; use serde::{Deserialize, Serialize}; use crate::{ - bibiman::citekeys::citekey_utils::{SKIPPED_ENTRIES, build_citekey, formatting_help}, + bibiman::{ + bibisetup::collect_file_paths, + citekeys::citekey_utils::{SKIPPED_ENTRIES, build_citekey, formatting_help}, + }, config::{BibiConfig, IGNORED_SPECIAL_CHARS, IGNORED_WORDS}, }; @@ -72,6 +76,7 @@ impl<'a> CitekeyFormatting<'a> { let mut formatter = CitekeyFormatting::default(); let mut source_file = PathBuf::new(); let mut target_file: Option = None; + let mut update_files = false; formatter.fields = cfg.citekey_formatter.fields.clone().ok_or_eyre(format!( "Need to define {} correctly in config file", @@ -101,6 +106,7 @@ impl<'a> CitekeyFormatting<'a> { Short('t') | Short('o') | Long("target") | Long("output") => { target_file = Some(parser.value()?.into()) } + Short('u') | Long("update-attachments") => update_files = true, _ => return Err(arg.unexpected().into()), } } @@ -122,10 +128,13 @@ impl<'a> CitekeyFormatting<'a> { &*IGNORED_WORDS.as_slice() }; - formatter - .do_formatting() - .rev_sort_new_keys_by_len() - .update_file(source_file, target_file)?; + let mut updated_formatter = formatter.do_formatting().rev_sort_new_keys_by_len(); + + updated_formatter.update_file(source_file, target_file)?; + + if update_files { + updated_formatter.update_notes_pdfs(cfg)?; + } Ok(()) } @@ -194,7 +203,13 @@ impl<'a> CitekeyFormatting<'a> { target_file: Option

, ) -> color_eyre::Result<()> { if self.dry_run { - println!("Following citekeys would be formatted: old => new\n"); + println!( + "{}\n", + "Following citekeys would be formatted: old => new" + .bold() + .underline() + .white() + ); self.old_new_keys_map.sort_by(|a, b| a.0.cmp(&b.0)); for (old, new) in &self.old_new_keys_map { println!("{} => {}", old.italic(), new.bold()) @@ -235,6 +250,64 @@ impl<'a> CitekeyFormatting<'a> { self } + pub fn update_notes_pdfs(&self, cfg: &BibiConfig) -> color_eyre::Result<()> { + if let Some(pdf_path) = &cfg.general.pdf_path { + self.update_files_by_citekey_basename(pdf_path, vec!["pdf".into()].as_slice())?; + } + if let Some(note_path) = &cfg.general.note_path + && let Some(ext) = &cfg.general.note_extensions + { + self.update_files_by_citekey_basename(note_path, ext.as_slice())?; + } + Ok(()) + } + + fn update_files_by_citekey_basename>( + &self, + path: P, + ext: &[String], + ) -> color_eyre::Result<()> { + let files = collect_file_paths(path.as_ref(), Some(ext)); + if self.dry_run { + println!( + "\n{}\n", + "Following paths would be updated:" + .underline() + .bold() + .white() + ) + } + if let Some(mut f) = files { + for (old_key, new_key) in self.old_new_keys_map.iter() { + for e in ext { + let old_basename = old_key.to_owned() + "." + e; + if let Some(item) = f.get_mut(&old_basename) { + for p in item { + let ext = p.extension(); + let basename = new_key.to_owned() + + "." + + ext.unwrap_or(OsStr::new("")).to_str().unwrap_or(""); + let new_name = p + .parent() + .expect("parent expected") + .join(Path::new(&basename)); + if !self.dry_run { + std::fs::rename(p, new_name)?; + } else { + println!( + "{} => {}", + p.display().to_string().italic().dimmed(), + new_name.display().to_string().bold() + ) + } + } + } + } + } + } + Ok(()) + } + /// Update the `Bibliography` of the `CitekeyFormatting` struct and return /// it as `String`. pub fn print_updated_bib_as_string(&mut self) -> String { diff --git a/src/bibiman/citekeys/citekey_utils.rs b/src/bibiman/citekeys/citekey_utils.rs index 58a8274..61a1804 100644 --- a/src/bibiman/citekeys/citekey_utils.rs +++ b/src/bibiman/citekeys/citekey_utils.rs @@ -79,7 +79,7 @@ pub(super) fn formatting_help() { \t{} \tThe bibfile for which the citekey formatting should be processed. \tTakes a path as argument. - ", "-s, -f, --source=, --file=".fg::().bold()}, + ", "-s, -f, --source=, --file=".fg::().bold()}, formatdoc!( " \t{} @@ -88,9 +88,22 @@ pub(super) fn formatting_help() { \tcreated. \tIf the argument isn't used, the original file will be {}! ", - "-t, -o, --target=, --output=".fg::().bold(), + "-t, -o, --target=, --output=" + .fg::() + .bold(), "overwritten".italic(), ), + formatdoc!( + " + \t{} + \tWhen formatting citekeys also rename all PDFs and notefiles + \tfollowing the bibiman citekey-basename scheme at the locations + \tset in the config file. This option can break file paths. Try + \twith {} first! + ", + "-u, --update-attachments".fg::().bold(), + "--dry-run".bold() + ), ]; let help = help.join("\n"); println!("{}", help); diff --git a/tests/biblatex-test-citekeys.bib b/tests/biblatex-test-citekeys.bib deleted file mode 100644 index 34c2f33..0000000 --- a/tests/biblatex-test-citekeys.bib +++ /dev/null @@ -1,476 +0,0 @@ -@set{SET, - entryset = {article:herrmann-ofele_carboc=carben=as_2006,article:aksin-turkmen_effect=immobi=on_2006,article:yoon-ryu_pallad=pincer=comple_2006}, - annotation = {A \texttt{set} with three members.}, -} - -@set{stdmodel, - entryset = {article:glashow_partia=symmet=weak_1961,article:weinberg_model=lepton_1967,salam}, - annotation = {A \texttt{set} with three members discussing the standard - model of particle physics.}, -} - -@collection{collection:matuz-miller_contem=litera=critic_1990gale, - title = {Contemporary Literary Criticism}, - year = {1990}, - location = {Detroit}, - publisher = {Gale}, - volume = {61}, - pages = {204--208}, - editor = {Matuz, Roger and Miller, Helen}, - keywords = {narration}, - langid = {english}, - langidopts = {variant=american}, - annotation = {A \texttt{collection} entry providing the excerpt information - for the \texttt{article:doody_heming=style=jakes_1974} entry. Note the format of the \texttt{ - pages} field}, -} - -@article{article:aksin-turkmen_effect=immobi=on_2006, - title = {Effect of immobilization on catalytic characteristics of saturated - {Pd-N}-heterocyclic carbenes in {Mizoroki-Heck} reactions}, - author = {Aks{\i}n, {\"O}zge and T{\"u}rkmen, Hayati and Artok , Levent and - { \c{C}}etinkaya, Bekir and Ni, Chaoying and B{\" u}y{ \"u}kg{\"u} - ng{ \" o}r, Orhan and {\"O}zkal, Erhan}, - volume = {691}, - number = {13}, - pages = {3027--3036}, - journaltitle = jomch, - date = {2006}, - indextitle = {Effect of immobilization on catalytic characteristics}, -} - -@article{article:angenendt_honore=salvat=vom_2002, - title = {In Honore Salvatoris~-- Vom Sinn und Unsinn der Patrozinienkunde}, - shorttitle = {In Honore Salvatoris}, - author = {Angenendt, Arnold}, - volume = {97}, - pages = {431--456, 791--823}, - journaltitle = {Revue d'Histoire Eccl{\'e}siastique}, - date = {2002}, - langid = {german}, - indextitle = {In Honore Salvatoris}, - annotation = {A German article in a French journal. Apart from that, a - typical \texttt{article} entry. Note the \texttt{indextitle} - field}, -} - -@book{book:aristotle_de=anima_1907cambr#unive#press, - title = {De Anima}, - author = {Aristotle}, - location = {Cambridge}, - publisher = cup, - date = {1907}, - editor = {Hicks, Robert Drew}, - keywords = {primary, ancient, philosophy, athens}, - langid = {english}, - langidopts = {variant=british}, - annotation = {A \texttt{book} entry with an \texttt{author} and an \texttt{ - editor}}, -} - -@book{book:aristotle_physic_1929g#p#putna, - title = {Physics}, - shorttitle = {Physics}, - author = {Aristotle}, - location = {New York}, - publisher = {G. P. Putnam}, - url = {https://www.infobooks.org/authors/classic/aristotle-books/#Physic}, - date = {1929}, - translator = {Wicksteed, P. H. and Cornford, F. M.}, - keywords = {primary, ancient, philosophy}, - langid = {english}, - langidopts = {variant=american}, - file = {~/Documents/coding/projects/bibiman/tests/book:aristotle_physic_1929g#p#putna.pdf}, - annotation = {A \texttt{book} entry with a \texttt{translator} field}, - abstract = {The Physics is a work by Aristotle dedicated to the study of - nature. Regarded by Heidegger as "the fundamental work of Western - philosophy", it presents the renowned distinction between the - four types of cause, as well as reflections on chance, motion, - infinity, and other fundamental concepts. It is here that - Aristotle sets out his celebrated paradox of time.}, -} - -@book{book:aristotle_poetic_1968clare#press, - title = {Poetics}, - shorttitle = {Poetics}, - author = {Aristotle}, - location = {Oxford}, - publisher = {Clarendon Press}, - series = {Clarendon {Aristotle}}, - date = {1968}, - editor = {Lucas, D. W.}, - keywords = {primary}, - langid = {english}, - langidopts = {variant=british}, - annotation = {A \texttt{book} entry with an \texttt{author} and an \texttt{ - editor} as well as a \texttt{series} field}, -} - -@mvbook{mvbook:aristotle_rhetor=aristo=with_1877cambr#unive#press, - title = {The \textbf{Rhetoric} of {Aristotle} with a commentary by the late {Edward - Meredith Cope}}, - shorttitle = {Rhetoric}, - author = {Aristotle}, - publisher = cup, - date = {1877}, - editor = {Cope, Edward Meredith}, - commentator = {Cope, Edward Meredith}, - volumes = {3}, - keywords = {primary}, - langid = {english}, - langidopts = {variant=british}, - sorttitle = {Rhetoric of Aristotle}, - indextitle = {Rhetoric of {Aristotle}, The}, - annotation = {A commented edition. Note the concatenation of the \texttt{ - editor} and \texttt{commentator} fields as well as the \texttt{ - volumes}, \texttt{sorttitle}, and \texttt{indextitle} fields}, -} - -@book{book:augustine_hetero=cataly=synthe_1995marce#dekke, - title = {Heterogeneous catalysis for the synthetic \textit{chemist}}, - shorttitle = {Heterogeneous catalysis}, - author = {Augustine, Robert L.}, - location = {New York}, - publisher = {Marcel Dekker}, - date = {1995}, - langid = {english}, - langidopts = {variant=american}, - annotation = {A plain \texttt{book} entry}, - keywords = {chemistry}, -} - -@book{book:averroes_epistl=on=possib_1982jewis#theol#semin#ameri, - title = {The Epistle on the Possibility of Conjunction with the Active - Intellect by {Ibn Rushd} with the Commentary of {Moses Narboni}}, - shorttitle = {Possibility of Conjunction}, - author = {Averroes}, - location = {New York}, - publisher = {Jewish Theological Seminary of America}, - series = {Moreshet: Studies in {Jewish} History, Literature and Thought}, - number = {7}, - date = {1982}, - editor = {Bland, Kalman P.}, - translator = {Bland, Kalman P.}, - keywords = {primary}, - langid = {english}, - langidopts = {variant=american}, - indextitle = {Epistle on the Possibility of Conjunction, The}, - annotation = {A \texttt{book} entry with a \texttt{series} and a \texttt{ - number}. Note the concatenation of the \texttt{editor} and - \texttt{translator} fields as well as the \texttt{indextitle} - field}, -} - -@article{article:baez-lauda_higher=algebr=v_2004, - title = {Higher-Dimensional Algebra {V}: 2-Groups}, - author = {Baez, John C. and Lauda, Aaron D.}, - volume = {12}, - pages = {423--491}, - journaltitle = {Theory and Applications of Categories}, - date = {2004}, - version = {3}, - eprint = {math/0307200v3}, - eprinttype = {arxiv}, - langid = {english}, - keywords = {math}, - langidopts = {variant=american}, - annotation = {An \texttt{article} with \texttt{eprint} and \texttt{ - eprinttype} fields. Note that the arXiv reference is - transformed into a clickable link if \texttt{hyperref} support - has been enabled. Compare \texttt{baez\slash online}, which is - the same item given as an \texttt{online} entry}, -} - -@article{article:bertram-wentworth_gromov=invari=holomo_1996, - title = {Gromov invariants for holomorphic maps on {Riemann} surfaces}, - shorttitle = {Gromov invariants}, - author = {Bertram, Aaron and Wentworth, Richard}, - volume = {9}, - number = {2}, - pages = {529--571}, - journaltitle = jams, - date = {1996}, - langid = {english}, - langidopts = {variant=american}, - annotation = {An \texttt{article} entry with a \texttt{volume} and a \texttt - {number} field}, -} - -@article{article:doody_heming=style=jakes_1974, - title = {Hemingway's Style and {Jake's} Narration}, - author = {Doody, Terrence}, - year = {1974}, - journal = {The Journal of Narrative Technique}, - volume = {4}, - number = {3}, - pages = {212--225}, - langid = {english}, - langidopts = {variant=american}, - related = {matuz:article:doody_heming=style=jakes_1974}, - relatedstring = {\autocap{e}xcerpt in}, - annotation = {An \texttt{article} entry cited as an excerpt from a \texttt{ - collection} entry. Note the format of the \texttt{related} and - \texttt{relatedstring} fields}, -} - -@article{article:gillies_herder=prepar=goethe_1933, - title = {Herder and the Preparation of {Goethe's} Idea of World Literature}, - author = {Gillies, Alexander}, - series = {newseries}, - volume = {9}, - pages = {46--67}, - journaltitle = {Publications of the English Goethe Society}, - date = {1933}, - langid = {english}, - langidopts = {variant=british}, - annotation = {An \texttt{article} entry with a \texttt{series} and a \texttt - {volume} field. Note that format of the \texttt{series} field - in the database file}, -} - -@article{article:glashow_partia=symmet=weak_1961, - title = {Partial Symmetries of Weak Interactions}, - author = {Glashow, Sheldon}, - volume = {22}, - pages = {579--588}, - journaltitle = {Nucl.~Phys.}, - date = {1961}, -} - -@article{article:herrmann-ofele_carboc=carben=as_2006, - title = {A carbocyclic carbene as an efficient catalyst ligand for {C--C} - coupling reactions}, - author = {Herrmann, Wolfgang A. and {\"O}fele, Karl and Schneider, Sabine K. - and Herdtweck, Eberhardt and Hoffmann, Stephan D.}, - volume = {45}, - number = {23}, - pages = {3859--3862}, - journaltitle = anch-ie, - date = {2006}, - indextitle = {Carbocyclic carbene as an efficient catalyst, A}, -} - -@article{article:hostetler-wingate_alkane=gold=cluste_1998, - title = {Alkanethiolate gold cluster molecules with core diameters from 1.5 - to 5.2~{nm}}, - shorttitle = {Alkanethiolate gold cluster molecules}, - author = {Hostetler, Michael J. and Wingate, Julia E. and Zhong, Chuan-Jian - and Harris, Jay E. and Vachet, Richard W. and Clark, Michael R. and - Londono, J. David and Green, Stephen J. and Stokes, Jennifer J. and - Wignall, George D. and Glish, Gary L. and Porter, Marc D. and Evans - , Neal D. and Murray, Royce W.}, - volume = {14}, - number = {1}, - pages = {17--30}, - journaltitle = {Langmuir}, - date = {1998}, - subtitle = {Core and monolayer properties as a function of core size}, - langid = {english}, - langidopts = {variant=american}, - indextitle = {Alkanethiolate gold cluster molecules}, - annotation = {An \texttt{article} entry with \arabic{author} authors. By - default, long author and editor lists are automatically - truncated. This is configurable}, -} - -@article{article:kastenholz-hunenberger_comput=method=ionic_2006, - title = {Computation of methodology\hyphen independent ionic solvation free - energies from molecular simulations}, - author = {Kastenholz, M. A. and H{\"u}nenberger, Philippe H.}, - volume = {124}, - doi = {10.1063/1.2172593}, - journaltitle = jchph, - date = {2006}, - subtitle = {{I}. {The} electrostatic potential in molecular liquids}, - eid = {124106}, - langid = {english}, - langidopts = {variant=american}, - indextitle = {Computation of ionic solvation free energies}, - annotation = {An \texttt{article} entry with an \texttt{eid} and a \texttt{ - doi} field. Note that the \textsc{doi} is transformed into a - clickable link if \texttt{hyperref} support has been enabled}, - abstract = {The computation of \texttt{ionic} solvation free energies from atomistic - simulations is a surprisingly difficult problem that has found no - satisfactory solution for more than 15 years. The reason is that - the charging free energies evaluated from such simulations are - affected by very large errors. One of these is related to the - choice of a specific convention for summing up the contributions - of solvent charges to the electrostatic potential in the ionic - cavity, namely, on the basis of point charges within entire - solvent molecules (M scheme) or on the basis of individual point - charges (P scheme). The use of an inappropriate convention may - lead to a charge-independent offset in the calculated potential, - which depends on the details of the summation scheme, on the - quadrupole-moment trace of the solvent molecule, and on the - approximate form used to represent electrostatic interactions in - the system. However, whether the M or P scheme (if any) - represents the appropriate convention is still a matter of - on-going debate. The goal of the present article is to settle - this long-standing controversy by carefully analyzing (both - analytically and numerically) the properties of the electrostatic - potential in molecular liquids (and inside cavities within them). - }, -} - -@article{article:sarfraz-razzak_techni=sectio=algori_2002, - title = {Technical section: {An} algorithm for automatic capturing of the - font outlines}, - author = {M. Sarfraz and M. F. A. Razzak}, - year = {2002}, - journal = {Computers and Graphics}, - volume = {26}, - number = {5}, - pages = {795--804}, - issn = {0097-8493}, - annotation = {An \texttt{article} entry with an \texttt{issn} field}, -} - -@article{article:reese_georgi=anglos=diplom_1958, - title = {Georgia in {Anglo-Spanish} Diplomacy, 1736--1739}, - author = {Reese, Trevor R.}, - series = {3}, - volume = {15}, - pages = {168--190}, - journaltitle = {William and Mary Quarterly}, - date = {1958}, - langid = {english}, - langidopts = {variant=american}, - annotation = {An \texttt{article} entry with a \texttt{series} and a \texttt - {volume} field. Note the format of the series. If the value of - the \texttt{series} field is an integer, this number is printed - as an ordinal and the string \enquote*{series} is appended - automatically}, -} - -@article{article:shore_twiceb=once=concei_1991, - title = {Twice-Born, Once Conceived}, - author = {Shore, Bradd}, - series = {newseries}, - volume = {93}, - number = {1}, - pages = {9--27}, - journaltitle = {American Anthropologist}, - date = {1991-03}, - subtitle = {Meaning Construction and Cultural Cognition}, - annotation = {An \texttt{article} entry with \texttt{series}, \texttt{volume - }, and \texttt{number} fields. Note the format of the \texttt{ - series} which is a localization key}, -} - -@article{article:sigfridsson-ryde_compar=method=derivi_1998, - title = {Comparison of methods for deriving atomic charges from the - electrostatic potential and moments}, - author = {Sigfridsson, Emma and Ryde, Ulf}, - volume = {19}, - number = {4}, - pages = {377--395}, - doi = {10.1002/(SICI)1096-987X(199803)19:4<377::AID-JCC1>3.0.CO;2-P}, - journaltitle = {Journal of Computational Chemistry}, - date = {1998}, - langid = {english}, - langidopts = {variant=american}, - indextitle = {Methods for deriving atomic charges}, - annotation = {An \texttt{article} entry with \texttt{volume}, \texttt{number - }, and \texttt{doi} fields. Note that the \textsc{doi} is - transformed into a clickable link if \texttt{hyperref} support - has been enabled}, - abstract = {Four methods for deriving partial atomic charges from the - quantum chemical electrostatic potential (CHELP, CHELPG, - Merz-Kollman, and RESP) have been compared and critically - evaluated. It is shown that charges strongly depend on how and - where the potential points are selected. Two alternative methods - are suggested to avoid the arbitrariness in the point-selection - schemes and van der Waals exclusion radii: CHELP-BOW, which also - estimates the charges from the electrostatic potential, but with - potential points that are Boltzmann-weighted after their - occurrence in actual simulations using the energy function of the - program in which the charges will be used, and CHELMO, which - estimates the charges directly from the electrostatic multipole - moments. Different criteria for the quality of the charges are - discussed.}, -} - -@article{article:spiegelberg_intent=intent=schola_1969, - title = {\mkbibquote{Intention} und \mkbibquote{Intentionalit{\"a}t} in der - Scholastik, bei Brentano und Husserl}, - shorttitle = {Intention und Intentionalit{\"a}t}, - author = {Spiegelberg, Herbert}, - volume = {29}, - pages = {189--216}, - journaltitle = {Studia Philosophica}, - date = {1969}, - langid = {german}, - sorttitle = {Intention und Intentionalitat in der Scholastik, bei Brentano - und Husserl}, - indexsorttitle = {Intention und Intentionalitat in der Scholastik, bei - Brentano und Husserl}, - annotation = {An \texttt{article} entry. Note the \texttt{sorttitle} and - \texttt{indexsorttitle} fields and the markup of the quotes in - the database file}, -} - -@article{article:springer_mediae=pilgri=routes_1950, - title = {Mediaeval Pilgrim Routes from {Scandinavia} to {Rome}}, - shorttitle = {Mediaeval Pilgrim Routes}, - author = {Springer, Otto}, - volume = {12}, - pages = {92--122}, - journaltitle = {Mediaeval Studies}, - date = {1950}, - langid = {english}, - langidopts = {variant=british}, - annotation = {A plain \texttt{article} entry}, -} - -@article{article:weinberg_model=lepton_1967, - title = {A Model of Leptons}, - author = {Weinberg, Steven}, - volume = {19}, - pages = {1264--1266}, - journaltitle = {Phys.~Rev.~Lett.}, - date = {1967}, -} - -@string{anch-ie = {Angew.~Chem. Int.~Ed.}} - -@string{cup = {Cambridge University Press}} - -@string{dtv = {Deutscher Taschenbuch-Verlag}} - -@string{hup = {Harvard University Press}} - -@string{jams = {J.~Amer. Math. Soc.}} - -@string{jchph = {J.~Chem. Phys.}} - -@string{jomch = {J.~Organomet. Chem.}} - -@string{pup = {Princeton University Press}} - -@incollection{incollection:westfahl_true=fronti, - title = {The True Frontier}, - author = {Westfahl, Gary}, - pages = {55--65}, - subtitle = {Confronting and Avoiding the Realities of Space in {American} - Science Fiction Films}, - crossref = {westfahl:frontier}, - langid = {english}, - langidopts = {variant=american}, - indextitle = {True Frontier, The}, - annotation = {A cross-referenced article from a \texttt{collection}. This is - an \texttt{incollection} entry with a \texttt{crossref} field. - Note the \texttt{subtitle} and \texttt{indextitle} fields}, -} - -@article{article:yoon-ryu_pallad=pincer=comple_2006, - title = {Palladium pincer complexes with reduced bond angle strain: - efficient catalysts for the {Heck} reaction}, - author = {Yoon, Myeong S. and Ryu, Dowook and Kim, Jeongryul and Ahn, Kyo - Han}, - volume = {25}, - number = {10}, - pages = {2409--2411}, - journaltitle = {Organometallics}, - date = {2006}, - indextitle = {Palladium pincer complexes}, -} -- cgit v1.2.3