Greasy Fork is available in English.

Publication Auto PDF

Automatically jumps to PDF when you visit a journal article abstract page. Also includes a utility to copy or download citation info.


Installer dette script?
// ==UserScript==// @name    Publication Auto PDF// @name:zh-CN  SCI文#PDF直达// @version 0.5.0// @author  sincostandx// @description Automatically jumps to PDF when you visit a journal article abstract page. Also includes a utility to copy or download citation info.// @description:zh-CN  访问SCI文#摘要页时自动跳转至PDF,附带文#摘录工具// @match https://www.sciencedirect.com/science/article/*// @match https://onlinelibrary.wiley.com/doi/*// @match https://*.onlinelibrary.wiley.com/doi/*// @match https://pubs.acs.org/doi/*// @match https://www.tandfonline.com/doi/*// @match https://www.beilstein-journals.org/*// @match https://pubs.rsc.org/en/content/*// @match https://link.springer.com/article*// @match https://pubs.aip.org/aip/*/article/*// @match https://www.nature.com/articles*// @match https://www.science.org/doi/*// @match https://journals.aps.org/*/abstract/10*// @match https://cdnsciencepub.com/doi/*// @match https://iopscience.iop.org/article/10*// @match https://www.cell.com/*/fulltext/*// @match https://journals.lww.com/*// @match https://*.biomedcentral.com/articles/*// @match https://journals.sagepub.com/doi/*// @match https://academic.oup.com/*/article/*// @match https://karger.com/*/article/*// @match https://www.cambridge.org/core/journals/*/article/*// @match https://www.annualreviews.org/doi/*// @match https://www.jstage.jst.go.jp/article/*// @match https://www.hindawi.com/journals/*// @match https://*.theclinics.com/article/*// @match https://www.liebertpub.com/doi/*// @match https://thorax.bmj.com/content/*// @match https://journals.physiology.org/doi/*// @match https://www.ahajournals.org/doi/*// @match https://dl.acm.org/doi/*// @match https://journals.asm.org/doi/*// @match https://*.apa.org/record/*// @match https://*.apa.org/fulltext/*// @match https://www.thelancet.com/journals/*/article/*// @match https://jamanetwork.com/journals/*// @match https://aacrjournals.org/*/article/*// @match https://royalsocietypublishing.org/doi/*// @match https://journals.plos.org/*/article*// @match https://*.psychiatryonline.org/doi/*// @match https://opg.optica.org/*/*.cfm*// @match https://www.thieme-connect.de/products/ejournals/*// @match https://journals.ametsoc.org/view/journals/*// @match https://www.frontiersin.org/articles/*// @match https://www.worldscientific.com/doi/*// @match https://www.nejm.org/doi/*// @match https://ascopubs.org/doi/*// @match https://www.jto.org/article/*// @match https://www.jci.org/articles/*// @match https://www.pnas.org/doi/*// @grant   GM.getValue// @grant   GM.setValue// @run-at  document-start// @namespace https://gfork.dahi.icu/users/171198// ==/UserScript==(function() {"use strict";let tit = null; // titlelet doi = null;let pdf = null; // pdf urllet sty = null; // citation text style// attempt to extract DOI from URLfunction getCrudeDOI() {const l = location.pathname.match(/(^.+doi\/)([^/]+\/)?(10\.[^/]+\/[^/]+)/);if (l === null) return [null, null];const d = l[l.length-1];return [d, l[1] + "pdf/" + d];}const [doiCrude, pdfPathname] = getCrudeDOI();// determine if we need to redirect to PDFlet jump = sessionStorage.getItem("%" + doiCrude) === null &&sessionStorage.getItem(location.pathname) === null;// For sites in "shortcutSites" modify the URL directly.// Otherwise, load PDF link from meta data or DOM.if (doiCrude !== null) {sessionStorage.setItem("%" + doiCrude, "1");if (jump && location.pathname !== pdfPathname) {const shortcutSites = ["acs", "aps", "wiley", "tandfonline", "sagepub", "annualreviews", "liebertpub","physiology", "ahajournals", "acm", "royalsocietypublishing", "psychiatryonline", "thieme","worldscientific", "nejm", "ascopubs", "cdnsciencepub", "asm", "science", "pnas"];const hostname = location.hostname;if (shortcutSites.some(a=>hostname.includes(a))) {location.pathname = pdfPathname;}} else {new Promise(checkLoaded).then(loadMeta);}} else {sessionStorage.setItem(location.pathname, "1");if (location.hostname.includes(".apa.")) {new Promise(checkAPALoaded).then(loadMeta);} else {new Promise(checkLoaded).then(loadMeta);}}function checkLoaded(resolve) {function check(){if (document.body !== null && document.body.innerHTML.length !== 0) {resolve();} else {setTimeout(check, 100);}}check();}function checkAPALoaded(resolve) {let count = 0;function check(){const main = document.querySelector("main");if (main !== null && main.offsetHeight > 300) {resolve();} else if (++count < 30){setTimeout(check, 1000);}}check();}function loadMeta() {const titmeta = ["dc.title", "citation_title", "wkhealth_title", "og:title"];const doimeta = ["citation_doi", "dc.identifier", "dc.source"];const pdfmeta = ["citation_pdf_url", "wkhealth_pdf_url"];const metaList = document.getElementsByTagName("meta");for (const meta of metaList) {let n = meta.getAttribute("name");if (n === null) {n = meta.getAttribute("property");if (n === null) continue;}n = n.toLowerCase();if (tit === null && titmeta.includes(n)) {tit = meta.getAttribute("content");continue;}if (doi === null && doimeta.includes(n)) {const d = meta.getAttribute("content");if (d.includes("10.")) {if (d.includes("doi")) {doi = d.slice(d.indexOf("10."));} else {doi = d;}continue;}}if (pdf === null && pdfmeta.includes(n)) {pdf = meta.getAttribute("content");}}if (jump && location.hostname.includes("sciencedirect")) {if (loadElsevierPDF()) return;}if (pdf !== null && location.hostname.includes(".apa.")) {// need to remove query string in apa pdf linksconst url = new URL(pdf);url.search = '';pdf = url.toString();}if (jump && pdf !== null && location.href !== pdf) {location.href = pdf;} else {if (doi === null) {doi = doiCrude;if (doi === null) return;}if (tit === null) tit = "Unknown Title";if (pdf === null) pdf = pdfPathname;toolbox(tit, doi, pdf);}}// newbr, newinput, newtag are util functions to create toolbox elements.function newbr(parent) {parent.appendChild(document.createElement("br"));}function newinput(parent, type, value, onclick) {const i = document.createElement("input");i.type = type;i.value = value;if (onclick !== null) {i.addEventListener("click", onclick, false);}i.className = "toolbox";parent.appendChild(i);return i;}function newtag(parent, tag, text) {const i = document.createElement(tag);if (text !== null) {i.textContent = text;}i.className = "toolbox";parent.appendChild(i);return i;}function loadElsevierPDF() {let pdflink = null;let trials = 0;function getJSON(resolve) {function get() {const json = document.querySelector('script[type="application/json"]');try {const meta = JSON.parse(json.innerHTML).article.pdfDownload.urlMetadata;pdflink = "/" + meta.path + "/" + meta.pii + meta.pdfExtension + "?md5=" + meta.queryParams.md5 + "&pid=" + meta.queryParams.pid;return true;} catch(e) {return false;}}if (!get()) {if (++trials > 30) {console.error("Auto PDF: Unable to load JSON from DOM!");throw "";}setTimeout(() => {getJSON(resolve);}, 1000);return;}resolve(pdflink);}new Promise(getJSON).then((pdflink) => {location.href = pdflink;}).catch(() => {});return true;}function toolbox(tit, doi, pdf) {const div = document.createElement("div");div.style = `z-index: 2147483647;position: fixed;right: 10px;top: 50%;transform: translate(0, -50%);border: 2px groove black;background: white;box-shadow: 6px 6px 3px grey;`;const sheet = document.createElement("style")sheet.textContent = `.toolbox {font-size: small !important;font-family: sans-serif !important;margin-bottom: 4px !important;margin-top: 0 !important;display: initial !important;line-height: initial !important;}input.toolbox, select.toolbox {background-image: none !important;width: auto;max-height: none;height: initial;}textarea.toolbox, input.toolbox[type=text] {-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;width: 11em;padding: 0.5rem;border-style: solid;}a.toolbox:hover {color: #006db4;}a.toolbox {cursor: pointer;color: #10147e;}input.toolbox[type=button]:hover {background: #006db4;}input.toolbox[type=button] {padding: 4px 8px;background: #10147e;color: white;border-radius: 4px;border: none;cursor: pointer;}[tooltip]:before {position: absolute;opacity: 0;}[tooltip]:hover:before {content: attr(tooltip);opacity: 1;color: black;background: white;padding: 2px;border: 1px groove black;white-space: nowrap;overflow: hidden;right: 0;margin-top: -25pt;}h2.toolbox {font-size: large !important;}`;div.appendChild(sheet);// Hide and Settings buttonconst hide_btn_parent = newtag(div, "div", null);hide_btn_parent.style = "display: flex !important; justify-content: flex-end; padding-right: 10px;";const hide_btn = newtag(hide_btn_parent, "a", "✖");hide_btn.style = "font-size: large !important; text-decoration: none;";hide_btn.addEventListener("click", () => div.remove(), false);// DOI textbox and copy buttonconst txt_doi = newinput(div,"text",doi,null);newbr(div);newinput(div, "button", "Copy", () => {txt_doi.select(); document.execCommand("Copy");});newbr(div);newbr(div);// info textbox and copy buttonconst info = tit + "\t" + doi;const txt_inf = newinput(div, "text", info, null);newbr(div);newinput(div, "button", "Copy", () => {txt_inf.select(); document.execCommand("Copy");});newbr(div);newbr(div);// bibtex buttonconst txt_bib = newtag(div, "textarea", null);txt_bib.style = "resize: none; display: none !important;";newbr(div);const btn_bib_label = "Copy BibTeX";const btn_bib = newinput(div, "button", btn_bib_label, loadBib);newbr(div);function loadBib() {btn_bib.disabled = true;btn_bib.value = "Loading";fetch("https://dx.doi.org/" + doi, {headers: {"Accept": "application/x-bibtex"}}).then(response => response.text()).then(data => {txt_bib.value = data;txt_bib.style.display = "";txt_bib.select();document.execCommand("Copy");btn_bib.value = btn_bib_label;btn_bib.disabled = false;}).catch(error => {alert("Cannot load BibTeX.");btn_bib.value = btn_bib_label;btn_bib.disabled = false;});}// Text buttonconst btn_txt_label = "Copy Text";const btn_txt = newinput(div, "button", btn_txt_label, loadTxt);function loadTxt() {if (sty === "") {setstyle();return;}btn_txt.disabled = true;btn_txt.value = "Loading";fetch("https://dx.doi.org/" + doi, {headers: {"Accept": "text/x-bibliography; style=" + sty}}).then(response => response.text()).then(data => {txt_bib.value = data;txt_bib.style.display = "";txt_bib.select();document.execCommand("Copy");btn_txt.value = btn_txt_label;btn_txt.disabled = false;}).catch(error => {alert("Cannot load text reference.");btn_txt.value = btn_txt_label;btn_txt.disabled = false;});}// text style linkconst stylink = newtag(div, "a", "Style");stylink.addEventListener("click", setstyle, false);newbr(div);function setstyle() {const div = document.createElement("div");div.style = `z-index: 2147483647;position: fixed;left: 50%;top: 50%;transform: translate(-50%, -50%);border: 2px groove black;background: white;padding: 20px;box-shadow: 10px 10px 5px grey;`;newtag(div, "h2", "Choose a citation style for text references:");const sel = newtag(div, "select", null);sel.size = 15;sel.style.minWidth = "600px";newbr(div);newtag(div, "p", "This citation style will be saved as default.").style = "margin-top: 5px !important";newbr(div);const btns = newtag(div, "div", null);btns.style = "display: block !important; text-align: center;";// OK buttonnewinput(btns, "button", "OK", () => {setStyleAndTooltip(sel.value);GM.setValue("sty", sty);document.body.removeChild(div);loadTxt();});// cancel buttonnewinput(btns, "button", "Cancel", () => document.body.removeChild(div)).style.marginLeft = "1em";// load stylesfetch("https://citation.crosscite.org/styles").then(response => response.json()).then(data => {for (const i of data) {const x = document.createElement("option");x.text = i;sel.add(x);}if (sty !== "") {sel.value = sty;} else {sel.selectedIndex = 0;}}).catch(error => {alert("Cannot load style list.");document.body.removeChild(div);});document.body.appendChild(div);}// RIS linkconst rislink = newtag(div, "a", "Download RIS");rislink.addEventListener("click", loadris);function loadris() {rislink.removeEventListener("click", loadris);fetch("https://dx.doi.org/" + doi, {headers: {"Accept": "application/x-research-info-systems"}}).then(response => response.text()).then(data => {const blob = new Blob([data], {type: "octet/stream"});const url = URL.createObjectURL(blob);rislink.href = url;rislink.download = doi.replace("/", "_") + ".ris";rislink.click();}).catch(error => {alert("Cannot download RIS.");rislink.addEventListener("click", loadris);});}newbr(div);newbr(div);// PDF linkif (pdf === null && location.hostname.includes("sciencedirect")) {pdf = sessionStorage.getItem(doi);if (pdf === null) {const pdflink = newtag(div, "a", "PDF");pdflink.addEventListener("click",() => {if (!loadElsevierPDF()) alert("Failed to load PDF link");});newbr(div);newbr(div);}}if (pdf !== null) {const pdflink = newtag(div,"a","PDF");pdflink.href = pdf;newbr(div);newbr(div);}// Sci-Hub linkconst scihubURL = "https://sci-hub.st/";const scihublink = newtag(div, "a", "Sci-Hub");if (doi !== null) {scihublink.href = scihubURL + doi;} else {scihublink.href = scihubURL + location.href;}newbr(div);newbr(div);document.body.appendChild(div);function setStyleAndTooltip(v) {sty = v;stylink.setAttribute("tooltip", v === null ? "Reference style not set" : "Current style: " + v);}GM.getValue("sty", null).then(setStyleAndTooltip);}})();