Save citations to your library

Save all citations of a paper to your library

// ==UserScript==
// @name         Save citations to your library
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Save all citations of a paper to your library
// @author       yusanshi
// @license      MIT
// @match        https://scholar.google.com/scholar?*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=google.com
// @require      https://cdn.jsdelivr.net/gh/uzairfarooq/arrive@77ff92c058598997e7da9789376b7a666a6d40db/src/arrive.js
// @grant        GM.setValue
// @grant        GM.getValue
// ==/UserScript==
const sleepTime = 1000;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const work = async (targetLibrary) => {
  await document.arrive('#gs_res_ccl_mid > div.gs_r.gs_or.gs_scl', {
    onceOnly: true,
    existing: true,
  });
  // Process the current page
  for (const e of document.querySelectorAll(
    '#gs_res_ccl_mid > div.gs_r.gs_or.gs_scl'
  )) {
    e.scrollIntoView();
    e.querySelector('div.gs_fl a.gs_or_sav span.gs_or_btn_lbl').click();
    await sleep(sleepTime);
    await document.arrive('#gs_md_albl-d.gs_vis div.gs_ldb_lbc', {
      onceOnly: true,
      existing: true,
    });

    let temp = [
      ...document.querySelectorAll('#gs_md_albl-d.gs_vis div.gs_ldb_lbc'),
    ].filter((a) => a.textContent === targetLibrary);
    if (temp.length === 0) {
      // create a new library
      document
        .querySelector('#gs_md_albl-d.gs_vis form span.gs_ldb_new_lb')
        .click();
      document.querySelector(
        '#gs_md_albl-d.gs_vis #gs_lbd_new_txt input'
      ).value = targetLibrary;
    } else {
      // select the old library
      temp = temp[0].querySelector('a');
      temp.scrollIntoView();
      if (!temp.classList.contains('gs_sel')) {
        temp.click();
      }
    }

    await sleep(sleepTime);
    document.querySelector('#gs_lbd_apl > span.gs_wr > span').click();
    await sleep(sleepTime);
  }

  const nextPage = document.querySelector(
    '#gs_n > center > table > tbody > tr > td > span.gs_ico_nav_current'
  ).parentElement.nextElementSibling;
  if (nextPage.innerText.trim() !== '') {
    nextPage.querySelector('a').click();
  }
};

(async function () {
  'use strict';

  document.body.insertAdjacentHTML(
    'beforeend',
    `<div
    style="
      position: fixed;
      bottom: 30px;
      right: 30px;
      background: rgba(240, 240, 240, 0.9);
      z-index: 1;
      padding: 5px;
      border: 1px solid #ccc;
      border-radius: 6px;
      display: flex;
      align-items: center;
    "
  >
    <label>Target library</label>
    <input type="text" id="targetLibrary" style="margin-left:6px;margin-right:10px" />
    <label>Current paper</label>
    <input type="text" id="currentPaper"  style="margin-left:6px;margin-right:10px" />
    <input
      type="checkbox"
      id="running"
      style="width: 16px; height: 16px"
    />
  </div>
  `
  );
  await document.arrive('#targetLibrary', {
    onceOnly: true,
    existing: true,
  });
  await document.arrive('#currentPaper', {
    onceOnly: true,
    existing: true,
  });
  await document.arrive('#running', {
    onceOnly: true,
    existing: true,
  });
  const targetLibraryInput = document.querySelector('#targetLibrary');
  const currentPaperInput = document.querySelector('#currentPaper');
  const runningCheckbox = document.querySelector('#running');

  targetLibraryInput.addEventListener('input', () => {
    GM.setValue('targetLibrary', targetLibraryInput.value.trim());
  });
  currentPaperInput.addEventListener('input', () => {
    GM.setValue('currentPaper', currentPaperInput.value.trim());
  });
  runningCheckbox.addEventListener('change', () => {
    GM.setValue('running', runningCheckbox.checked ? 'on' : 'off');
  });

  const targetLibrary = await GM.getValue('targetLibrary', '');
  const currentPaper = await GM.getValue('currentPaper', '');
  const running = await GM.getValue('running', 'off');

  targetLibraryInput.value = targetLibrary;
  currentPaperInput.value = currentPaper;
  runningCheckbox.checked = running === 'on';

  const params = new URL(window.location.href).searchParams;

  if (
    targetLibrary !== '' &&
    params.get('cites') === currentPaper &&
    params.get('q') === null &&
    running === 'on'
  ) {
    work(targetLibrary);
  }
})();

QingJ © 2025

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