feat: add insert bibliography, fix: html escape in citations
This commit is contained in:
+11
-15
@@ -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<T>(url: string): Promise<T> {
|
||||
@@ -56,21 +58,15 @@ export class CiteReferenceClient {
|
||||
|
||||
}
|
||||
|
||||
async getItemReference(itemKey: string): Promise<string> {
|
||||
|
||||
const url = `${this.baseURL}/users/${this.userID}/items/${itemKey}?format=json&include=citation`
|
||||
|
||||
const item = await this.request<ZoteroItemResponse>(url);
|
||||
|
||||
if (!item.citation) {
|
||||
throw new Error(`No citation returned for item ${itemKey}`);
|
||||
}
|
||||
|
||||
return item.citation;
|
||||
async getAllCitations(): Promise<ZoteroItemResponse[]> {
|
||||
const url = `${this.baseURL}/users/${this.userID}/items?format=json&include=citation,data&style=${this.style}`
|
||||
console.log(url)
|
||||
return this.request<ZoteroItemResponse[]>(url);
|
||||
}
|
||||
|
||||
async getAllItems(): Promise<ZoteroItemResponse[]> {
|
||||
const url = `${this.baseURL}/users/${this.userID}/items?format=json&include=citation,data&style=apa`
|
||||
async getAllBibliographies(): Promise<ZoteroItemResponse[]> {
|
||||
const url = `${this.baseURL}/users/${this.userID}/items?format=json&include=bib,data&style=${this.style}`
|
||||
console.log(url)
|
||||
return this.request<ZoteroItemResponse[]>(url);
|
||||
}
|
||||
|
||||
|
||||
+17
-6
@@ -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));
|
||||
|
||||
+40
-18
@@ -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<ZoteroItemResponse> {
|
||||
export class CiteModal extends FuzzySuggestModal<ZoteroItemResponse> {
|
||||
|
||||
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<ZoteroItemResponse> {
|
||||
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<ZoteroItemResponse> {
|
||||
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)})`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user