use indexmap crate for sorted output
This commit is contained in:
parent
928887c1a3
commit
40c40f83d6
3 changed files with 88 additions and 11 deletions
72
Cargo.lock
generated
72
Cargo.lock
generated
|
@ -12,11 +12,19 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
|||
name = "broot"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"open",
|
||||
"pulldown-cmark",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
|
@ -26,18 +34,82 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-docker"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-wsl"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
|
||||
dependencies = [
|
||||
"is-docker",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "open"
|
||||
version = "5.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95"
|
||||
dependencies = [
|
||||
"is-wsl",
|
||||
"libc",
|
||||
"pathdiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
|
|
|
@ -6,6 +6,8 @@ description = "Markdown to JSON bookmark opener."
|
|||
authors = ["Troy Lusty <hello@troylusty.com>"]
|
||||
|
||||
[dependencies]
|
||||
indexmap = "2.9.0"
|
||||
open = "5.3.2"
|
||||
pulldown-cmark = "0.13.0"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_json = "1.0.140"
|
||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -1,6 +1,6 @@
|
|||
use indexmap::IndexMap;
|
||||
use pulldown_cmark::{Event, LinkType, Parser, Tag, TagEnd};
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
|
@ -13,27 +13,27 @@ struct Link {
|
|||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let path = env::args().nth(1).unwrap_or_else(|| {
|
||||
eprintln!("❌ Usage: select_bookmark <input.md>");
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
||||
let path = env::args()
|
||||
.nth(1)
|
||||
.expect("❌ Usage: select_bookmark <input.md>");
|
||||
let markdown = fs::read_to_string(path)?;
|
||||
let parser = Parser::new(&markdown);
|
||||
|
||||
let mut links_by_heading: HashMap<String, Vec<Link>> = HashMap::new();
|
||||
let mut current_heading = "No Heading".to_string();
|
||||
let mut links_by_heading: IndexMap<String, Vec<Link>> = IndexMap::new();
|
||||
let mut current_heading = String::from("No Heading");
|
||||
let mut heading_buf = String::new();
|
||||
let mut current_link: Option<Link> = None;
|
||||
|
||||
for event in parser {
|
||||
match event {
|
||||
Event::Start(Tag::Heading { .. }) => heading_buf.clear(),
|
||||
|
||||
Event::End(TagEnd::Heading(_)) => {
|
||||
if !heading_buf.trim().is_empty() {
|
||||
current_heading = heading_buf.trim().to_string();
|
||||
current_heading = heading_buf.trim().to_owned();
|
||||
}
|
||||
}
|
||||
|
||||
Event::Start(Tag::Link {
|
||||
link_type: LinkType::Inline,
|
||||
dest_url,
|
||||
|
@ -44,6 +44,7 @@ fn main() -> std::io::Result<()> {
|
|||
title: String::new(),
|
||||
});
|
||||
}
|
||||
|
||||
Event::End(TagEnd::Link) => {
|
||||
if let Some(link) = current_link.take() {
|
||||
links_by_heading
|
||||
|
@ -52,6 +53,7 @@ fn main() -> std::io::Result<()> {
|
|||
.push(link);
|
||||
}
|
||||
}
|
||||
|
||||
Event::Text(text) => {
|
||||
if let Some(link) = current_link.as_mut() {
|
||||
link.title.push_str(&text);
|
||||
|
@ -59,6 +61,7 @@ fn main() -> std::io::Result<()> {
|
|||
heading_buf.push_str(&text);
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -92,11 +95,11 @@ fn main() -> std::io::Result<()> {
|
|||
}
|
||||
|
||||
let output = child.wait_with_output()?;
|
||||
let selected = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||
let selected = String::from_utf8_lossy(&output.stdout).trim().to_owned();
|
||||
|
||||
if let Some((_, url)) = entries.iter().find(|(label, _)| label == &selected) {
|
||||
println!("🌐 Opening: {}", url);
|
||||
Command::new("xdg-open").arg(url).spawn()?;
|
||||
open::that(url)?;
|
||||
} else {
|
||||
println!("❌ Selection not found or canceled.");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue