Files
Marcos Paulo 5e8020aa38
ci / ci (macos-latest) (push) Has been cancelled
ci / ci (ubuntu-latest) (push) Has been cancelled
ci / ci (windows-latest) (push) Has been cancelled
feat: Obsidian basics, editor previews, graph rework, query blocks, stacked tabs, pop-out windows
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>
2026-10-19 11:21:19 -03:00

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");
}