iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
生成式 AI

讓AI「陪」你寫論文系列 第 19

Day19 zotero掛件組合技:一鍵把螢光筆重點變筆記

  • 分享至 

  • xImage
  •  

今日事項:了解可以如何組合 zotero 書目管理軟體的不同 Plugns,做到更複雜的功能。比如在將 PDF 畫螢光筆作筆記後,直接有畫螢光筆的字句分類、另建筆記。

如果文章對你有幫助的話,歡迎按讚或留言,讓我知道我不是一個人在這裡碎碎念(?),我會很感謝的❤️

Plugins 不只有一種使用方式,還可以是組合拳

前面我們介紹了五種 Plugins 與使用方式,每一個都已經很好用了,但除了這幾個插件基本的功能,他們還可以組合使用,讓筆記的過程更方便!

比如今天要介紹的功能,就是其中的一種。

看完前面的介紹,不知道大家有沒有跟著一起去做 Zotero 的 PDF 筆記,如果有去的話,有可能會跟我一樣發現一件事情--將字句拉到筆記做筆記的方法、畫螢光筆做筆記的方法,沒有辦法兩全其美

因為如果僅僅是畫螢光筆,那就單純只是在 PDF 上做標記,沒有另外統整的筆記;但若只是拉字句做筆記,有時候打開論文,看著全白的頁面,也會覺得找不到重點。

所以就有人設計出了這個,可以畫螢光筆之後,一次將做了標記的字句分類並做成筆記的 Plugins 組合。

一、需要用到的 Plugins

本篇的設定參考 Better Note Github 中 mulei000 的文章

要達到前面說的這個效果,需要使用到前面介紹的三個插件,分別是--Style、Better Notes、Action TAGs

如果說還不知道這三個是什麼的,快去補課!

Day15 zotero掛件 2:Style-美化版面、整理文獻的好幫手

Day17 zotero掛件 4:Better Notes-導入各式大神做好的論文筆記模板

Day18 zotero掛件 5:Tags-自訂的功能按鈕

二、步驟流程

1. Style - 先設定好螢光筆的顏色標記與名稱

因為要讓螢光筆抓過去的時候有按照顏色與類別分類,所以要先定義好顏色、分類
Style Plugins 要先安裝好)

  1. 先點開一篇 PDF,在開啟的畫面中按下 Shift+P,點擊跳出面板中的標註,進到下面這個畫面

  2. 複製下面的文字(內容是對於螢光筆顏色、名稱的設定)

    [["創新點","#ffd400"],["背景","#5fb236"],["文獻","#a28ae5"],["變數與數據","#2ea8e5"],["方法與操作","#f19837"],["結論","#ff6666"],["Figure","#aaaaaa"]]
    
  3. 點擊步驟一畫面中的 Import,螢光筆的顏色與名稱就會自動匯入了。

2. Action TAGs - 將顏色自動註釋

想要將 PDF 中的螢光筆區塊抓到筆記中自動分類好的話,需要在每個區塊都先標註好,他才會依照標註分類。
而如果要自己手動標註的話,必定會很花時間,所以利用 Action TAGs 來去做一個自動化(美化完螢光筆都會自動標註)

  1. 工具列的編輯 > 設定> 點選設定中的 Action TAGs > +字按鈕 新增項目

  2. 項目如同下方圖片設定,數據的部分,則貼上下一個步驟中的代碼

  3. 數據的欄位貼上下列代碼

    /**
     * 注释:根据注释颜色增加标签
     * @author appwcn windingwind
     * @link https://github.com/windingwind/zotero-actions-tags/discussions/339
     */
    
    // EDTI TAG MAPPING BELOW
    const tags = {
    	"#ffd400": "創新點",
    	"#5fb236": "背景",
    	"#a28ae5": "文獻",
    	"#2ea8e5": "變數與數據",
    	"#f19837": "方法與操作",
    	"#ff6666": "結論",
    	"#aaaaaa": "Figure",
    }
    
    if (!item) {
    	return;
    }
    
    if (!item.isAnnotation() || !item.annotationColor) {
    	return;
    }
    
    const tag = tags[item.annotationColor];
    item.addTag(tag);
    return `Tag added: ${tag}`;
    

3. Better Notes 筆記模板設定

