5e8020aa38
Editor previews (colour swatches, arrows, embeds), the 18 obsidian-basics tasks (find and replace with regex, back/forward, auto-pair, footnotes, folding, search operators, split view, PDF/audio/ video embeds, spelling, drag and drop, pinned tabs, settings) and round 2: ```query blocks, stacked tabs, pop-out windows, tasks ticked inside embeds, text around an embed, embeds that follow edits, block menu shortcut. New crates: notescraft-regex (linear-time engine) and notescraft-syntax. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
44 lines
2.7 KiB
Rust
44 lines
2.7 KiB
Rust
//! `Session::pdf_preview`: a page image from the system's renderer, cached in the vault.
|
|
|
|
mod common;
|
|
|
|
use common::temp_vault;
|
|
use notescraft_engine::Session;
|
|
|
|
/// A one-page PDF with a line of text.
|
|
const PDF: &str = "%PDF-1.1\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj\n3 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 200 100]/Contents 4 0 R/Resources<</Font<</F1 5 0 R>>>>>>endobj\n4 0 obj<</Length 44>>stream\nBT /F1 24 Tf 20 40 Td (Hello) Tj ET\nendstream\nendobj\n5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj\ntrailer<</Root 1 0 R>>\n%%EOF\n";
|
|
|
|
#[test]
|
|
fn a_pdf_page_becomes_a_cached_png_or_a_clear_error() {
|
|
let vault = temp_vault("pdf-preview");
|
|
std::fs::write(vault.path().join("doc.pdf"), PDF).expect("write");
|
|
let session = Session::open(vault.path()).expect("open");
|
|
assert!(session.pdf_preview("doc.pdf", 0).is_err(), "page numbers start at 1");
|
|
assert!(session.pdf_preview("../outside.pdf", 1).is_err());
|
|
match session.pdf_preview("doc.pdf", 1) {
|
|
Ok(png) => {
|
|
assert!(png.starts_with(b"\x89PNG"), "a PNG came back");
|
|
let cached = std::fs::read_dir(vault.path().join(".notescraft/cache")).expect("cache").count();
|
|
assert!(cached >= 1, "the image is cached");
|
|
assert_eq!(session.pdf_preview("doc.pdf", 1).expect("again"), png, "the second call reads the cache");
|
|
}
|
|
Err(error) => eprintln!("no PDF renderer on this machine: {error}"),
|
|
}
|
|
}
|
|
|
|
/// A two-page PDF: page 2 says "Second".
|
|
const TWO_PAGES: &str = "%PDF-1.1\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n2 0 obj<</Type/Pages/Kids[3 0 R 6 0 R]/Count 2>>endobj\n3 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 200 100]/Contents 4 0 R/Resources<</Font<</F1 5 0 R>>>>>>endobj\n4 0 obj<</Length 44>>stream\nBT /F1 24 Tf 20 40 Td (First) Tj ET\nendstream\nendobj\n5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj\n6 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 300 200]/Contents 7 0 R/Resources<</Font<</F1 5 0 R>>>>>>endobj\n7 0 obj<</Length 45>>stream\nBT /F1 24 Tf 20 40 Td (Second) Tj ET\nendstream\nendobj\ntrailer<</Root 1 0 R>>\n%%EOF\n";
|
|
|
|
#[test]
|
|
fn the_page_asked_for_is_the_page_rendered() {
|
|
let vault = temp_vault("pdf-pages");
|
|
std::fs::write(vault.path().join("two.pdf"), TWO_PAGES).expect("write");
|
|
let session = Session::open(vault.path()).expect("open");
|
|
let (Ok(first), Ok(second)) = (session.pdf_preview("two.pdf", 1), session.pdf_preview("two.pdf", 2)) else {
|
|
eprintln!("no PDF renderer able to pick a page on this machine");
|
|
return;
|
|
};
|
|
assert_ne!(first, second, "page 2 is a different image (it is also a different size)");
|
|
assert!(session.pdf_preview("two.pdf", 3).is_err(), "a page past the end is an error");
|
|
}
|