mirror of
https://github.com/brokensandals/obsidian-paste-quote-plugin.git
synced 2026-07-22 12:00:32 +00:00
add Paste CSL YAML command
This commit is contained in:
parent
68ea31a7b1
commit
6c836dad39
2 changed files with 93 additions and 4 deletions
30
README.md
30
README.md
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
This is a small [Obsidian](https://obsidian.md/) plugin to help with formatting and citing quotations when pasting them from the clipboard. Currently, citation support only applies to quotes pasted from the Kindle app, and is focused on generating [Pandoc-style citations](https://pandoc.org/chunkedhtml-demo/8.20-citation-syntax.html).
|
||||
|
||||
## Formatting
|
||||
The plugin also contians a command to help paste references from e.g. Zotero into the `references` section of the note's front matter.
|
||||
|
||||
## Paste Quote command
|
||||
|
||||
### Formatting
|
||||
|
||||
Suppose you have this text on the clipboard:
|
||||
|
||||
|
|
@ -22,7 +26,7 @@ But if the cursor is in the middle of a line, then quotation marks will be added
|
|||
|
||||

|
||||
|
||||
## Citations
|
||||
### Citations
|
||||
|
||||
If you copy text from the Kindle app, you'll end up with something like this on your clipboard:
|
||||
|
||||
|
|
@ -43,3 +47,25 @@ If your document _does_ have a references section in its frontmatter, then the p
|
|||

|
||||
|
||||
![A sample document after pasting, which includes the quote and a citation in the format \[@pressfield2002, p. 40-41\]](docs/cite-refs-post.png)
|
||||
|
||||
## Paste CSL YAML command
|
||||
|
||||
Suppose you use [Zotero](https://www.zotero.org/) and [the Better BibTeX](https://retorque.re/zotero-better-bibtex/) plugin, and you select an entry there and use 'Copy as Better CSL YAML'. Then you'll have something like this on your clipboard:
|
||||
|
||||
```
|
||||
---
|
||||
references:
|
||||
- id: pressfield2002
|
||||
author:
|
||||
- family: Pressfield
|
||||
given: Steven
|
||||
citation-key: pressfield2002
|
||||
issued:
|
||||
- year: 2002
|
||||
publisher: Rugged Land, LLC
|
||||
title: The War of Art
|
||||
type: book
|
||||
...
|
||||
```
|
||||
|
||||
Running the `Paste CSL YAML` command will add the references from the clipboard into your note's front matter. The advantage over just pasting it directly into the front matter yourself is that if your note _already_ has a `references` section in its front matter, the command will add the new references onto the existing list, and will warn you if there are any duplicate IDs.
|
||||
67
main.ts
67
main.ts
|
|
@ -1,5 +1,5 @@
|
|||
import { Editor, MarkdownView, Plugin, TFile } from 'obsidian';
|
||||
import { parseQuote, Quote, replaceDoubleQuotes, guessCiteId } from 'src/quotes';
|
||||
import { Editor, MarkdownView, Plugin, TFile, parseYaml, Notice } from 'obsidian';
|
||||
import { parseQuote, Quote, replaceDoubleQuotes, guessCiteId, CslReference } from 'src/quotes';
|
||||
|
||||
export default class PasteQuotePlugin extends Plugin {
|
||||
async onload() {
|
||||
|
|
@ -8,6 +8,12 @@ export default class PasteQuotePlugin extends Plugin {
|
|||
name: 'Paste quote',
|
||||
editorCallback: this.pasteQuote.bind(this),
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: 'paste-csl-yaml',
|
||||
name: 'Paste CSL YAML',
|
||||
editorCallback: this.pasteCslYaml.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
async pasteQuote(editor: Editor, view: MarkdownView) {
|
||||
|
|
@ -60,6 +66,63 @@ export default class PasteQuotePlugin extends Plugin {
|
|||
return citation;
|
||||
}
|
||||
|
||||
async pasteCslYaml(editor: Editor, view: MarkdownView) {
|
||||
if (!view.file) {
|
||||
return;
|
||||
}
|
||||
|
||||
const clipboardText = await navigator.clipboard.readText();
|
||||
if (!clipboardText) {
|
||||
new Notice('Paste CSL YAML failed: there is no text on the clipboard');
|
||||
return;
|
||||
}
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = parseYaml(clipboardText);
|
||||
} catch (err) {
|
||||
new Notice("Paste CSL YAML failed: could not parse clipboard text as YAML");
|
||||
return;
|
||||
}
|
||||
|
||||
let references: CslReference[];
|
||||
if (Array.isArray(data.references) && data.references.length > 0 && data.references[0].id) {
|
||||
references = data.references;
|
||||
} else if (Array.isArray(data) && data.length > 0 && data[0].id) {
|
||||
references = data;
|
||||
} else if (data.id) {
|
||||
references = [data];
|
||||
} else {
|
||||
new Notice("Paste CSL YAML failed: clipboard content does not look like CSL (expected object(s) with 'id' keys, optionally under a 'references' key)")
|
||||
return;
|
||||
}
|
||||
|
||||
await this.app.fileManager.processFrontMatter(view.file, (frontmatter) => {
|
||||
if (frontmatter.references === undefined || frontmatter.references === null) {
|
||||
frontmatter.references = [];
|
||||
}
|
||||
if (!Array.isArray(frontmatter.references)) {
|
||||
new Notice("Paste CSL YAML failed: there is an existing 'references' field, but it is not an array");
|
||||
}
|
||||
|
||||
const oldIds = new Set((frontmatter.references || []).map((ref: CslReference) => ref.id));
|
||||
const skipped = [];
|
||||
|
||||
for (const ref of references) {
|
||||
if (oldIds.has(ref.id)) {
|
||||
skipped.push(ref.id);
|
||||
oldIds.add(ref.id); // in case there are duplicates within the pasted yaml
|
||||
} else {
|
||||
frontmatter.references.push(ref);
|
||||
}
|
||||
}
|
||||
|
||||
if (skipped.length > 0) {
|
||||
new Notice(`Paste CSL YAML skipped ${skipped.length} items because their IDs were already present`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue