diff --git a/src/clients.ts b/src/clients.ts index bb18299..4835b77 100644 --- a/src/clients.ts +++ b/src/clients.ts @@ -19,14 +19,16 @@ type ZoteroItemResponse = { }; }; -export class CiteReferenceClient { +export class CiteClient { private baseURL: string; private userID: number; + private style: string; - constructor(port: string){ + constructor(port: string, style: string){ this.baseURL = `http://127.0.0.1:${port}/api`; this.userID = 0; + this.style = style; } private async request(url: string): Promise { @@ -56,21 +58,15 @@ export class CiteReferenceClient { } - async getItemReference(itemKey: string): Promise { - - const url = `${this.baseURL}/users/${this.userID}/items/${itemKey}?format=json&include=citation` - - const item = await this.request(url); - - if (!item.citation) { - throw new Error(`No citation returned for item ${itemKey}`); - } - - return item.citation; + async getAllCitations(): Promise { + const url = `${this.baseURL}/users/${this.userID}/items?format=json&include=citation,data&style=${this.style}` + console.log(url) + return this.request(url); } - async getAllItems(): Promise { - const url = `${this.baseURL}/users/${this.userID}/items?format=json&include=citation,data&style=apa` + async getAllBibliographies(): Promise { + const url = `${this.baseURL}/users/${this.userID}/items?format=json&include=bib,data&style=${this.style}` + console.log(url) return this.request(url); } diff --git a/src/main.ts b/src/main.ts index d13f8f4..04e5307 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ import { App, Editor, MarkdownView, Modal, Plugin, Notice } from 'obsidian'; import { DEFAULT_SETTINGS, CiteSettings, CiteSettingTab } from "./settings"; -import { CiteReferenceModal } from "./modals" +import { CiteModal } from "./modals" export default class Cite extends Plugin { settings: CiteSettings; @@ -9,7 +9,7 @@ export default class Cite extends Plugin { await this.loadSettings(); - this.addRibbonIcon('scroll-text', 'cite', (evt: MouseEvent) => { + this.addRibbonIcon('scroll-text', 'insert citation', (evt: MouseEvent) => { const view = this.app.workspace.getActiveViewOfType(MarkdownView); if (!view) { @@ -20,22 +20,33 @@ export default class Cite extends Plugin { const editor = view.editor; - new CiteReferenceModal(this.app, this.settings.portSetting, this.settings.linkSetting, (citation: string) => { + new CiteModal(this.app, this.settings.portSetting, this.settings.linkSetting, this.settings.styleSetting, "citation", (citation: string) => { editor.replaceSelection(citation); }).open(); }); this.addCommand({ - id: 'citation-modal', - name: 'reference', + id: 'citation-command', + name: 'insert citation', editorCallback: (editor: Editor, view: MarkdownView) => { const selection = editor.getSelection(); - new CiteReferenceModal(this.app, this.settings.portSetting, this.settings.linkSetting, (citation: string) => { + new CiteModal(this.app, this.settings.portSetting, this.settings.linkSetting, this.settings.styleSetting, "citation",(citation: string) => { editor.replaceSelection(citation); }).open(); } }); + this.addCommand({ + id: 'bibliograpy-command', + name: 'insert bibliography', + editorCallback: (editor: Editor, view: MarkdownView) => { + const selection = editor.getSelection(); + new CiteModal(this.app, this.settings.portSetting, this.settings.linkSetting, this.settings.styleSetting, "bibliography",(bibliography: string) => { + editor.replaceSelection(bibliography); + }).open(); + } + }); + this.addSettingTab(new CiteSettingTab(this.app, this)); this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000)); diff --git a/src/modals.ts b/src/modals.ts index 186b39d..15b1633 100644 --- a/src/modals.ts +++ b/src/modals.ts @@ -1,44 +1,50 @@ import { App, FuzzyMatch, FuzzySuggestModal, renderResults, Notice } from 'obsidian'; -import {CiteReferenceClient, ZoteroItemResponse} from "./clients" +import {CiteClient, ZoteroItemResponse} from "./clients" -export class CiteReferenceModal extends FuzzySuggestModal { +export class CiteModal extends FuzzySuggestModal { private onChoose: (citation: string) => void; - private client: CiteReferenceClient; - private citations: ZoteroItemResponse[] = []; + private client: CiteClient; + private items: ZoteroItemResponse[] = []; private zoteroBaseUrl: string; private createLink: boolean; + private mode: string; constructor( app: App, port: string, createLink: boolean, + style: string, + mode: string, onChoose: (citation: string) => void, ) { super(app); - this.client = new CiteReferenceClient(port); + this.client = new CiteClient(port, style); this.onChoose = onChoose; this.setPlaceholder("Loading citations..."); this.zoteroBaseUrl = "zotero://select/library/items/"; this.createLink = createLink; + this.mode = mode; } async onOpen(){ super.onOpen(); try { - const items = await this.client.getAllItems(); + if (this.mode === "citation"){ + this.items = await this.client.getAllCitations(); + } else if (this.mode === "bibliography"){ + this.items = await this.client.getAllBibliographies(); + } else { + throw new Error(`Unknown mode: ${this.mode}`); + } - this.citations = items.filter( - (item): item is ZoteroItemResponse & { citation: string } => !!item.citation - ); - - this.setPlaceholder("Search citations..."); + this.setPlaceholder("Search Zotero..."); this.inputEl.disabled = false; this.inputEl.focus(); this.updateSuggestions(); } catch (error) { - new Notice("Failed to load citations from Zotero. Maybe you forgot to turn on or configure Zotero."); + new Notice("Failed to load citations/bibliographies from Zotero. Maybe you forgot to turn on or configure Zotero."); console.error(error); this.close(); } @@ -73,8 +79,15 @@ export class CiteReferenceModal extends FuzzySuggestModal { return item.key ?? "No Key"; } + private htmlToPlainText(html: string): string { + const div = document.createElement("div"); + div.innerHTML = html; + + return div.textContent?.trim() ?? ""; + } + getItems(): ZoteroItemResponse[] { - return this.citations; + return this.items; } getItemText(item: ZoteroItemResponse): string { @@ -96,16 +109,25 @@ export class CiteReferenceModal extends FuzzySuggestModal { renderResults(subtitleEl, `${author}, ${year}`, match.match, offset); } + onChooseItem(item: ZoteroItemResponse) { - if (!item.citation) { - throw new Error(`Missing citation for item ${item.key}`); - return; + + let output = ""; + + if (this.mode === "citation"){ + const raw = item.citation ?? ""; + output = this.htmlToPlainText(raw); + } else if (this.mode === "bibliography"){ + const raw = item.bib ?? ""; + output = this.htmlToPlainText(raw); + } else { + throw new Error(`Unknown mode: ${this.mode}`); } if (!this.createLink) { - this.onChoose(item.citation); + this.onChoose(output); } else { - this.onChoose(`[${item.citation}](${this.zoteroBaseUrl}${this.getKey(item)})`); + this.onChoose(`[${output}](${this.zoteroBaseUrl}${this.getKey(item)})`); } }