aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukeflo2025-10-10 10:31:45 +0200
committerlukeflo2025-10-10 10:31:45 +0200
commitf9548af5c7693edf536b4ad45564a964338e2c2e (patch)
treeec7b093c48fc06cff9c651d0f59baa57d2fcb898
parent669936a8e4ff99012e8b32ae15616f8fe206ab2d (diff)
downloadbibiman-f9548af5c7693edf536b4ad45564a964338e2c2e.tar.gz
bibiman-f9548af5c7693edf536b4ad45564a964338e2c2e.zip
set up citekey formatting cli, reformat help output
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/bibiman/citekeys.rs87
-rw-r--r--src/cliargs.rs106
-rw-r--r--src/main.rs14
5 files changed, 168 insertions, 41 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 49f65b4..a27636e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -107,6 +107,7 @@ dependencies = [
"editor-command",
"figment",
"futures",
+ "indoc",
"itertools",
"lexopt",
"logos",
diff --git a/Cargo.toml b/Cargo.toml
index 098848e..abf1eee 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -40,6 +40,7 @@ figment = { version = "0.10.19", features = [ "toml", "test" ]}
owo-colors = "4.2.2"
logos = "0.15.1"
phf = { version = "0.13.1", features = ["macros"] }
+indoc = "2.0.6"
[workspace.metadata.cross.target.aarch64-unknown-linux-gnu]
# Install libssl-dev:arm64, see <https://github.com/cross-rs/cross/blob/main/docs/custom_images.md#adding-dependencies-to-existing-images>
diff --git a/src/bibiman/citekeys.rs b/src/bibiman/citekeys.rs
index b7995ac..cafd124 100644
--- a/src/bibiman/citekeys.rs
+++ b/src/bibiman/citekeys.rs
@@ -23,7 +23,12 @@ use std::{
use biblatex::{Bibliography, ChunksExt, Entry, Type};
use color_eyre::eyre::eyre;
-use owo_colors::OwoColorize;
+use indoc::formatdoc;
+use lexopt::Arg::{Long, Short};
+use owo_colors::{
+ OwoColorize,
+ colors::{BrightBlue, Green, White},
+};
use serde::{Deserialize, Serialize};
use crate::{bibiman::sanitize::sanitize_single_string_fully, config::BibiConfig};
@@ -48,6 +53,30 @@ pub(crate) struct CitekeyFormatting {
}
impl CitekeyFormatting {
+ pub(crate) fn parse_citekey_cli(
+ parser: &mut lexopt::Parser,
+ cfg: &BibiConfig,
+ ) -> color_eyre::Result<()> {
+ let mut formatter = CitekeyFormatting::default();
+
+ while let Some(arg) = parser.next()? {
+ match arg {
+ Short('h') | Long("help") => {
+ formatting_help();
+ return Ok(());
+ }
+ Short('s') | Short('f') | Long("source") | Long("file") => {
+ formatter.bibfile_path.0 = parser.value()?.into()
+ }
+ Short('t') | Short('o') | Long("target") | Long("output") => {
+ formatter.bibfile_path.1 = Some(parser.value()?.into())
+ }
+ _ => return Err(arg.unexpected().into()),
+ }
+ }
+
+ Ok(())
+ }
/// Start Citekey formatting with building a new instance of `CitekeyFormatting`
/// Formatting is processed file by file, because `bibman` can handle
/// multi-file setups.
@@ -136,6 +165,62 @@ impl CitekeyFormatting {
}
}
+fn formatting_help() {
+ let help = vec![
+ formatdoc!(
+ "{} {}\n",
+ env!("CARGO_PKG_NAME").fg::<Green>().bold(),
+ env!("CARGO_PKG_VERSION")
+ ),
+ formatdoc!("{}", "USAGE".bold()),
+ formatdoc!(
+ "\t{} {} {} {}\n",
+ env!("CARGO_PKG_NAME").fg::<White>().bold(),
+ "format-citekeys".bold(),
+ "--source=<SOURCE>".bold(),
+ "--output=<TARGET>".bold()
+ ),
+ formatdoc!(
+ "
+ \tThis help describes the CLI usage for the citekey formatting
+ \tfunctionality of bibiman. The definition of patterns how the
+ \tcitekeys should be formatted must be set in the config file.
+ \tFor further informations how to use this patterns etc. see:
+ \t{}
+ ",
+ "https://codeberg.org/lukeflo/bibiman/src/branch/main#bibiman"
+ .italic()
+ .fg::<BrightBlue>()
+ ),
+ formatdoc!("{}", "OPTIONS".bold()),
+ formatdoc!(
+ "
+ \t{}
+ \tShow this help and exit
+ ",
+ "-h, --help".fg::<White>().bold()
+ ),
+ formatdoc! {"
+ \t{}
+ \tThe bibfile for which the citekey formatting should be processed.
+ \tTakes a path as argument.
+ ", "-s, -f, --source=, --file=".fg::<White>().bold()},
+ formatdoc!(
+ "
+ \t{}
+ \tThe bibfile to which the updated content should be written.
+ \tTakes a path as argument. If the file doesn't exist, it will be
+ \tcreated.
+ \tIf the argument isn't used, the original file will be {}!
+ ",
+ "-t, -o, --target=, --output=".fg::<White>().bold(),
+ "overwritten".italic(),
+ ),
+ ];
+ let help = help.join("\n");
+ println!("{}", help);
+}
+
/// Build the citekey from the patterns defined in the config file
fn build_citekey(entry: &Entry, pattern_fields: &[String], case: Option<&CitekeyCase>) -> String {
let mut new_citekey = String::new();
diff --git a/src/cliargs.rs b/src/cliargs.rs
index 26a07af..e766e77 100644
--- a/src/cliargs.rs
+++ b/src/cliargs.rs
@@ -16,6 +16,7 @@
/////
use dirs::{config_dir, home_dir};
+use indoc::formatdoc;
use lexopt::prelude::*;
use owo_colors::OwoColorize;
use owo_colors::colors::css::LightGreen;
@@ -25,6 +26,7 @@ use std::path::PathBuf;
use walkdir::WalkDir;
use crate::app;
+use crate::bibiman::citekeys::CitekeyFormatting;
use crate::config::BibiConfig;
// struct for CLIArgs
@@ -37,10 +39,16 @@ pub struct CLIArgs {
}
impl CLIArgs {
- pub fn parse_args() -> color_eyre::Result<(CLIArgs, BibiConfig)> {
+ /// This struct parses the command line and initializes and returns the
+ /// necessary structs `CLIArgs` and `BibiConfig`.
+ ///
+ /// Additionally, it returns a bool which defines if the TUI should be run
+ /// or not. The latter is the case for pure CLI processes as `format-citekeys`.
+ pub fn parse_args() -> color_eyre::Result<(CLIArgs, BibiConfig, bool)> {
let mut args = CLIArgs::default();
let mut parser = lexopt::Parser::from_env();
let mut subcommand = None;
+ let mut run_tui = true;
// Default config
args.cfg_path = if config_dir().is_some() {
@@ -81,6 +89,7 @@ impl CLIArgs {
match value.as_str() {
"format-citekeys" => {
subcommand = Some(value);
+ run_tui = false;
break;
}
_ => {
@@ -111,14 +120,16 @@ impl CLIArgs {
if let Some(cmd) = subcommand {
match cmd.as_str() {
- "format-citekeys" => todo!("write citekey formatting"),
+ "format-citekeys" => {
+ CitekeyFormatting::parse_citekey_cli(&mut parser, &cfg)?;
+ }
_ => {}
}
}
cfg.cli_overwrite(&args);
- Ok((args, cfg))
+ Ok((args, cfg, run_tui))
}
}
@@ -172,14 +183,21 @@ pub fn help_func() -> String {
env!("CARGO_PKG_VERSION").fg::<LightGreen>(),
),
format!(
- "{}:\n\t{} [Flags] [files/dirs]\n",
+ "{}\n\t{} [OPTIONS] [SUBCOMMAND | POSITIONAL ARGUMENTS]\n",
"USAGE".bold(),
- "bibiman".bold()
+ env!("CARGO_PKG_NAME").fg::<White>().bold()
+ ),
+ formatdoc!(
+ "
+ \tYou can either use a {} or {}, not both!
+ ",
+ "subcommand".bold(),
+ "positional arguments".bold()
),
format!(
- "{}:\n\t{}\t\tPath to {} file",
+ "{}\n\t{}\t\tPath to {} file",
"POSITIONAL ARGUMENTS".bold(),
- "<file>".fg::<BrightMagenta>().bold(),
+ "<file>".fg::<Magenta>().bold(),
".bib".fg::<BrightBlack>().bold()
),
format!(
@@ -188,38 +206,58 @@ pub fn help_func() -> String {
".bib".fg::<BrightBlack>().bold()
),
format!("\n\t{}", "Both can be passed multiple times".italic()),
- format!("\n{}:", "FLAGS".bold()),
- format!("\t{}", "-h, --help".bold().fg::<BrightCyan>()),
- format!("\t\t{}", "Show this help and exit"),
- format!("\t{}", "-v, --version".bold().fg::<BrightCyan>()),
- format!("\t\t{}", "Show the version and exit"),
- format!("\t{}", "--light-terminal".bold().fg::<BrightCyan>()),
- format!(
- "\t\t{}",
- "Enable default colors for light terminal background"
+ format!("\n{}", "SUBCOMMANDS".bold()),
+ formatdoc!(
+ "
+ \t{}
+ \tRun the citekey formatting procedure on a specified bibfile.
+ \tFor further infos run {}
+ ",
+ "format-citekeys".fg::<BrightYellow>().bold(),
+ "bibiman format-citekeys --help".fg::<BrightBlack>().bold()
),
- format!(
- "\t{}{}",
- "-c, --config-file=".bold().fg::<BrightCyan>(),
- "<value>".bold().italic().fg::<BrightCyan>()
+ format!("{}", "OPTIONS".bold()),
+ formatdoc!(
+ "
+ \t{}
+ \tShow this help and exit
+ ",
+ "-h, --help".bold().fg::<White>()
),
- format!("\t\t{}", "Path to config file used for current session."),
- format!("\t\t{}", "Takes precedence over standard config file."),
- format!(
- "\t{}{}",
- "--pdf-path=".bold().fg::<BrightCyan>(),
- "<value>".bold().italic().fg::<BrightCyan>()
+ formatdoc!(
+ "
+ \t{}
+ \tShow the version and exit
+ ",
+ "-v, --version".bold().fg::<White>()
),
- format!("\t\t{}", "Path to directory containing PDF files."),
- format!(
- "\t\t{}",
- "If the pdf files basename matches an entrys citekey,"
+ formatdoc!(
+ "
+ \t{}
+ \tEnable default colors for light terminal background
+ ",
+ "--light-terminal".bold().fg::<White>()
),
- format!(
- "\t\t{}",
- "its attached as connected PDF file for the current session."
+ formatdoc!(
+ "
+ \t{}{}
+ \tPath to config file used for current session.
+ \tTakes precedence over standard config file.
+ ",
+ "-c, --config-file=".bold().fg::<White>(),
+ "<value>".bold().italic().fg::<White>()
+ ),
+ formatdoc!(
+ "
+ \t{}{}
+ \tPath to directory containing PDF files.
+ \tIf the pdf files basename matches an entrys citekey,
+ \tits attached as connected PDF file for the current session.
+ \tDoes not edit the bibfile itself!
+ ",
+ "--pdf-path=".bold().fg::<White>(),
+ "<value>".bold().italic().fg::<White>()
),
- format!("\t\t{}", "Does not edit the bibfile itself!"),
];
let help = help.join("\n");
help
diff --git a/src/main.rs b/src/main.rs
index 58805d5..e735eb0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,7 +18,6 @@
use app::App;
use cliargs::CLIArgs;
use color_eyre::eyre::Result;
-use config::BibiConfig;
use errorsetup::init_error_hooks;
pub mod app;
@@ -31,13 +30,16 @@ pub mod tui;
#[tokio::main]
async fn main() -> Result<()> {
// Parse CLI arguments
- let (mut parsed_args, mut cfg) = CLIArgs::parse_args()?;
+ let (mut parsed_args, mut cfg, run_tui) = CLIArgs::parse_args()?;
- init_error_hooks()?;
+ if run_tui {
+ init_error_hooks()?;
- // Create an application.
- let mut app = App::new(&mut parsed_args, &mut cfg)?;
+ // Create an application.
+ let mut app = App::new(&mut parsed_args, &mut cfg)?;
+
+ app.run(&cfg).await?;
+ }
- app.run(&cfg).await?;
Ok(())
}