Write notes beside a PDF
Stage six. What you write goes into the note's ordinary content, so it is encrypted, versioned, linkable and searchable like any other note — a PDF note is a note with a document attached, not a separate kind of thing. The panel is composed from the editor pieces rather than reusing NoteEditor, which carries a whole drawing mode with its own canvas, tools and undo stack. The PDF already has a drawing layer; a second one behind the panel would be two places to draw with one of them invisible. Side by side on a wide screen, two tabs on a narrow one, and either half can be hidden — the second of the two toggles asked for. Reading the original without one's own marks in the way is a normal thing to want. The suite caught a real defect while checking this. A PDF note has two sources of searchable text — what the reader typed and what the document says — written at different moments by different code, both calling setEntry. Whichever ran last was the only searchable half: typing a note dropped the document's text, and reopening the document dropped the note. The index now holds the two apart and replaces only the half it is given, with six unit tests covering each direction, plus the snippet falling back to the document so a hit inside a PDF still shows its sentence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b12b0d6142
commit
7f9f39790f
8 files changed
+409
-16
No files matched your search
@@ -74,6 +74,58 @@ describe("search", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("attached document text", () => {
|
||||
/* A PDF note has two sources of text, written at different moments by
|
||||
* different code. Before these, whichever ran last was the only searchable
|
||||
* half — typing a note dropped the document, re-reading it dropped the note. */
|
||||
it("finds a note by a word from its attached document", () => {
|
||||
search.setEntry("p1", "Handbuch", body("Meine eigene Notiz."));
|
||||
search.setAttachedText("p1", "Handbuch", "Der Motor hat eine Zündkerze.");
|
||||
expect(search.search("Zündkerze")?.map((h) => h.id)).toEqual(["p1"]);
|
||||
search.removeEntry("p1");
|
||||
});
|
||||
|
||||
it("and by a word the user typed beside it", () => {
|
||||
search.setEntry("p1", "Handbuch", body("Meine eigene Notiz."));
|
||||
search.setAttachedText("p1", "Handbuch", "Der Motor hat eine Zündkerze.");
|
||||
expect(search.search("eigene")?.map((h) => h.id)).toEqual(["p1"]);
|
||||
search.removeEntry("p1");
|
||||
});
|
||||
|
||||
it("keeps the document text when the note is edited afterwards", () => {
|
||||
search.setAttachedText("p1", "Handbuch", "Der Motor hat eine Zündkerze.");
|
||||
search.setEntry("p1", "Handbuch", body("Ganz neuer Notiztext."));
|
||||
expect(search.search("Zündkerze")?.map((h) => h.id)).toEqual(["p1"]);
|
||||
expect(search.search("neuer")?.map((h) => h.id)).toEqual(["p1"]);
|
||||
search.removeEntry("p1");
|
||||
});
|
||||
|
||||
it("keeps the note when the document is re-read afterwards", () => {
|
||||
search.setEntry("p1", "Handbuch", body("Meine eigene Notiz."));
|
||||
search.setAttachedText("p1", "Handbuch", "Der Motor hat eine Zündkerze.");
|
||||
search.setAttachedText("p1", "Handbuch", "Der Motor hat eine Zündkerze und einen Riemen.");
|
||||
expect(search.search("eigene")?.map((h) => h.id)).toEqual(["p1"]);
|
||||
expect(search.search("Riemen")?.map((h) => h.id)).toEqual(["p1"]);
|
||||
search.removeEntry("p1");
|
||||
});
|
||||
|
||||
it("shows the sentence a document hit was found in, not an unrelated excerpt", () => {
|
||||
search.setEntry("p1", "Handbuch", body("Kurze Notiz."));
|
||||
search.setAttachedText("p1", "Handbuch", "Vorher. Der Motor hat eine Zündkerze. Nachher.");
|
||||
const hit = search.search("Zündkerze")?.[0];
|
||||
expect(hit?.snippet).toMatch(/Zündkerze/);
|
||||
search.removeEntry("p1");
|
||||
});
|
||||
|
||||
it("clears the attached text when it is set to empty", () => {
|
||||
search.setEntry("p1", "Handbuch", body("Notiz."));
|
||||
search.setAttachedText("p1", "Handbuch", "Zündkerze");
|
||||
search.setEntry("p1", "Handbuch", body("Notiz."), "");
|
||||
expect(search.search("Zündkerze")).toEqual([]);
|
||||
search.removeEntry("p1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("contentToText", () => {
|
||||
it("reads a v2 document", () => {
|
||||
expect(search.contentToText(body("hello world"))).toBe("hello world");
|
||||
|
||||
Reference in new issue
Block a user