use spectre_parse::{Document, Object};
fn main() {
let path = std::env::args().nth(1).expect("usage: trace_one_outline <pdf>");
let bytes = std::fs::read(&path).expect("read");
let doc = Document::open(&bytes).expect("open");
let cat = doc.catalog().expect("catalog");
let outlines_ref = cat
.get(b"Outlines")
.expect("Outlines")
.as_reference()
.expect("Outlines ref");
let outlines = doc.get_dictionary(outlines_ref).expect("Outlines dict");
let first_ref = outlines
.get(b"First")
.expect("First")
.as_reference()
.expect("First ref");
let mut cur = Some(first_ref);
let mut count = 0;
while let Some(id) = cur {
if count >= 5 {
break;
}
count += 1;
let dict = match doc.get_dictionary(id) {
Ok(d) => d,
Err(e) => {
println!("err: {e}");
break;
}
};
let title = dict.get_optional(b"Title");
println!("--- entry #{count} (id={id:?}) ---");
println!(" Title: {title:?}");
if let Some(a_obj) = dict.get_optional(b"A") {
println!(" A: {a_obj:?}");
let action = match a_obj {
Object::Reference(aid) => doc.get_dictionary(*aid).ok(),
Object::Dictionary(d) => Some(d.clone()),
_ => None,
};
if let Some(action) = action {
let d = action.get_optional(b"D");
println!(" A.D: {d:?}");
let s = action.get_optional(b"S");
println!(" A.S: {s:?}");
}
}
if let Some(dest_obj) = dict.get_optional(b"Dest") {
println!(" Dest: {dest_obj:?}");
}
cur = dict
.get_optional(b"Next")
.and_then(|o| o.as_reference().ok());
}
}