Open jooyoungseo opened 6 months ago
Thank you for your suggestion, this indeed is an interesting and useful feature. However, currently, I don't have time to implement it. I'm putting this on my todo list, and if anyone can help with a PR I'll be happy to review and merge it.
In the meantime, in my current setup, I'm using better bibtex's auto export feature, which can automatically export the entire library to a single .bib
file.
Here is a code sample for citing items in Zotero and adding them to bib
. I hope this helps!
import * as vscode from "vscode";
import Client, {
MultiReadResponse,
SingleReadResponse,
} from "zotero-api-client";
const apiKey = "KDRPW", userId = 123;
const zotero = new Client(apiKey).library("user", userId);
class Collection {
constructor(
public key: string,
public name: string,
public parentCollection: string | false
) {}
}
class Item {
constructor(
public key: string,
public name: string,
public doi: string,
public creators: object[]
) {}
}
type ZoteroObject = Collection | Item;
async function getTopCollections() {
const collections = await zotero.collections().top().get(),
data = (collections as MultiReadResponse).getData();
return data.map(
(c: any) => new Collection(c.key, c.name, c.parentCollection)
);
}
async function getSubCollections(collectionKey: string) {
const collections = await zotero
.collections(collectionKey)
.subcollections()
.get(),
data = (collections as MultiReadResponse).getData();
return data.map(
(c: any) => new Collection(c.key, c.name, c.parentCollection)
);
}
async function getItems(collectionKey: string) {
const items = await zotero.collections(collectionKey).items().top().get(),
data = (items as MultiReadResponse).getData();
return data.map((i: any) => new Item(i.key, i.title, i.doi, i.creators));
}
async function getItemInfo(itemKey: string) {
const item = await zotero.items(itemKey).get({ include: "bibtex" });
return (item as SingleReadResponse).getData();
}
function matchCiteKeys(bibtex: string) {
const regex = /@\S*?{\S*?,/g;
return bibtex.match(regex);
}
function getCiteKey(bibtex: string) {
const regex = /@\S*?{(\S*?),/;
return regex.exec(bibtex)?.[1];
}
async function citeItem(item: Item) {
const editor = vscode.window.activeTextEditor;
if (!editor) return;
const file = await vscode.workspace.findFiles("zotero.bib");
if (!file.length) return;
const info = await getItemInfo(item.key),
bibtex: string = (<any>info).bibtex,
citeKey = matchCiteKeys(bibtex)!,
doc = await vscode.workspace.openTextDocument(file[0]),
citeKeys = matchCiteKeys(doc.getText());
editor.edit((editBuilder) =>
editBuilder.insert(editor.selection.active, `\\cite{${getCiteKey(bibtex)}}`)
);
if (!citeKeys || !citeKeys.includes(citeKey[0])) {
const edit = new vscode.WorkspaceEdit(),
position = new vscode.Position(0, 0);
edit.insert(file[0], position, bibtex);
vscode.workspace.applyEdit(edit);
}
}
class SimpleTreeProvider implements vscode.TreeDataProvider<ZoteroObject> {
private _onDidChangeTreeData = new vscode.EventEmitter<undefined>();
readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
refresh(): void {
this._onDidChangeTreeData.fire(undefined);
}
getTreeItem(element: ZoteroObject): vscode.TreeItem {
const treeItem = new vscode.TreeItem(element.name);
treeItem.contextValue = element instanceof Item ? "item" : "collection";
treeItem.collapsibleState =
element instanceof Item
? vscode.TreeItemCollapsibleState.None
: vscode.TreeItemCollapsibleState.Collapsed;
return treeItem;
}
getChildren(element?: Collection) {
if (!element) return getTopCollections();
else
return Promise.all([
getSubCollections(element.key),
getItems(element.key),
]).then((arr) => arr.flat());
}
}
export function activate(context: vscode.ExtensionContext) {
const treeDataProvider = new SimpleTreeProvider();
vscode.window.createTreeView("latero", {
treeDataProvider,
showCollapseAll: true,
canSelectMany: true,
});
context.subscriptions.push(
vscode.commands.registerCommand("latero.cite", citeItem),
vscode.commands.registerCommand(
"latero.refresh",
treeDataProvider.refresh.bind(treeDataProvider)
)
);
}
Since Better BibTex is required anyway, you could use the auto-export to your project. Wouldn't that help?
Type: Feature Request
Using
Cite from Zotero
command, people can easily insert citations from their Zotero libraries.Once all the citations are inserted into tex file, could we generate a bib (default "./references.bib") file for the cited references?
I think this is technically possible as demonstrated in other extension, such as "XING.zotero-cite".
However, their extension does not support "vscode"citation method.
I believe this feature would be greatly appreciated by many Zotero+LaTeX users.
Extension version: 0.4.13 VS Code version: Code - Insiders 1.87.0-insider (c11a2dd4d52e38cb92b8c464f47a7b02bb7c8762, 2024-02-24T01:20:40.384Z) OS version: Windows_NT x64 10.0.22631 Modes: