diff --git a/README.md b/README.md index d6527ab..ec72b72 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,9 @@ You can make a [pull request](https://github.com/elias-sundqvist/obsidian-annota ## Changelog +### 0.1.2 (2021-09-11) *Quick Fix* +* Fixed critical bug that prevented any annotations from being saved. (See issue #61) + ### 0.1.1 (2021-09-10) *Drag & Drop Fixes, Open links in new pane, Multi-Line Comments Fix* * Drag and drop has been improved. The drop handlers are now unloaded when the plugin is unloaded. The issues regarding interferrence with other Drag and Drop functionality are hopefully also resolved. (See Issue #50) * Using an array format for the annotation target should now work. This improves compatibility with MetaEdit (See Issue #51) diff --git a/manifest.json b/manifest.json index 5fcb4c6..04416f0 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-annotator", "name": "Annotator", - "version": "0.1.1", + "version": "0.1.2", "minAppVersion": "0.9.12", "description": "This is a sample plugin for Obsidian. It allows you to open and annotate PDF and EPUB files.", "author": "Obsidian", diff --git a/package.json b/package.json index bcdd29a..89493f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-annotator", - "version": "0.1.0", + "version": "0.1.2", "description": "This is a sample plugin for Obsidian (https://obsidian.md)", "main": "main.js", "scripts": { diff --git a/src/annotationFileUtils.tsx b/src/annotationFileUtils.tsx index ccac3c8..d3e2bb6 100644 --- a/src/annotationFileUtils.tsx +++ b/src/annotationFileUtils.tsx @@ -17,12 +17,16 @@ export async function writeAnnotation(annotation: Annotation, plugin: AnnotatorP const vault = plugin.app.vault; const tfile = vault.getAbstractFileByPath(annotationFilePath); + let res: ReturnType; if (tfile instanceof TFile) { const text = await vault.read(tfile); - return writeAnnotationToAnnotationFileString(annotation, text, plugin).newAnnotation; + res = writeAnnotationToAnnotationFileString(annotation, text, plugin); + vault.modify(tfile, res.newAnnotationFileString); } else { - return writeAnnotationToAnnotationFileString(annotation, null, plugin).newAnnotation; + res = writeAnnotationToAnnotationFileString(annotation, null, plugin); + vault.create(annotationFilePath, res.newAnnotationFileString); } + return res.newAnnotation; } export async function loadAnnotations( @@ -52,6 +56,7 @@ export async function deleteAnnotation( const text = await vault.read(tfile); const updatedText = deleteAnnotationFromAnnotationFileString(annotationId, text); if (text !== updatedText) { + vault.modify(tfile, updatedText); return { deleted: true, id: annotationId diff --git a/src/annotationUtils.tsx b/src/annotationUtils.tsx index 59bf86f..1552798 100644 --- a/src/annotationUtils.tsx +++ b/src/annotationUtils.tsx @@ -139,7 +139,7 @@ export const stripDefaultValues = (obj: Record, defaultObj: Rec const strippedObject: Record = {}; const toIgnore = ['group', 'permissions', 'user', 'user_info']; for (const key of Object.keys(obj)) { - if (JSON.stringify(obj[key]) !== JSON.stringify(defaultObj[key]) && !toIgnore.contains(key)) { + if (JSON.stringify(obj[key]) !== JSON.stringify(defaultObj[key]) && !toIgnore.includes(key)) { strippedObject[key] = obj[key]; } } @@ -166,7 +166,7 @@ export function writeAnnotationToAnnotationFileString( if (!didReplace) { annotationFileString = `${annotationFileString}\n${annotationString}`; } - return { newAnnotationFileString: annotationString, newAnnotation: res }; + return { newAnnotationFileString: annotationFileString, newAnnotation: res }; } else { return { newAnnotationFileString: annotationString, newAnnotation: res }; } diff --git a/tests/annotationUtils.test.ts b/tests/annotationUtils.test.ts index bced363..2e3fc58 100644 --- a/tests/annotationUtils.test.ts +++ b/tests/annotationUtils.test.ts @@ -1,13 +1,58 @@ import fs from "fs"; import path from "path"; import * as annotationUtils from "../src/annotationUtils"; +import { Annotation } from '../src/types'; +import { IHasAnnotatorSettings } from '../src/main'; + +const testAnnotatorSettings: IHasAnnotatorSettings = { + settings: { + deafultDarkMode: false, + darkReaderSettings: null, + customDefaultPath: null, + annotationMarkdownSettings: { + includePostfix: true, + includePrefix: true, + highlightHighlightedText: true + } + } +} + +function loadMd(mdfile: string) { + const mdTestFilePath = path.join(__dirname, "./", mdfile); + return fs.readFileSync(mdTestFilePath, {encoding: "utf8"}).replaceAll('\r\n','\n'); +} + +function loadJson(jsonfile: string) { + const jsonTestFilePath = path.join(__dirname, "./", jsonfile); + return fs.readFileSync(jsonTestFilePath, {encoding: "utf8"}); +} -const mdTestFilePath = path.join(__dirname, "./", "testfile.md"); -const mdTestFile = fs.readFileSync(mdTestFilePath, {encoding: "utf8"}).replaceAll('\r\n','\n'); -const jsonTestFilePath = path.join(__dirname, "./", "testfile.json"); -const jsonTestFile = fs.readFileSync(jsonTestFilePath, {encoding: "utf8"}); test("AnnotationShouldBeCorrectlyParsed", ()=>{ - const loadedAnnotations = annotationUtils.loadAnnotationsAtUriFromFileText(null, mdTestFile) + const mdTestFile = loadMd("testfile.md"); + const jsonTestFile = loadJson("testfile.json"); + const loadedAnnotations = annotationUtils.loadAnnotationsAtUriFromFileText(null, mdTestFile); expect(JSON.parse(jsonTestFile)).toEqual(loadedAnnotations); +}) + +test("AnnotationsCanBeModified", ()=>{ + const mdTestFile = loadMd("testfile2.md"); + const loadedAnnotations = annotationUtils.loadAnnotationsAtUriFromFileText(null, mdTestFile); + const modifiedAnnotation: Annotation = {...JSON.parse(JSON.stringify(loadedAnnotations.rows[0])), text: "this is a modified comment"}; + const res = annotationUtils.writeAnnotationToAnnotationFileString(modifiedAnnotation, mdTestFile, testAnnotatorSettings); + const loadedModifiedAnnotations = annotationUtils.loadAnnotationsAtUriFromFileText(null, res.newAnnotationFileString); + expect(loadedModifiedAnnotations.total).toEqual(loadedAnnotations.total); + expect(loadedModifiedAnnotations.rows[0]).toEqual(modifiedAnnotation); + const drop1 = ([arr, ...rest]: Annotation[])=>rest; + expect(drop1(loadedAnnotations.rows)).toEqual(drop1(loadedModifiedAnnotations.rows)); +}) + +test("AnnotationsCanBeAdded", ()=>{ + const mdTestFile = loadMd("testfile2.md"); + const loadedAnnotations = annotationUtils.loadAnnotationsAtUriFromFileText(null, mdTestFile); + const newAnnotation: Annotation = {...JSON.parse(JSON.stringify(loadedAnnotations.rows[0])), id: 'anewid'}; + const res = annotationUtils.writeAnnotationToAnnotationFileString(newAnnotation, mdTestFile, testAnnotatorSettings); + const loadedModifiedAnnotations = annotationUtils.loadAnnotationsAtUriFromFileText(null, res.newAnnotationFileString); + expect(loadedModifiedAnnotations.total).toEqual(loadedAnnotations.total+1); + expect(loadedModifiedAnnotations.rows).toEqual([...loadedAnnotations.rows, newAnnotation]); }) \ No newline at end of file diff --git a/tests/testfile2.md b/tests/testfile2.md new file mode 100644 index 0000000..2fbe0b2 --- /dev/null +++ b/tests/testfile2.md @@ -0,0 +1,56 @@ +annotation-target:: TIF160+CourseIntro+2021.pdf + +>%% +>```annotation-json +>{"created":"2021-08-31T19:14:06.862Z","updated":"2021-08-31T19:14:06.862Z","uri":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","document":{"title":"TIF160/FIM800 Humanoid robotics -Course introduction-","link":[{"href":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729"}],"documentFingerprint":"522f388ebd51503bb23c2db5991d6729"},"target":[{"source":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","selector":[{"type":"TextPositionSelector","start":98,"end":121},{"type":"TextQuoteSelector","exact":"Mechanics and Maritime ","prefix":"ssociate professorDepartment of ","suffix":"SciencesChalmers University of T"}]}]} +>``` +>%% +>*%%PREFIX%%ssociate professorDepartment of%%HIGHLIGHT%% ==Mechanics and Maritime== %%POSTFIX%%SciencesChalmers University of T* +>%%LINK%%[[#^ghrcuqkctcn|show annotation]] +>%%COMMENT%% +> +>%%TAGS%% +> +^ghrcuqkctcn + + +>%% +>```annotation-json +>{"text":"testie ball","target":[{"source":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","selector":[{"type":"TextPositionSelector","start":32,"end":51},{"type":"TextQuoteSelector","exact":"Course introduction","prefix":"TIF160/FIM800 Humanoid robotics-","suffix":"-Krister WolffAssociate professo"}]}],"created":"2021-09-01T14:48:59.315Z","updated":"2021-09-01T14:48:59.315Z","uri":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","document":{"title":"TIF160/FIM800 Humanoid robotics -Course introduction-","link":[{"href":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729"}],"documentFingerprint":"522f388ebd51503bb23c2db5991d6729"}} +>``` +>%% +>*%%HIGHLIGHT%% ==Course introduction== * +>%%LINK%%[[#^0lj0rg85p8y9|show annotation]] +>%%COMMENT%% +>testie ball +>%%TAGS%% +> +^0lj0rg85p8y9 + + +>%% +>```annotation-json +>{"created":"2021-09-03T13:35:28.431Z","updated":"2021-09-03T13:35:28.431Z","uri":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","document":{"title":"TIF160/FIM800 Humanoid robotics -Course introduction-","link":[{"href":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729"}],"documentFingerprint":"522f388ebd51503bb23c2db5991d6729"},"target":[{"source":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","selector":[{"type":"TextPositionSelector","start":6212,"end":6232},{"type":"TextQuoteSelector","exact":"Contribution outside","prefix":"to contribute to team meetings,I","suffix":" of team meetings,IShow confiden"}]}]} +>``` +>%% +>*%%HIGHLIGHT%% ==Contribution outside== * +>%%LINK%%[[#^undefined|show annotation]] +>%%COMMENT%% +> +>%%TAGS%% +> +^chill + + +>%% +>```annotation-json +>{"created":"2021-09-03T13:42:22.993Z","updated":"2021-09-03T13:42:22.993Z","uri":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","document":{"title":"TIF160/FIM800 Humanoid robotics -Course introduction-","link":[{"href":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729"}],"documentFingerprint":"522f388ebd51503bb23c2db5991d6729"},"target":[{"source":"urn:x-pdf:522f388ebd51503bb23c2db5991d6729","selector":[{"type":"TextPositionSelector","start":6642,"end":6655},{"type":"TextQuoteSelector","exact":"Krister Wolff","prefix":"tics Compendium(draft version)by","suffix":"Please note:This is awork in pro"}]}]} +>``` +>%% +>*%%HIGHLIGHT%% ==Krister Wolff== * +>%%LINK%%[[#^pt6evw5pjd|show annotation]] +>%%COMMENT%% +> +>%%TAGS%% +> +^pt6evw5pjd diff --git a/versions.json b/versions.json index 16a868f..c876a2b 100644 --- a/versions.json +++ b/versions.json @@ -9,5 +9,6 @@ "0.0.8": "0.9.12", "0.0.9": "0.9.12", "0.1.0": "0.9.12", - "0.1.1": "0.9.12" + "0.1.1": "0.9.12", + "0.1.2": "0.9.12" }