[Share]用其他程序打开PDF(Open PDF with specific application) #132
Replies: 11 comments 30 replies
-
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
|
Thank you very much! So something similar to this: https://github.com/retorquere/zotero-open-pdf |
Beta Was this translation helpful? Give feedback.
-
|
您好,这个动作只能“选中PDF条目-执行”才有效,能不能改进一下,使得“选中父条目-执行”也可以打开PDF? |
Beta Was this translation helpful? Give feedback.
-
|
楼主好 方案1: 方案2: if(item) return;
const window = require("window");
const ZoteroPane = require("ZoteroPane");
async function getPDFAttachmentPath(item) {
// 如果是PDF,直接获取路径
if (item.isAttachment() && item.attachmentContentType === 'application/pdf') {
return await item.getFilePathAsync();
}
// 如果是父条目,查找其PDF附件
else if (item.isRegularItem() && !item.isAttachment()) {
let attachments = await item.getAttachments();
for (let attachmentID of attachments) {
let attachment = await Zotero.Items.getAsync(attachmentID);
if (attachment.attachmentContentType === 'application/pdf') {
return await attachment.getFilePathAsync();
}
//break;
}
}
return null;
}
async function openPDF(item) {
let path = await getPDFAttachmentPath(item);
if (!path) {
Zotero.alert(window, "打开失败", "未找到PDF附件");
return "未找到PDF附件";
}
let exePath = Zotero.Prefs.get("extensions.actionsTags.mypdfapp2", true);
if (!exePath) {
exePath = window.prompt("输入打开PDF的exe程序路径");
Zotero.Prefs.set("extensions.actionsTags.mypdfapp2", exePath, true);
}
// Example: exe path string in windows, C:\\QuickLook\\QuickLook.exe
Zotero.launchFileWithApplication(path, exePath);
// 减少提示干扰
// return "打开成功";
}
// 你需要获取当前选中的条目
return await openPDF(items[0]);
|
Beta Was this translation helpful? Give feedback.
-
|
I modified the Quick Look code in #132 (comment) for MacOS: if(item) return;
const window = require("window");
const ZoteroPane = require("ZoteroPane");
async function getPDFAttachmentPath(item) {
if (item.isAttachment() && item.attachmentContentType === 'application/pdf') {
return await item.getFilePathAsync();
}
else if (item.isRegularItem() && !item.isAttachment()) {
let attachments = await item.getAttachments();
for (let attachmentID of attachments) {
let attachment = await Zotero.Items.getAsync(attachmentID);
if (attachment.attachmentContentType === 'application/pdf') {
return await attachment.getFilePathAsync();
}
}
}
return null;
}
async function openPDF(item) {
let filePath = await getPDFAttachmentPath(item);
if (!filePath) {
Zotero.alert(window, "Failed to open.", "PDF attachment not found.");
return "PDF attachment not found.";
}
let applicationPath = "/usr/bin/qlmanage"
let args = ['-p', filePath]
Zotero.Utilities.Internal.exec(applicationPath, args);
}
return await openPDF(items[0]); |
Beta Was this translation helpful? Give feedback.
-
|
@dschaehi For Linux and sushi quicklook, not only pdf, but also including doc, image, html, music, txt, epub. etc if(item) return;
const window = require("window");
const ZoteroPane = require("ZoteroPane");
async function getAttachmentPath(item) {
if (item.isAttachment() && !item.isNote()) {
return await item.getFilePathAsync();
}
else if (item.isRegularItem() && !item.isAttachment()) {
let attachments = await item.getAttachments();
for (let attachmentID of attachments) {
let attachment = await Zotero.Items.getAsync(attachmentID);
return await attachment.getFilePathAsync();
}
}
return null;
}
async function openFile(item) {
let filePath = await getAttachmentPath(item);
if (!filePath) {
return false;
}
let applicationPath = "/usr/bin/sushi"
let args = [filePath]
Zotero.Utilities.Internal.exec(applicationPath, args);
}
return await openFile(items[0]); |
Beta Was this translation helpful? Give feedback.
-
|
Type Space bar and QuickLook, Thank you to the following two people for this discussion: @windingwind @iiwenwen const ZoteroPane = require("ZoteroPane");
const Zotero_Tabs = require("Zotero_Tabs");
const document = require("document");
var lastItem = "";
async function getAttachmentPath(item) {
if (item.isAttachment() && !item.isNote()) {
return await item.getFilePathAsync();
}
else if (item.isRegularItem() && !item.isAttachment()) {
let attachments = await item.getAttachments();
for (let attachmentID of attachments) {
let attachment = await Zotero.Items.getAsync(attachmentID);
return await attachment.getFilePathAsync();
}
}
return null;
}
async function openFile(item) {
let filePath = await getAttachmentPath(item);
if (!filePath) {
return false;
}
// macbook path : -p /usr/bin/qlmanage
// linux path : /usr/bin/sushi
let applicationPath = "/usr/bin/sushi"
let args = [filePath]
Zotero.Utilities.Internal.exec(applicationPath, args);
}
async function oneKey(event) {
var key = String.fromCharCode(event.which);
let newItem = ZoteroPane.getSelectedItems()[0];
if (Zotero_Tabs.selectedID === "zotero-pane") {
if ((key == ' ' && !(event.ctrlKey || event.altKey || event.metaKey)) || (key == 'y' && event.metaKey && !(event.ctrlKey || event.altKey))) {
if(newItem) {
lastItem = newItem;
return await openFile(newItem);
}
else {
return await openFile(lastItem);
}
}
}
}
document.getElementById('zotero-items-tree').addEventListener("keydown", oneKey, false); |
Beta Was this translation helpful? Give feedback.
-
|
@YaoLiMuMu Can this code be run on windows, I can't get it to work when I try to run it. |
Beta Was this translation helpful? Give feedback.
-
|
我写了一个可以弹出文件选择框的版本,这样就不用手动处理转义的问题了 if (!items?.length) return;
const window = require("window");
async function getPDFAttachmentPath (item) {
// If it is PDF, get the path directly
if (item.isAttachment() && item.attachmentContentType === 'application/pdf') {
return await item.getFilePathAsync();
}
// If it is a parent item, find its PDF attachment
else if (item.isRegularItem() && !item.isAttachment()) {
let attachments = await item.getAttachments();
for (let attachmentID of attachments) {
let attachment = await Zotero.Items.getAsync(attachmentID);
if (attachment.attachmentContentType === 'application/pdf') {
return await attachment.getFilePathAsync();
}
//break;
}
}
return null;
}
async function getPDFReaderExecutablePath () {
try {
const reader = Services.prefs.getComplexValue("extensions.actionsTags.pdfReader", Ci.nsIFile);
if (reader.exists()) return reader.path;
} catch (e) { }
return null;
}
async function selectPDFReader () {
const fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
fp.init(
!("inIsolatedMozBrowser" in window.browsingContext.originAttributes)
? window.browsingContext
: window,
"Select PDF Reader",
fp.modeOpen
);
fp.appendFilters(Ci.nsIFilePicker.filterApps);
return await new Promise(resolve => {
fp.open(res => resolve(res === Ci.nsIFilePicker.returnOK ? fp.file : null));
});
}
async function openPDF (item) {
let filePath = await getPDFAttachmentPath(item);
if (!filePath) {
Zotero.alert(window, "Open failed", "PDF attachment not found");
return "PDF attachment not found";
}
let execPath = await getPDFReaderExecutablePath();
if (!execPath) {
throw new Error("PDF reader not found");
}
Zotero.launchFileWithApplication(filePath, execPath);
}
let execPath = await getPDFReaderExecutablePath();
if (!execPath) {
let execPath = await selectPDFReader();
Services.prefs.setComplexValue("extensions.actionsTags.pdfReader", Ci.nsIFile, execPath);
if (!execPath) {
throw new Error("PDF reader not found");
}
}
for (const item of items) {
try {
await openPDF(item);
} catch (e) {
return e.message;
}
} |
Beta Was this translation helpful? Give feedback.
-
|
重新编写,使得quicklook能够打开任意文件,并非只有PDF文件。原理上Quicklook支持的可打开的文件类型都能用上。 目前还有个小问题: 这个目前不好实现,可能是因为当 QuickLook 打开后,Zotero 的窗口仍然拥有键盘焦点,而菜单栏的快捷键(比如↑,↓可能被菜单的导航捕获)优先于用户期望的条目跳转功能。 不过也不影响使用,因为Quciklook始终在屏幕置顶,所以只需要用鼠标去单击你想要点开的条目,再去摁预设的快捷键就能连续打开了 if(item) return;
const window = require("window");
const ZoteroPane = require("ZoteroPane");
/**
* 获取任意类型附件的本地路径
* @param {Zotero.Item} item - Zotero条目
* @returns {Promise<string|null>} 附件本地路径,无有效附件时返回null
*/
async function getAttachmentPath(item) {
// 如果是附件条目,直接获取路径(不限制类型)
if (item.isAttachment()) {
// 检查是否为本地可访问的附件(排除在线附件)
const linkMode = item.attachmentLinkMode;
// 0: 链接的文件, 2: 嵌入的文件, 3: 链接的URL(可能无法本地打开)
if (linkMode === 0 || linkMode === 2) {
const path = await item.getFilePathAsync();
return path || null;
}
return null;
}
// 如果是父条目,查找其第一个有效附件(任意类型)
else if (item.isRegularItem() && !item.isAttachment()) {
let attachments = await item.getAttachments();
for (let attachmentID of attachments) {
let attachment = await Zotero.Items.getAsync(attachmentID);
// 检查附件是否可本地访问
const linkMode = attachment.attachmentLinkMode;
if (linkMode === 0 || linkMode === 2) {
const path = await attachment.getFilePathAsync();
if (path) return path;
}
}
}
return null;
}
/**
* 使用QuickLook打开选中条目的附件(任意类型)
* @param {Zotero.Item} item - Zotero条目
* @returns {Promise<string>} 操作结果提示
*/
async function openAttachment(item) {
let path = await getAttachmentPath(item);
if (!path) {
Zotero.alert(window, "打开失败", "未找到可访问的本地附件");
return "未找到可访问的本地附件";
}
// 获取QuickLook程序路径(优先使用已保存的设置)
let exePath = Zotero.Prefs.get("extensions.actionsTags.quickLookPath", true);
if (!exePath) {
// 提示用户输入QuickLook路径(默认给出常见安装路径)
exePath = window.prompt("QuickLook.exe的路径,按自己实际的安装位置去替换");
if (exePath) {
Zotero.Prefs.set("extensions.actionsTags.quickLookPath", exePath, true);
} else {
Zotero.alert(window, "路径未设置", "请先设置QuickLook程序路径");
return "路径未设置";
}
}
// 启动QuickLook打开目标文件
Zotero.launchFileWithApplication(path, exePath);
// 减少提示干扰
// return "正在用QuickLook打开文件";
}
// 打开当前选中的第一个条目
return await openAttachment(items[0]); |
Beta Was this translation helpful? Give feedback.



Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
使用指定程序打开PDF,在首次打开时会检测配置变量,如果配置名称
extensions.actionsTags.mypdfapp不存在则跳出窗口,可以窗口中粘贴指定程序的exe路径(windows下火狐的路径是这样,C:\\Program Files\\Mozilla Firefox\\firefox.exe,注意空格和分隔符)如果首次设置好PDF阅读器路径,那后期如果要改,建议直接到高级 -> 拉到最下方编辑器 -> 搜索配置名称
extensions.actionsTags.mypdfapp进行手动修改You can open PDF with a specific PDF application when you right click on a PDF attachment.
Event: None
Operation: Script
Shortcut: None
Name: Open PDF
Beta Was this translation helpful? Give feedback.
All reactions