谷歌学术自动复制 BiBTeX (Enhanced BibTeX Fetcher with Filtering and Highlighting)

Fetch and copy BibTeX citations from academic papers, with advanced filtering and highlighting

  1. // ==UserScript==
  2. // @name 谷歌学术自动复制 BiBTeX (Enhanced BibTeX Fetcher with Filtering and Highlighting)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.03
  5. // @description Fetch and copy BibTeX citations from academic papers, with advanced filtering and highlighting
  6. // @author Apricity
  7. // @match https://scholar.google.com/*
  8. // @match https://scholar.googleusercontent.com/scholar.bib*
  9. // @icon https://scholar.google.com/favicon.ico
  10. // @grant GM_setClipboard
  11. // @license GNU GPLv3
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. "use strict";
  16.  
  17. function copyToClipboard(text) {
  18. GM_setClipboard(text, "text");
  19. }
  20.  
  21. function endsWithAny(strings, url) {
  22. for (var i = 0; i < strings.length; i++) {
  23. if (url.endsWith(strings[i])) {
  24. return true;
  25. }
  26. }
  27. return false;
  28. }
  29.  
  30. function containsAny(strings, url) {
  31. for (var i = 0; i < strings.length; i++) {
  32. if (url.includes(strings[i])) {
  33. return true;
  34. }
  35. }
  36. return false;
  37. }
  38.  
  39. function processEntries() {
  40. // Select all entries
  41. var entries = document.querySelectorAll(".gs_ri");
  42.  
  43. // Iterate over each entry
  44. for (var i = 0; i < entries.length; i++) {
  45. var entry = entries[i];
  46.  
  47. // Select the description element
  48. var description = entry.querySelector(".gs_a");
  49.  
  50. // If the description exists and the URL ends with .edu, .de, .jp, or contains amazonaws, hide the entry
  51. if (
  52. description &&
  53. (endsWithAny([".edu", ".de", ".jp"], description.innerText) ||
  54. containsAny(
  55. ["amazonaws", "thetalkingmachines"],
  56. description.innerText
  57. ))
  58. ) {
  59. entry.parentNode.style.display = "none";
  60. }
  61.  
  62. // If the description exists and the URL contains meethings, highlight the entry
  63. if (
  64. description &&
  65. containsAny(
  66. ["aclanthology.org", "openreview.net", "neurips.cc", "dl.acm.org"],
  67. description.innerText
  68. )
  69. ) {
  70. entry.parentNode.style.backgroundColor = "#e4efff";
  71. }
  72. }
  73. }
  74.  
  75. if (window.location.href.includes("scholar.bib")) {
  76. // Wait for the BibTeX text to load, then copy it
  77. setTimeout(function () {
  78. var bibtexText = document.body.innerText;
  79. if (bibtexText) {
  80. copyToClipboard(bibtexText);
  81. alert("BibTeX citation copied to clipboard!");
  82. }
  83. }, 2000); // Adjust timing as needed
  84. return;
  85. }
  86.  
  87. var logoLink = document.querySelector("#gs_hdr_lgo");
  88. if (logoLink && logoLink.href.includes("zh-CN")) {
  89. // Copy the first citation
  90. var observer = new MutationObserver(function (mutations) {
  91. mutations.forEach(function (mutation) {
  92. if (!mutation.addedNodes) return;
  93.  
  94. for (var i = 0; i < mutation.addedNodes.length; i++) {
  95. var node = mutation.addedNodes[i];
  96. var citationDiv = node.querySelector(".gs_citr");
  97. if (citationDiv) {
  98. // Copy the first citation
  99. var citationText = citationDiv.textContent;
  100. copyToClipboard(citationText);
  101. alert("Citation copied to clipboard!");
  102. }
  103. }
  104. });
  105. });
  106. } else {
  107. observer = new MutationObserver(function (mutations) {
  108. mutations.forEach(function (mutation) {
  109. if (!mutation.addedNodes) return;
  110.  
  111. for (var i = 0; i < mutation.addedNodes.length; i++) {
  112. var node = mutation.addedNodes[i];
  113. var bibtexButton = node.querySelector("#gs_citi a.gs_citi");
  114. if (bibtexButton) {
  115. window.location.href = bibtexButton.href;
  116. observer.disconnect();
  117. return;
  118. }
  119. }
  120. });
  121. });
  122. }
  123.  
  124. processEntries();
  125. observer.observe(document.body, {
  126. childList: true,
  127. subtree: true,
  128. });
  129. var processObserver = new MutationObserver(processEntries);
  130. processObserver.observe(document.body, { childList: true, subtree: true });
  131. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址