Google Scholar Bib Helper

Copy BibTeX records quickly within search results.

  1. // ==UserScript==
  2. // @name Google Scholar Bib Helper
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Copy BibTeX records quickly within search results.
  6. // @author yusanshi
  7. // @license MIT
  8. // @match https://scholar.google.com/scholar?*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=scholar.google.com
  10. // @require https://cdn.jsdelivr.net/npm/arrive@2.4.1/minified/arrive.min.js
  11. // @grant GM.xmlHttpRequest
  12. // @connect scholar.googleusercontent.com
  13. // ==/UserScript==
  14.  
  15. function toggleShowHide(div) {
  16. if (div.style.display !== 'none') {
  17. div.style.display = 'none';
  18. } else {
  19. div.style.display = 'block';
  20. }
  21. }
  22.  
  23. (function () {
  24. 'use strict';
  25.  
  26. document.arrive(
  27. '#gs_res_ccl_mid > div.gs_r.gs_or.gs_scl',
  28. { existing: true },
  29. function () {
  30. const url = new URL('https://dblp.org/search');
  31. const title = this.querySelector('h3.gs_rt > a').innerText;
  32. url.searchParams.set('q', title);
  33. url.searchParams.set('clean', 'true');
  34. this.querySelector('div.gs_ri div.gs_fl').insertAdjacentHTML(
  35. 'beforeend',
  36. `<button class="google-bib-button" type="button" style="height:22px">Show Bib</button> <button class="dblp-iframe-button" type="button" style="height:22px;margin-left:8px;">Search DBLP</button>`
  37. );
  38. this.insertAdjacentHTML(
  39. 'beforeend',
  40. `<div class="google-bib-container"></div> <div class="dblp-iframe-container"></div>`
  41. );
  42.  
  43. this.querySelector('.google-bib-button').addEventListener('click', () => {
  44. const container = this.querySelector('.google-bib-container');
  45. if (container.hasChildNodes()) {
  46. toggleShowHide(container);
  47. } else {
  48. container.innerHTML = `<textarea rows="8" class="bib-textarea" style="font-size:11px;margin-top:8px;border-color:rgb(220,220,220);border-radius:5px;outline:none;width:100%;color:gray;" onclick="this.select()">Fetching BibTeX record...</textarea>`;
  49.  
  50. const bibTextArea = this.querySelector('.bib-textarea');
  51. document.arrive('#gs_citi', { onceOnly: true }, async () => {
  52. let bibURL;
  53. try {
  54. const bibAnchor = Array.from(
  55. document.querySelectorAll('#gs_citi a')
  56. ).filter((e) => e.textContent === 'BibTeX')[0];
  57. bibURL = bibAnchor.href;
  58. document.querySelector('#gs_cit-x').click();
  59. } catch (error) {
  60. bibTextArea.value = 'BibTeX entry not found!';
  61. document.querySelector('#gs_cit-x').click();
  62. return;
  63. }
  64. try {
  65. const bibText = (await GM.xmlHttpRequest({ url: bibURL }))
  66. .responseText;
  67. bibTextArea.value = bibText;
  68. } catch (error) {
  69. console.log(error);
  70. bibTextArea.value = `Error while fetching ${bibURL}.\n\nPlease see the console for the error message.`;
  71. }
  72. });
  73. Array.from(this.querySelectorAll('div.gs_ri div.gs_fl > a'))
  74. .filter((e) => e.textContent === 'Cite')[0]
  75. .click();
  76. }
  77. });
  78. this.querySelector('.dblp-iframe-button').addEventListener(
  79. 'click',
  80. () => {
  81. const container = this.querySelector('.dblp-iframe-container');
  82. if (container.hasChildNodes()) {
  83. toggleShowHide(container);
  84. } else {
  85. container.innerHTML = `<iframe width="100%" height="400" style="margin-top:8px;border:1px solid rgb(220, 220, 220);border-radius:5px;" src="${url.href}"></iframe>`;
  86. }
  87. }
  88. );
  89. }
  90. );
  91. })();

QingJ © 2025

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