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);
- }
- })();