設定筆記模板,讓模板在創建的時候,可以自動抓取選取的內容(來自 mulei000

  1. 工具列的編輯 > 設定> 點選設定中的 Better Notes > 打開模板編輯器按鈕

  2. 模板類型選擇條目、模板名稱可以自己命名

  3. 將下方的代碼,貼入下方的模板中,貼完記得按保存

    原先網站作者創作的內文是簡體,這邊我有改成繁體

    // @author mulei
    ${await (async () => {
        const getAnnotationsByTag = async (tagName) => {
            const pdfItem = await topItem.getBestAttachment();
            let result = "";
            for (let annoItem of pdfItem.getAnnotations()) {
                if (annoItem.getTags().find(i => i.tag.includes(tagName))) {
                    const res = Zotero.EditorInstanceUtilities.serializeAnnotations(
                        [
                            {
                                ...(await Zotero.Annotations.toJSON(annoItem)), ...{ attachmentItemID: annoItem.parentID }
                            }
                        ]
                    );
                    result += res.html;
                }
            }
            return result;
        };
    
        // 輔助函數:檢測字符串是否包含中文字符
        const containsChinese = (text) => /[\u4e00-\u9fa5]/.test(text);
    
        // 提取影響因子
        let impactFactor = Zotero.ZoteroStyle.api.renderCell(topItem, "publicationTags").textContent.trim();
        let impactFactorValues = impactFactor.match(/\d+(\.\d+)?/g); // 提取数字部分
    
        // 獲取翻譯標題,如果沒有或者為空,則使用原始標題
        let titleTranslationMatch = topItem.getField("extra").match(/titleTranslation:(.+)/);
        let titleTranslation = (titleTranslationMatch && titleTranslationMatch[1].trim()) ? titleTranslationMatch[1].trim() : topItem.getField("title");
    
        // 檢查標題是否為中文
        let isChineseTitle = containsChinese(topItem.getField("title"));
    
        // 根據標題語言決定 IFQ 的顯示方式
        let impactFactorDisplay = isChineseTitle ? impactFactor : (impactFactorValues ? impactFactorValues.join(' / ') : '');
    
        // 獲取作者顯示內容
        let creators = topItem.getCreators();
        let authorDisplay = "";
        if (isChineseTitle) {
            // 中文標題:顯示第一作者全名,格式為“姓 前名”
            if (creators.length > 0) {
                let firstAuthor = creators[0];
                let fullName = `${firstAuthor.lastName} ${firstAuthor.firstName}`;
                authorDisplay = fullName;
            }
        } else {
            // 非中文標題:顯示第一作者姓氏並附加“et al.”
            if (creators.length > 0) {
                let firstAuthorLastName = creators[0].lastName;
                authorDisplay = `${firstAuthorLastName} et al.`;
            }
        }
    
        // 獲取各部分注視內容
        const 創新點 = await getAnnotationsByTag('創新點');
    	  const 背景 = await getAnnotationsByTag('背景');
        const 文獻 = await getAnnotationsByTag('文獻');
        const 變數與數據 = await getAnnotationsByTag('變數與數據');
        const 方法與操作 = await getAnnotationsByTag('方法與操作');
        const 結論 = await getAnnotationsByTag('結論');
        const Figure = await getAnnotationsByTag('Figure');
    
        // 新增部分:提取 Figure 標籤的內容
        const getFigureAnnotations = async (item, tag) => {
            let annots = item.getAnnotations();
            annots = annots.filter((annot) => annot.getTags().map(tagObj => tagObj.tag).includes(tag));
            return await Zotero.BetterNotes.api.convert.annotations2html(annots, { noteItem: targetNoteItem });
        };
    
        const attachments = Zotero.Items.get(topItem.getAttachments()).filter((i) => i.isPDFAttachment());
    
        let figureRes = "";
        for (let attachment of attachments) {
            const annots = await getFigureAnnotations(attachment, 'Figure');
            figureRes += annots ? annots : "";
        }
    
        const itemNotes = []; // 需要獲取文獻的相關筆記
        const notes = itemNotes.filter(noteItem => noteItem.getTags().map(tagObj => tagObj.tag).includes('Figure'));
        const notesWithTags = `${notes.map((noteItem) => {
            const noteLink = Zotero.BetterNotes.api.convert.note2link(noteItem);
            const noteLine = `<p style="color:red; background-color: #efe3da;">📜 Article Note:  <a href="${noteLink}">${noteItem.getNoteTitle() || noteLink}</a></p>
    <p>tags: ${noteItem.getTags().map(tagObj => tagObj.tag).join(', ')}</p>
    <p> </p>`;
            return noteLine;
        }).join("\n")}`;
    
        figureRes += notesWithTags;
    
        // 生成標題,處理中文和英文情况
        let res = `<h1>🔤${titleTranslation} (<span style="background-color: #B1A5E1">${topItem.getField("year")}</span>, <span style="background-color: #CBE1A5">${authorDisplay}</span>) ${topItem.getField("journalAbbreviation")} (${impactFactorDisplay})</h1>
    <p><strong><span style="color: #283593">原名:</span></strong>${topItem.getField('title')}</p>
    <p><strong><span style="color: #283593">譯名:</span></strong>${titleTranslation}</p>
    <p><strong><span style="color: #283593">作者:</span></strong>${authorDisplay}</p>
    <p><strong><span style="color: #283593">期刊:</span></strong>${topItem.getField('publicationTitle')}</p>
    <p><strong><span style="color: #283593">IFQ:</span></strong><span style="">
    
    ${{
    let space = " ㅤㅤ ㅤㅤ"
    return Array.prototype.map.call(
    	Zotero.ZoteroStyle.api.renderCell(topItem, "publicationTags").childNodes,
    	e => {
    		e.innerText =  space + e.innerText + space;
    		return e.outerHTML
    	}
    	).join(space)
    }}$
    </p >
    
    ${(() => {
            const doi = topItem.getField("DOI");
            if (doi) {
                return `<b><span style="color: #283593">DOI:</span></strong> </b><a href="https://doi.org/${topItem.getField('DOI')}">${topItem.getField('DOI')}</a>`;
            } else {
                return `<b><span style="color: #283593">URL:</span></strong> </b><a href="${topItem.getField('url')}">${topItem.getField('url')}</a>`;
            }
        })()}
    <p><strong><span style="color: #283593">發表時間:</span></strong>${topItem.getField('date')}</p>
    
    <!-- 本地鏈接 -->
    <tr>
      <td style="color:#193c47; background-color:#dbeedd; padding:8px;">
        ${(() => {
            const attachments = Zotero.Items.get(topItem.getAttachments());
            if (attachments && attachments.length > 0) {
                return `<b><span style="color: #283593">本地鏈接:</span> </b><a href="zotero://open-pdf/0_${attachments[0].key}">${attachments[0].getFilename()}</a>`;
            } else {
                return `<b><span style="color: #283593">本地鏈接:</span> </b>`;
            }
        })()}
      </td>
    </tr>
    <p>
    <!-- 摘要 -->
    <tr>
      <td style="color:#193c47; background-color:#dbeedd; padding:8px;">
        ${(() => {
            const abstractTranslation = topItem.getField('abstractTranslation');
            if (abstractTranslation) {
                return `<b><span style="color: #283593">摘要翻譯:</span> </b><i>${abstractTranslation}</i>`;
            } else {
                return `<b><span style="color: #283593">摘要:</span> </b><i>${topItem.getField('abstractNote')}</i>`;
            }
        })()}
      </td>
    </tr>
    
    <!-- 生成標籤筆記 -->
    ${創新點 ? `<h3><span style="color: #ffd400">💡創新點:</span></h3>${創新點}` : ''}
    
    ${背景 ? `<h3><span style="color: #5fb236">🌏背景:</span></h3>${背景}` : ''}
    
    ${文獻 ? `<h3><span style="color: #a28ae5">📜文獻:</span></h3>${文獻}` : ''}
    
    ${變數與數據 ? `<h3><span style="color: #2ea8e5">💧變數與數據:</span></h3>${變數與數據}` : ''}
    
    ${方法與操作 ? `<h3><span style="color: #f19837">🔬方法與操作:</span></h3>${方法與操作}` : ''}
    
    ${結論 ? `<h3><span style="color: #ff6666">🚩結論:</span></h3>${結論}` : ''}
    
    ${figureRes ? `<h3><span style="color: #aaaaaa">🖼️Figure 筆記:</span></h3>${figureRes}` : ''}
    
    `;
    
        return res;
    })()}
    

4. (可選)Actions TAGs + Translate - 翻譯標題

除了上面三個必要的設定,在筆記模板中也有加入可翻譯標題的功能
Translate 掛件的安裝可見這篇:Day14 zotero掛件 1:Translate-讓你隨看隨翻

  1. 工具列的編輯 > 設定> 點選設定中的 Action TAGs > +字按鈕 新增項目

  2. 項目如同下方圖片設定,數據的部分,則貼上下一個步驟中的代碼

  3. 數據的欄位貼上下列代碼

    // Translate item title automatically
    // @author windingwind
    // @link https://github.com/windingwind/zotero-tag/discussions/107
    // @usage Event=Create Item
    
    const Zotero = require("Zotero");
    if (!Zotero.PDFTranslate) {
    	return "[Action:Translate Title] Translate for Zotero is not installed or disabled.";
    }
    if (!item) {
    	return "[Action:Translate Title] Target item is empty";
    }
    
    const title = item.getField("title");
    const result = (await Zotero.PDFTranslate.api.translate(title)).result;
    Zotero.PDFTranslate.data.ztoolkit.ExtraField.setExtraField(item, "titleTranslation", result);
    
    return `[Action:Translate Title] successfully translate ${title} to ${result}.`;
    

Day19 總結

這個設定呢,說簡單不簡單,說複雜呢……其實也不複雜。

真正困難的東西我覺得是,Plugins 的設計、筆記模板的設計等等,但因為前面有許多大神都已經幫我們把東西用完了,所以現在真正要設定的時候,只是步驟複雜了一些。

但設定完,後面要做筆記會方便很多喔!

(p.s. 今天教的這個,因為他的運行是透過顏色、顏色名稱的設定,所以要更改的話要記得進到螢光筆設定筆記模板Action TAGs 三個地方一起更改,才不會在運行的時候抓不到正確的內容)


上一篇
Day18 zotero掛件 5:Tags-自訂的功能按鈕
下一篇
Day20 論文怎麼讀?!快速了解怎麼閱讀論文
系列文
讓AI「陪」你寫論文20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言