diff --git a/manifest.json b/manifest.json index b9a845f..86082b9 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "bookfusion", "name": "BookFusion", - "version": "1.0.3", + "version": "1.0.4", "minAppVersion": "0.15.0", "description": "Import your BookFusion highlights & annotations into your vault.", "author": "BookFusion", diff --git a/package.json b/package.json index 8af2cc4..f96176f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bookfusion/obsidian-plugin", - "version": "1.0.3", + "version": "1.0.4", "description": "Import your BookFusion (https://www.bookfusion.com) highlights into Obsidian (https://obsidian.md).", "main": "main.js", "scripts": { diff --git a/src/pages_processor.ts b/src/pages_processor.ts index abaab59..bc420fc 100644 --- a/src/pages_processor.ts +++ b/src/pages_processor.ts @@ -1,10 +1,9 @@ import { App, TFile, TFolder, normalizePath } from 'obsidian' -import { AtomicHighlightPage, BookPage, HighlightBlock, IndexPage, Page } from './bookfusion_api' +import { BookPage, IndexPage, Page } from './bookfusion_api' import { BookFusionPlugin } from './plugin' import AppendStrategy from './update_strategy/append_strategy' import ReplaceStrategy from './update_strategy/replace_strategy' import UpdateStrategy from './update_strategy/update_strategy' -import { formatHighlightContent, formatHighlightLink, wrapWithMagicComment } from './utils' import SmartStrategy from './update_strategy/smart_strategy' export default class PageProcessor { @@ -71,42 +70,7 @@ export default class PageProcessor { } private async createBookPage (page: BookPage, filePath: string): Promise { - let content = wrapWithMagicComment(page.id, String(page.content)) - - if (page.frontmatter != null) { - content = `---\n${page.frontmatter}\n---\n${content}\n` - } - - if (page.highlights.length > 0) { - if (page.atomic_highlights) { - for (const highlight of page.highlights as AtomicHighlightPage[]) { - content += wrapWithMagicComment(highlight.id, formatHighlightLink(highlight)) - - const dirPath = normalizePath(highlight.directory) - const directory = this.app.vault.getAbstractFileByPath(dirPath) - - if (!(directory instanceof TFolder)) { - await this.plugin.tryCreateFolder(dirPath) - } - - await this.app.vault.create(normalizePath(`${dirPath}/${highlight.filename}`), highlight.content) - - this.plugin.events.emit('highlightModified', { filePath }) - } - } else { - for (const highlight of page.highlights as HighlightBlock[]) { - content += wrapWithMagicComment(highlight.id, formatHighlightContent(highlight)) - - this.plugin.events.emit('highlightModified', { filePath }) - } - } - } - - const file = await this.app.vault.create(filePath, content) - - this.plugin.events.emit('bookCreated', { filePath }) - - return file + return await this.buildStrategy(page).createBookPage(page, filePath) } private async modifyBookPage (page: BookPage, file: TFile): Promise { diff --git a/src/update_strategy/append_strategy.ts b/src/update_strategy/append_strategy.ts index 3a76723..85b7040 100644 --- a/src/update_strategy/append_strategy.ts +++ b/src/update_strategy/append_strategy.ts @@ -1,7 +1,6 @@ import { TFile, normalizePath } from 'obsidian' import { AtomicHighlightPage, BookPage, HighlightBlock } from 'src/bookfusion_api' import UpdateStrategy from './update_strategy' -import { wrapWithMagicComment } from 'src/utils' export default class AppendStrategy extends UpdateStrategy { async modifyBookPage (page: BookPage, file: TFile): Promise { @@ -12,12 +11,12 @@ export default class AppendStrategy extends UpdateStrategy { } if (page.atomic_highlights) { - const formatter = (highlight: AtomicHighlightPage): string => wrapWithMagicComment(highlight.id, highlight.link) + const formatter = (highlight: AtomicHighlightPage): string => this.wrapWithMagicComment(highlight.id, highlight.link) await this.appendAtomicHighlights(highlights as AtomicHighlightPage[], file) await this.appendHighlights(highlights as AtomicHighlightPage[], file, formatter) } else { - const formatter = (highlight: HighlightBlock): string => wrapWithMagicComment(highlight.id, highlight.content) + const formatter = (highlight: HighlightBlock): string => this.wrapWithMagicComment(highlight.id, highlight.content) await this.appendHighlights(highlights as HighlightBlock[], file, formatter) } diff --git a/src/update_strategy/replace_strategy.ts b/src/update_strategy/replace_strategy.ts index 3d2b02e..7fbaebf 100644 --- a/src/update_strategy/replace_strategy.ts +++ b/src/update_strategy/replace_strategy.ts @@ -1,7 +1,7 @@ import { TFile, normalizePath } from 'obsidian' import { AtomicHighlightPage, BookPage, HighlightBlock, SomeHighlight } from 'src/bookfusion_api' import UpdateStrategy from './update_strategy' -import { formatHighlightContent, formatHighlightLink, wrapWithMagicComment } from 'src/utils' +import { formatHighlightContent, formatHighlightLink } from 'src/utils' export default class ReplaceStrategy extends UpdateStrategy { async modifyBookPage (page: BookPage, file: TFile): Promise { @@ -11,14 +11,14 @@ export default class ReplaceStrategy extends UpdateStrategy { if (page.atomic_highlights) { const formatter = (highlight: AtomicHighlightPage): string => { - return wrapWithMagicComment(highlight.id, formatHighlightLink(highlight)) + return formatHighlightLink(highlight) } await this.appendHighlights(highlights as HighlightBlock[], file, formatter) await this.replaceAtomicHighlights(highlights as AtomicHighlightPage[]) } else { const formatter = (highlight: HighlightBlock): string => { - return wrapWithMagicComment(highlight.id, formatHighlightContent(highlight)) + return formatHighlightContent(highlight) } await this.appendHighlights(highlights as HighlightBlock[], file, formatter) @@ -64,9 +64,13 @@ export default class ReplaceStrategy extends UpdateStrategy { } for (const highlight of highlights) { - await this.app.vault.append(file, formatter(highlight)) + await this.app.vault.append(file, formatter(highlight) + '\n') } this.plugin.events.emit('highlightModified', { filePath: file.path, count: highlights.length }) } + + protected wrapWithMagicComment (id: string, content: string): string { + return content + '\n' + } } diff --git a/src/update_strategy/smart_strategy.ts b/src/update_strategy/smart_strategy.ts index f479ba9..1fc3de5 100644 --- a/src/update_strategy/smart_strategy.ts +++ b/src/update_strategy/smart_strategy.ts @@ -1,8 +1,9 @@ -import { App, TFile, normalizePath } from 'obsidian' +import { App, TFile, normalizePath, parseYaml } from 'obsidian' import { AtomicHighlightPage, BookPage, HighlightBlock, SomeHighlight } from 'src/bookfusion_api' import UpdateStrategy from './update_strategy' -import { DoublyLinkedList, ListNode, formatHighlightContent, formatHighlightLink, replaceBlock, wrapWithMagicComment } from 'src/utils' +import { DoublyLinkedList, ListNode, formatHighlightContent, formatHighlightLink, replaceBlock } from 'src/utils' import BookFusionPlugin from 'main' +import logger from 'src/logger' interface ExtractedHighlight { id: string @@ -16,6 +17,9 @@ interface UpdateResult { } export default class SmartStrategy extends UpdateStrategy { + /** + * Switch Magic Update / Smart Insert + */ replace: boolean constructor (plugin: BookFusionPlugin, app: App, replace: boolean = true) { @@ -49,6 +53,24 @@ export default class SmartStrategy extends UpdateStrategy { const content = await this.app.vault.read(file) const newContent = replaceBlock(content, page.id, String(page.content)) + if (this.replace) { + try { + let oldFrontMatter, newFrontMatter + await this.app.fileManager.processFrontMatter(file, (frontmatter) => { + oldFrontMatter = JSON.stringify(frontmatter) + Object.assign(frontmatter, parseYaml(String(page.frontmatter))) + newFrontMatter = JSON.stringify(frontmatter) + }) + + if (oldFrontMatter !== newFrontMatter) { + this.plugin.events.emit('bookModified', { filePath: file.path }) + } + } catch (error) { + logger.error(error) + this.plugin.events.emit('bookFailed', { filePath: file.path, error }) + } + } + if (content.trim() !== newContent.trim()) { await this.app.vault.modify(file, newContent) this.plugin.events.emit('bookModified', { filePath: file.path }) @@ -77,7 +99,7 @@ export default class SmartStrategy extends UpdateStrategy { this.plugin.events.emit('highlightModified', { filePath: file.path }) } } else if (highlightFile == null) { - await this.app.vault.create(filePath, wrapWithMagicComment(highlight.id, highlight.content)) + await this.app.vault.create(filePath, this.wrapWithMagicComment(highlight.id, highlight.content)) this.plugin.events.emit('highlightModified', { filePath: file.path }) } } @@ -119,7 +141,7 @@ export default class SmartStrategy extends UpdateStrategy { continue } - const value = { id: highlight.id, index: -1, text: wrapWithMagicComment(highlight.id, highlightContent) } + const value = { id: highlight.id, index: -1, text: this.wrapWithMagicComment(highlight.id, highlightContent) } if (highlight.next != null) { target = nodesMap.get(highlight.next) diff --git a/src/update_strategy/update_strategy.ts b/src/update_strategy/update_strategy.ts index d116a8a..1ee2a25 100644 --- a/src/update_strategy/update_strategy.ts +++ b/src/update_strategy/update_strategy.ts @@ -1,6 +1,7 @@ import BookFusionPlugin from 'main' -import { App, TFile } from 'obsidian' -import { BookPage } from 'src/bookfusion_api' +import { App, TFile, TFolder, normalizePath } from 'obsidian' +import { AtomicHighlightPage, BookPage, HighlightBlock } from 'src/bookfusion_api' +import { formatHighlightContent, formatHighlightLink, wrapWithMagicComment } from '../utils' export type UpdateStrategyId = 'append' | 'replace' | 'magic' | 'insert' @@ -13,7 +14,48 @@ export default abstract class UpdateStrategy { this.app = app } + async createBookPage (page: BookPage, filePath: string): Promise { + let content = this.wrapWithMagicComment(page.id, String(page.content)) + + if (page.frontmatter != null) { + content = `---\n${page.frontmatter}\n---\n${content}\n` + } + + if (page.highlights.length > 0) { + if (page.atomic_highlights) { + for (const highlight of page.highlights as AtomicHighlightPage[]) { + content += this.wrapWithMagicComment(highlight.id, formatHighlightLink(highlight)) + + const dirPath = normalizePath(highlight.directory) + const directory = this.app.vault.getAbstractFileByPath(dirPath) + + if (!(directory instanceof TFolder)) { + await this.plugin.tryCreateFolder(dirPath) + } + + await this.app.vault.create(normalizePath(`${dirPath}/${highlight.filename}`), highlight.content) + } + } else { + for (const highlight of page.highlights as HighlightBlock[]) { + content += this.wrapWithMagicComment(highlight.id, formatHighlightContent(highlight)) + } + } + + this.plugin.events.emit('highlightModified', { filePath }) + } + + const file = await this.app.vault.create(filePath, content) + + this.plugin.events.emit('bookCreated', { filePath }) + + return file + } + async modifyBookPage (page: BookPage, file: TFile): Promise { throw new Error('Method not implemented.') } + + protected wrapWithMagicComment (id: string, content: string): string { + return wrapWithMagicComment(id, content) + '\n' + } } diff --git a/src/utils.ts b/src/utils.ts index 1f246dc..663ee97 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ import { AtomicHighlightPage, HighlightBlock } from './bookfusion_api' export function wrapWithMagicComment (id: string, content: string): string { - return `%%begin-${id}%%\n${content}\n%%end-${id}%%\n\n` + return `%%begin-${id}%%\n${content}\n%%end-${id}%%\n` } export function replaceBlock (content: string, id: string, fragment: string): string { diff --git a/versions.json b/versions.json index ca35501..0438402 100644 --- a/versions.json +++ b/versions.json @@ -2,5 +2,6 @@ "1.0.0": "0.15.0", "1.0.1": "0.15.0", "1.0.2": "0.15.0", - "1.0.3": "0.15.0" + "1.0.3": "0.15.0", + "1.0.4": "0.15.0" }