// ==UserScript== // @name CNKI 文献详情页 - 保存摘要(含来源日期) // @namespace https://www.0x99.top // @version 1.2 // @description 在CNKI文献详情页顶部中央添加按钮,保存格式化摘要:作者. 标题, 来源信息\n摘要: 内容 // @author zmrbak // @match https://kns.cnki.net/kcms2/article/abstract?* // @match https://kns.cnki.net/kcms/detail/* // @match https://kns.cnki.net/kcms2/detail/* // @grant none // ==/UserScript== (function() { 'use strict'; // 获取标题(从 .wx-tit h1) function getTitle() { const titleElem = document.querySelector('.wx-tit h1'); if (titleElem) { let title = titleElem.innerText.trim(); // 移除可能附带的视频标记等 title = title.replace(/\s*/, '').trim(); return title; } return '未知标题'; } // 获取作者列表(从 #authorpart 下的 a 链接,去除上标数字) function getAuthors() { const authorContainer = document.getElementById('authorpart'); if (!authorContainer) return []; const authorLinks = authorContainer.querySelectorAll('a'); const authors = []; for (let link of authorLinks) { let name = link.innerText.trim(); // 去除上标数字(如 "陈国青1" -> "陈国青") name = name.replace(/\d+$/, '').trim(); if (name) authors.push(name); } // 去重(保留顺序) return [...new Map(authors.map(a => [a, a])).values()]; } // 获取来源信息(期刊名、年份、卷期、页码) function getSourceInfo() { const topTip = document.querySelector('.top-tip span'); if (!topTip) return ''; // 获取所有文本内容(包含链接内的文本) let rawText = topTip.innerText || topTip.textContent || ''; // 去除“查看该刊数据库收录来源”和“使用帮助”等额外文字 rawText = rawText.replace(/查看该刊数据库收录来源.*$/, '') .replace(/使用帮助.*$/, '') .trim(); // 合并多余空白 rawText = rawText.replace(/\s+/g, ' ').trim(); // 去掉末尾可能的标点 return rawText; } // 获取摘要文本 function getAbstractText() { let abstract = ''; const summarySpan = document.getElementById('ChDivSummary'); if (summarySpan) { abstract = summarySpan.innerText.trim(); } if (!abstract) { const abstractInput = document.getElementById('abstract_text'); if (abstractInput && abstractInput.value) { abstract = abstractInput.value.trim(); } } if (!abstract) { const rowDiv = Array.from(document.querySelectorAll('.row')).find(row => { const span = row.querySelector('.rowtit'); return span && span.innerText.includes('摘要'); }); if (rowDiv) { const abstractSpan = rowDiv.querySelector('.abstract-text'); if (abstractSpan) abstract = abstractSpan.innerText.trim(); } } return abstract.replace(/\s+/g, ' ').trim(); } // 获取文件名基础(用标题,清理非法字符) function getBaseFileName() { let title = getTitle(); title = title.replace(/[\\/:*?"<>|]/g, ''); if (title.length > 100) title = title.slice(0, 100); return title; } // 保存文本文件 function saveAsTextFile(content, filename) { if (!content) { alert('未找到摘要内容,可能页面结构已变化。'); return false; } const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); const link = document.createElement('a'); const url = URL.createObjectURL(blob); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); return true; } // 创建按钮(顶部居中) function createButton() { const btn = document.createElement('button'); btn.textContent = '📝 保存摘要'; btn.id = 'cnki-detail-save-abstract-btn'; btn.style.cssText = ` position: fixed; left: 50%; transform: translateX(-50%); top: 12px; z-index: 9999; padding: 8px 20px; font-size: 14px; font-weight: bold; color: #fff; background-color: #2c7da0; border: none; border-radius: 30px; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,0.2); transition: background-color 0.2s; display: block; width: auto; min-width: 120px; text-align: center; font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; `; btn.onmouseover = () => btn.style.backgroundColor = '#1f5e7a'; btn.onmouseout = () => btn.style.backgroundColor = '#2c7da0'; btn.addEventListener('click', () => { const title = getTitle(); const authors = getAuthors(); const authorStr = authors.length ? authors.join(',') : '未知作者'; const sourceInfo = getSourceInfo(); const abstract = getAbstractText(); if (!abstract) { alert('未找到摘要内容,请确认页面已完全加载。'); return; } // 格式:作者. 标题, 来源信息\n摘要: 内容 let firstLine = `${authorStr}. ${title}`; if (sourceInfo) { firstLine += `, ${sourceInfo}`; } const content = `${firstLine}\n摘要: ${abstract}`; const filename = `${getBaseFileName()}_摘要.txt`; const success = saveAsTextFile(content, filename); if (success) { const notice = document.createElement('div'); notice.textContent = `✅ 摘要已保存: ${filename}`; notice.style.cssText = ` position: fixed; bottom: 20px; right: 20px; background: #4caf50; color: white; padding: 6px 12px; border-radius: 4px; font-size: 12px; z-index: 10000; opacity: 0.9; `; document.body.appendChild(notice); setTimeout(() => notice.remove(), 3000); } }); return btn; } function addButton() { if (document.getElementById('cnki-detail-save-abstract-btn')) return; const btn = createButton(); document.body.appendChild(btn); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', addButton); } else { addButton(); } })();