From cf0c6b53c7884fa5407042f352d80e3cac2f578e Mon Sep 17 00:00:00 2001 From: Federico Granata <3602209+Edo78@users.noreply.github.com> Date: Sun, 30 Jan 2022 00:37:46 +0100 Subject: [PATCH] Feature/add commands (#35) * feat(commands): add commands to better interact with the plugin Close #34 * fix: twitter button in README.md * bump to 0.4.0 --- README.md | 20 ++++++-- manifest.json | 2 +- package-lock.json | 4 +- package.json | 2 +- src/main.ts | 114 +++++++++++++++++++++++++++++++++++++++++++--- versions.json | 3 +- 6 files changed, 131 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c8911f6..4990500 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ Sync [KOReader][1] notes in your [Obsidian][2] vault. The KOReader device must be connected to the device running obsidian to let the plugin scan through it's files. +In the beginning of each note there a series of YAML data knwon as Frontmatter. Those data are mainly used by the plugin itself (you can use them as shown in [dataview examples](#dataview-examples)) but messing with them will cause unexpected behaviour so use the provided [commands](#commands) to properly interact with them. + +When you're comfy reading your notes in obsidian think about how useful is this plugin to you and express your gratitude with a tweet or with a coffee :coffee: + +[![Twitter URL](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Ftext%3DI%2527m%2520enjoying%2520%2540Edo78%2527s%2520%2523Obsidian%2520plugin%2520to%2520sync%2520my%2520%2523KOReader%2520notes.%250AThank%2520you%2520for%2520your%2520great%2520work.%250A%250Ahttps%253A%252F%252Fgithub.com%252FEdo78%252Fobsidian-koreader-sync)](https://twitter.com/intent/tweet?text=I%27m%20enjoying%20%40Edo78%27s%20%23Obsidian%20plugin%20to%20sync%20my%20%23KOReader%20notes.%0AThank%20you%20for%20your%20great%20work.%0A%0Ahttps%3A%2F%2Fgithub.com%2FEdo78%2Fobsidian-koreader-sync) +Buy Me A Coffee + ## Configuration There ara four main settings: @@ -47,12 +54,19 @@ The query itself will embed the single notes and a CSS will hide every `h2` and **ATTENTION**: this feature require at least Obsidian v0.13.19 but there is a glitch that sometimes show only the filename of the notes instead of their contents. Try to close the note and open it again (sorry, not my fault) ## Usage -Once the plugin is configured properly you can plug the device with KOReader and click on the icon with two documents and the tooltip `KOReader Plugin`. The plugin should propmplty create a single file for each note. +Once the plugin is configured properly you can plug the device with KOReader and click on the icon with two documents and the tooltip `Sync your KOReader highlights`. The plugin should propmplty create a single file for each note. -Create an issue if something didn't work as expected. +### Commands +There are five commands: +- `Sync` it's the same as clicking on the plugin's icon, it's trigger the sync of the notes +- `Mark this note as Edited` set the frontmatter propery `yet_to_be_edited` to `false` (see [Note editing](#note-editing)) +- `Mark this note as NOT Edited` set the frontmatter propery `yet_to_be_edited` to `true` (see [Note editing](#note-editing)) +- `Enable Sync for this note` set the frontmatter propery `keep_in_sync` to `true` (see [sync](#sync)) +- `Disable Sync for this note` set the frontmatter propery `keep_in_sync` to `false` (see [sync](#sync)) ### Note editing If you chose to manually edit a note you are strongly raccomanded to change the frontmatter `yet_to_be_edited` value from `true` to `false` to let the plugin know that you altered something and to avoid any loss in case of [sync](#sync) +It's easier/safer to use the proper [commands](#commands) to do so instead of manually editing the frontmatter ### Sync **WARNING** Sync works by deleting a note and creating it again from KOReader. Anything added or updated (in Obsidian) will be lost _like tears in rain_. Consider yourself warned. @@ -68,7 +82,7 @@ Both needs to be `true` for the note to be synced. The default value for `keep_in_sync` is `false` so the default behaviour is that once a note is in obsidian it will never be synced again. -If you modify your notes in KOReader and want them to be synced in obsidian you have to enable the `Keep in sync` setting **OR** to manually change the `keep_in_sync` frontmatter of a specific note from `false` to `true` and if the `yet_to_be_edited` of that note is `true` then the note will be deleted and recreated. +If you modify your notes in KOReader and want them to be synced in obsidian you have to enable the `Keep in sync` setting **OR** use the proper [commands](#commands) to change the `keep_in_sync` frontmatter of a specific note from `false` to `true` and if the `yet_to_be_edited` of that note is `true` then the note will be deleted and recreated. ## Dataview examples Thanks to the frontmatter data in each note you can use Dataview to easily query your notes diff --git a/manifest.json b/manifest.json index 481bc4a..ee70978 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-koreader-plugin", "name": "KOReader Highlights", - "version": "0.3.0", + "version": "0.4.0", "minAppVersion": "0.13.19", "description": "This is a plugin for Obsidian. This plugin syncs highlights and notes taken in KOReader.", "author": "Federico \"Edo\" Granata", diff --git a/package-lock.json b/package-lock.json index dfa37f6..aa4fb9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "obsidian-koreader-plugin", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "obsidian-koreader-plugin", - "version": "0.3.0", + "version": "0.4.0", "license": "MIT", "dependencies": { "eta": "^1.12.3", diff --git a/package.json b/package.json index ad2e025..202cc9f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-koreader-plugin", - "version": "0.3.0", + "version": "0.4.0", "description": "This is a plugin for Obsidian. This plugin syncs highlights and notes taken in KOReader.", "main": "main.js", "scripts": { diff --git a/src/main.ts b/src/main.ts index 7ecdc15..1202fcd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,20 @@ +import * as crypto from 'crypto'; +import * as eta from 'eta'; + import { App, + Editor, + MarkdownView, Plugin, PluginSettingTab, Setting, - normalizePath, TAbstractFile, TFile, + normalizePath, } from 'obsidian'; -import * as matter from 'gray-matter'; -import * as crypto from 'crypto'; -import * as eta from 'eta'; +import matter from 'gray-matter'; import { Book, Bookmark, Books, FrontMatter } from './types'; + import { KOReaderMetadata } from './koreader-metadata'; interface KOReaderSettings { @@ -87,10 +91,66 @@ export default class KOReader extends Plugin { const ribbonIconEl = this.addRibbonIcon( 'documents', - 'KOReader Plugin', + 'Sync your KOReader highlights', this.importNotes.bind(this) ); + this.addCommand({ + id: 'obsidian-koreader-plugin-sync', + name: 'Sync', + callback: () => { + this.importNotes(); + }, + }); + + this.addCommand({ + id: 'obsidian-koreader-plugin-set-edit', + name: 'Mark this note as Edited', + editorCallback: (editor: Editor, view: MarkdownView) => { + this.setFrontmatterProperty( + `${[KOREADERKEY]}.metadata.yet_to_be_edited`, + false, + view + ); + }, + }); + + this.addCommand({ + id: 'obsidian-koreader-plugin-clear-edit', + name: 'Mark this note as NOT Edited', + editorCallback: (editor: Editor, view: MarkdownView) => { + this.setFrontmatterProperty( + `${[KOREADERKEY]}.metadata.yet_to_be_edited`, + true, + view + ); + }, + }); + + this.addCommand({ + id: 'obsidian-koreader-plugin-set-sync', + name: 'Enable Sync for this note', + editorCallback: (editor: Editor, view: MarkdownView) => { + this.setFrontmatterProperty( + `${[KOREADERKEY]}.metadata.keep_in_sync`, + true, + view + ); + }, + }); + + this.addCommand({ + id: 'obsidian-koreader-plugin-clear-sync', + name: 'Disable Sync for this note', + editorCallback: (editor: Editor, view: MarkdownView) => { + this.setFrontmatterProperty( + `${[KOREADERKEY]}.metadata.keep_in_sync`, + false, + view + ); + }, + }); + this.addSettingTab(new KoreaderSettingTab(this.app, this)); } @@ -104,6 +164,48 @@ export default class KOReader extends Plugin { await this.saveData(this.settings); } + private getObjectProperty(object: { [x: string]: any }, path: string) { + if (path === undefined || path === null) { + return object; + } + const parts = path.split('.'); + for (let i = 0; i < parts.length; ++i) { + if (object === undefined || object === null) { + return undefined; + } + const key = parts[i]; + object = object[key]; + } + return object; + } + + private setObjectProperty( + object: { [x: string]: any }, + path: string, + value: any + ) { + const parts = path.split('.'); + const limit = parts.length - 1; + for (let i = 0; i < limit; ++i) { + const key = parts[i]; + object = object[key] ?? (object[key] = {}); + } + const key = parts[limit]; + object[key] = value; + } + + async setFrontmatterProperty( + property: string, + value: any, + view: MarkdownView + ) { + const { data, content } = matter(view.data); + this.setObjectProperty(data, property, value); + const val = this.getObjectProperty(data, property); + const note = matter.stringify(content, data); + view.setViewData(note, false); + } + private async createNote(note: { path: string; uniqueId: string; @@ -215,7 +317,7 @@ return n['koreader-sync'] && n['koreader-sync'].type == 'koreader-sync-note' && ); } - async importNotes(evt: MouseEvent) { + async importNotes() { const metadata = new KOReaderMetadata(this.settings.koreaderBasePath); const data: Books = await metadata.scan(); diff --git a/versions.json b/versions.json index 57fc49a..096497d 100644 --- a/versions.json +++ b/versions.json @@ -11,5 +11,6 @@ "0.2.0": "0.12.0", "0.2.1": "0.12.0", "0.2.2": "0.12.0", - "0.3.0": "0.13.19" + "0.3.0": "0.13.19", + "0.4.0": "0.13.19" }