wiki-reference

Позволяет генерировать ссылки в формате {{Статья}} и {{книга}} для ру-вики

当前为 2014-05-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name wiki-reference
  3. // @namespace torvin
  4. // @include https://www.ncbi.nlm.nih.gov/pubmed/*
  5. // @include http://www.ncbi.nlm.nih.gov/pubmed/*
  6. // @include http://adsabs.harvard.edu/abs/*
  7. // @include http://adsabs.harvard.edu/doi/*
  8. // @include http://ufn.ru/ru/articles/*
  9. // @include http://books.google.*/books?*
  10. // @include http://www.sciencedirect.com/science/article/*
  11. // @include http://gen.lib.rus.ec/scimag/*
  12. // @include http://onlinelibrary.wiley.com/doi/*
  13. // @include http://www.jstor.org/stable/*
  14. // @include http://www.jstor.org/discover/*
  15. // @version 1.5.2
  16. // @description Позволяет генерировать ссылки в формате {{Статья}} и {{книга}} для ру-вики
  17. // @grant GM_xmlhttpRequest
  18. // ==/UserScript==
  19.  
  20. const templates = {
  21. article: 'Статья',
  22. book: 'книга',
  23. };
  24.  
  25. var Template = function(name) {
  26. var attrs = [];
  27.  
  28. this.add = function(name, value) {
  29. attrs.push({
  30. name: name,
  31. value: value
  32. });
  33. return this;
  34. };
  35.  
  36. var getAttr = function(x) {
  37. return "|" + x.name + (x.value === undefined ? "" : " = " + x.value);
  38. };
  39.  
  40. this.toWiki = function() {
  41. if (attrs.length == 1)
  42. return "{{" + name + getAttr(attrs[0]) + "}}";
  43. else
  44. return "{{" + name + "\n" + attrs.map(function(x) { return " " + getAttr(x)}).join("\n") + "\n}}";
  45. };
  46. };
  47.  
  48. var pubmed = {
  49. 'автор': {
  50. selector: 'Article > AuthorList > Author',
  51. map: function(node) { return [ node.querySelector('LastName'), node.querySelector('Initials') ] },
  52. mapText: function(nodes) { return new Template('nobr').add(nodes[0] + ' ' + nodes[1].replace(/(.)/g, "$1. ").trim()).toWiki() },
  53. },
  54. 'заглавие': {
  55. selector: 'Article > ArticleTitle',
  56. mapText: function(text) { return text.replace(/^(.*?)\.?$/, "$1") },
  57. },
  58. 'издание': {
  59. selector: 'Article > Journal > Title',
  60. },
  61. 'год': {
  62. selector: 'Article > Journal > JournalIssue > PubDate',
  63. mapText: function(text) { return /^\s*(\d{4})/.exec(text)[1] },
  64. },
  65. 'выпуск': {
  66. selector: 'Article > Journal > JournalIssue > Issue',
  67. },
  68. 'том': {
  69. selector: 'Article > Journal > JournalIssue > Volume',
  70. },
  71. 'страницы': {
  72. selector: 'Article > Pagination > MedlinePgn',
  73. },
  74. 'issn': {
  75. selector: 'Article > Journal > ISSN[IssnType=Electronic]',
  76. },
  77. 'doi': {
  78. selector: 'ArticleIdList > ArticleId[IdType=doi]',
  79. },
  80. 'pmid': {
  81. selector: 'ArticleIdList > ArticleId[IdType=pubmed]',
  82. },
  83. 'ссылка': { const: "" },
  84. 'ref': { const: "" },
  85. 'archiveurl': { const: "" },
  86. 'archivedate': { const: "" },
  87. };
  88.  
  89. var getText = function(node) {
  90. return node instanceof Element ? node.textContent : node;
  91. };
  92.  
  93. var ajax = function(params) {
  94. setTimeout(function() {
  95. GM_xmlhttpRequest(params)
  96. }, 0);
  97. }
  98.  
  99. var clone = function(obj) {
  100. var target = {};
  101. for (var i in obj) {
  102. var value = obj[i];
  103. if (value instanceof Function)
  104. ;
  105. else if (typeof value == 'string')
  106. ;
  107. else
  108. value = clone(value);
  109. target[i] = value;
  110. }
  111. return target;
  112. }
  113.  
  114. var getWpFromXml = function(name, rules, xml) {
  115. var article = new Template(name);
  116.  
  117. for(var name in rules) {
  118. var rule = rules[name];
  119. article.add(name, rule.const ||
  120. Array.slice(xml.querySelectorAll(rule.selector)).map(function(node) {
  121. if (rule.map)
  122. node = rule.map(node);
  123. return Array.isArray(node) ? node.map(getText) : getText(node);
  124. }).map(function(item) {
  125. return rule.mapText ? rule.mapText(item) : item;
  126. }).join(rule.separator || ', ')
  127. );
  128. }
  129.  
  130. return article.toWiki();
  131. };
  132.  
  133. var Parser = function(sourceText, index, tokens) {
  134. var _match;
  135. var _isEof;
  136.  
  137. //var _tokenRegex = /(\s*)(\{|\}|,|=|\\\W|\\[\w]+|[^\{\},\\=\s])/g;
  138. var _tokenRegex = new RegExp("(\\s*)(" + tokens.map(function(x) { return x.source || x }).join('|') + ")", 'g');
  139. _tokenRegex.lastIndex = index;
  140.  
  141. var getToken = function() {
  142. if (_isEof)
  143. throw new Error("EOF");
  144.  
  145. var index = _tokenRegex.lastIndex;
  146.  
  147. var res = _tokenRegex.exec(sourceText);
  148. if (!res) {
  149. _isEof = true;
  150. return null;
  151. }
  152. _match = {
  153. match: res[0],
  154. token: res[2],
  155. space: res[1].replace(/\s+/g, ' '),
  156. index: index,
  157. }
  158. }
  159.  
  160. this.matchAny = function() {
  161. var res = _match;
  162. getToken();
  163. return res;
  164. }
  165.  
  166. this.match = function(str) {
  167. if (_match.token !== str)
  168. throw new Error("Parser error at pos " + _tokenRegex.lastIndex + ". Expected '" + str + "', found '" + _match.token + "'.");
  169. return this.matchAny();
  170. }
  171.  
  172. this.matchIgnoreCase = function(str) {
  173. if (_match.token.toUpperCase() !== str.toUpperCase())
  174. throw new Error("Parser error at pos " + _tokenRegex.lastIndex + ". Expected '" + str + "', found '" + _match.token + "'.");
  175. return this.matchAny();
  176. }
  177.  
  178. this.matchAnyIgnoreCase = function(strs) {
  179. if (strs.every(function(str) { return _match.token.toUpperCase() !== str.toUpperCase(); }))
  180. throw new Error("Parser error at pos " + _tokenRegex.lastIndex + ". Expected any of: '" + strs.join("', '") + "', found '" + _match.token + "'.");
  181. return this.matchAny();
  182. }
  183.  
  184. this.matchNot = function(strs) {
  185. if (strs.indexOf(_match.token) != -1)
  186. throw new Error("Parser error at pos " + _tokenRegex.lastIndex + ". Unexpected '" + _match.token + "'.");
  187. return this.matchAny();
  188. }
  189.  
  190. this.index = function() {
  191. return _match.index;
  192. }
  193.  
  194. Object.defineProperty(this, "token", { get: function() { return _match.token; }});
  195.  
  196. getToken();
  197. }
  198.  
  199. var Bibtex = function(sourceText, index, entryTypes) {
  200. var _plainText = /[^\{\},\\=\s]+/;
  201. const _tokens = [
  202. /\{/,
  203. /\}/,
  204. /,/,
  205. /=/,
  206. /@/,
  207. /\\\W/,
  208. /\\[\w]+/,
  209. _plainText,
  210. ];
  211.  
  212. var _parser = new Parser(sourceText, index, _tokens);
  213.  
  214. var entry = function() {
  215. _parser.match("{");
  216. var id = fieldValue();
  217. _parser.match(",");
  218. var f = fields();
  219. _parser.match("}");
  220.  
  221. f.bibcode = id;
  222. return f;
  223. }
  224.  
  225. var comment = function() {
  226. _parser.match("{");
  227. var text = fieldValue();
  228. _parser.match("}");
  229. return { comment: text };
  230. }
  231.  
  232. var type = function() {
  233. _parser.match('@');
  234. var token = _parser.token;
  235. if (entryTypes.length)
  236. _parser.matchAnyIgnoreCase(entryTypes);
  237. else
  238. _parser.matchAny();
  239. return token;
  240. }
  241.  
  242. var fields = function() {
  243. var res = {};
  244. for(;;) {
  245. var f = field();
  246. res[f.name] = f.value;
  247. if (_parser.token !== ",") break;
  248. _parser.match(",");
  249. if (_parser.token === "}") break;
  250. }
  251. return res;
  252. }
  253.  
  254. var quoted = function() {
  255. return _parser.match("{").space + quotedValue() + _parser.match("}").space;
  256. }
  257.  
  258. var diacritics = {
  259. '`': '\u0300',
  260. '\'': '\u0301',
  261. '^': '\u0302',
  262. '~': '\u0303',
  263. '=': '\u0304',
  264. 'u': '\u0306',
  265. '.': '\u0307',
  266. '"': '\u0308',
  267. 'r': '\u030a',
  268. 'H': '\u030b',
  269. 'v': '\u030c',
  270. 'c': '\u0327',
  271. 'k': '\u0328',
  272. 'd': '\u0323',
  273. 'b': '\u0331',
  274. 't': '\u0361',
  275. };
  276.  
  277. var ligatures = {
  278. 'L': '\u0141',
  279. 'l': '\u0142',
  280. 'AA': '\u00c5',
  281. 'aa': '\u00e5',
  282. 'AE': '\u00c6',
  283. 'ae': '\u00e6',
  284. 'O': '\u00d8',
  285. 'o': '\u00f8',
  286. 'OE': '\u0152',
  287. 'oe': '\u0153',
  288. 'i': '\u0131',
  289. 'j': '\u0237',
  290. 'ss': '\u00df',
  291. };
  292.  
  293. var entity = function() {
  294. if (_parser.token[0] != '\\')
  295. throw new Error("Expected entity, found " + _parser.token);
  296.  
  297. var cmd = _parser.matchAny().token.substr(1);
  298.  
  299. var value = ligatures[cmd];
  300. if (value)
  301. return value;
  302.  
  303. value = diacritics[cmd];
  304. if (value)
  305. return fieldValue() + value;
  306.  
  307. return cmd;
  308. }
  309.  
  310. var quotedValue = function() {
  311. var res = "";
  312. for(;;) {
  313. if (_parser.token === "{")
  314. res += quoted();
  315. else if (_parser.token === "}")
  316. break;
  317. else if (_parser.token[0] === '\\')
  318. res += entity();
  319. else
  320. res += _parser.matchAny().match;
  321. }
  322. return res;
  323. }
  324.  
  325. var fieldValue = function() {
  326. var res = "";
  327. for(;;) {
  328. if (_parser.token == "{")
  329. res += quoted();
  330. else if (_parser.token[0] === '\\')
  331. res += entity();
  332. else if (_plainText.test(_parser.token))
  333. res += _parser.matchAny().match;
  334. else
  335. break;
  336. }
  337. return res.trim().replace(/^"?(.*?)"?$/, '$1').replace(/---?/g, '—');
  338.  
  339. }
  340.  
  341. var field = function() {
  342. var name = fieldValue();
  343. _parser.match("=");
  344. var value = fieldValue();
  345.  
  346. return {
  347. name: name,
  348. value: value
  349. }
  350. }
  351.  
  352. if (!entryTypes)
  353. entryTypes = []
  354. else if (typeof entryTypes == 'string' || entryTypes instanceof String)
  355. entryTypes = [ entryTypes ];
  356. var realType = type(entryTypes);
  357.  
  358. if (realType.toLowerCase() == 'comment')
  359. var result = comment();
  360. else
  361. var result = entry();
  362.  
  363. result.type = realType;
  364. result._index = _parser.index();
  365. return result;
  366. }
  367.  
  368. var bibtexBase = {
  369. 'автор': {
  370. selector: 'author',
  371. getAuthors: function(text) {
  372. return text.split(' and ').map(function(name) {
  373. return name.replace(/~/g, ' ').replace(',', '');
  374. });
  375. },
  376. getWiki: function(authors) {
  377. return authors.map(function(name) {
  378. return new Template('nobr').add(name).toWiki()
  379. }).join(', ');
  380. },
  381. map: function(text) {
  382. var me = bibtexBase['автор'];
  383. return me.getWiki(me.getAuthors(text));
  384. },
  385. },
  386. 'заглавие': {
  387. selector: 'title',
  388. map: function(text) {
  389. return text.replace(/^"|"$/g, '')
  390. }
  391. },
  392. 'издание': {
  393. selector: 'journal',
  394. map: function(text) {
  395. return {
  396. aj: 'Astronomical Journal',
  397. actaa: 'Acta Astronomica',
  398. araa: 'Annual Review of Astron and Astrophys',
  399. apj: 'Astrophysical Journal',
  400. apjl: 'Astrophysical Journal, Letters',
  401. apjs: 'Astrophysical Journal, Supplement',
  402. ao: 'Applied Optics',
  403. apss: 'Astrophysics and Space Science',
  404. aap: 'Astronomy and Astrophysics',
  405. aapr: 'Astronomy and Astrophysics Reviews',
  406. aaps: 'Astronomy and Astrophysics, Supplement',
  407. azh: 'Astronomicheskii Zhurnal',
  408. baas: 'Bulletin of the AAS',
  409. caa: 'Chinese Astronomy and Astrophysics',
  410. cjaa: 'Chinese Journal of Astronomy and Astrophysics',
  411. icarus: 'Icarus',
  412. jcap: 'Journal of Cosmology and Astroparticle Physics',
  413. jrasc: 'Journal of the RAS of Canada',
  414. memras: 'Memoirs of the RAS',
  415. mnras: 'Monthly Notices of the RAS',
  416. na: 'New Astronomy',
  417. nar: 'New Astronomy Review',
  418. pra: 'Physical Review A: General Physics',
  419. prb: 'Physical Review B: Solid State',
  420. prc: 'Physical Review C',
  421. prd: 'Physical Review D',
  422. pre: 'Physical Review E',
  423. prl: 'Physical Review Letters',
  424. pasa: 'Publications of the Astron. Soc. of Australia',
  425. pasp: 'Publications of the ASP',
  426. pasj: 'Publications of the ASJ',
  427. rmxaa: 'Revista Mexicana de Astronomia y Astrofisica',
  428. qjras: 'Quarterly Journal of the RAS',
  429. skytel: 'Sky and Telescope',
  430. solphys: 'Solar Physics',
  431. sovast: 'Soviet Astronomy',
  432. ssr: 'Space Science Reviews',
  433. zap: 'Zeitschrift fuer Astrophysik',
  434. nat: 'Nature',
  435. iaucirc: 'IAU Cirulars',
  436. aplett: 'Astrophysics Letters',
  437. apspr: 'Astrophysics Space Physics Research',
  438. bain: 'Bulletin Astronomical Institute of the Netherlands',
  439. fcp: 'Fundamental Cosmic Physics',
  440. gca: 'Geochimica Cosmochimica Acta',
  441. grl: 'Geophysics Research Letters',
  442. jcp: 'Journal of Chemical Physics',
  443. jgr: 'Journal of Geophysics Research',
  444. jqsrt: 'Journal of Quantitiative Spectroscopy and Radiative Transfer',
  445. memsai: 'Mem. Societa Astronomica Italiana',
  446. nphysa: 'Nuclear Physics A',
  447. physrep: 'Physics Reports',
  448. physscr: 'Physica Scripta',
  449. planss: 'Planetary Space Science',
  450. procspie: 'Proceedings of the SPIE',
  451. }[text] || text;
  452. },
  453. },
  454. 'год': {
  455. selector: 'year',
  456. },
  457. 'выпуск': {
  458. selector: 'number',
  459. },
  460. 'том': {
  461. selector: 'volume',
  462. },
  463. 'страницы': {
  464. selector: 'pages',
  465. },
  466. 'издательство': {
  467. selector: 'publisher',
  468. },
  469. 'issn': {
  470. selector: 'issn',
  471. },
  472. 'doi': {
  473. selector: 'doi',
  474. },
  475. 'arxiv': {
  476. selector: 'eprint',
  477. map: function(text) {
  478. const prefix = 'arXiv:';
  479. if (text.indexOf(prefix) == 0)
  480. text = text.substr(prefix.length);
  481. return text;
  482. }
  483. },
  484. 'ссылка': { const: "" },
  485. 'ref': { const: "" },
  486. 'archiveurl': { const: "" },
  487. 'archivedate': { const: "" },
  488. };
  489.  
  490. var adsabsBibcode = (function() {
  491. var bibtex = clone(bibtexBase);
  492. bibtex.bibcode = { selector: 'bibcode' };
  493. return bibtex;
  494. })();
  495.  
  496. var ufnBibtex = (function() {
  497. var bibtex = clone(bibtexBase);
  498.  
  499. var nameRegex = /^(.+) (\S+)$/;
  500. var author = bibtex['автор'];
  501. author.map = function(text) {
  502. return author.getWiki(author.getAuthors(text).map(function(name) {
  503. var match = nameRegex.exec(name);
  504. if (!match) return name;
  505. return match[2] + ' ' + match[1];
  506. }));
  507. }
  508. return bibtex;
  509. })();
  510.  
  511. var googleBibtex = function(url) {
  512. var bibtex = clone(bibtexBase);
  513. bibtex.серия = { 'selector': 'series' };
  514. bibtex.страниц = { const: "" };
  515. bibtex.isbn = { 'selector': 'isbn' };
  516. delete bibtex.ссылка;
  517. delete bibtex.archiveurl;
  518. delete bibtex.archivedate;
  519. delete bibtex.ref;
  520. bibtex.ссылка = { const: url };
  521. bibtex.ref = { const: "" };
  522. return bibtex;
  523. };
  524.  
  525. var sciencedirectBibtex = (function() {
  526. var bibtex = clone(bibtexBase);
  527. bibtex.ссылка = { selector: 'url' };
  528. bibtex.doi.map = function(text) {
  529. var res = /http:\/\/dx\.doi\.org\/(.*)$/.exec(text) || [];
  530. return res[1] || text;
  531. }
  532. bibtex.страницы.map = function(text) {
  533. return text.replace(' - ', '—')
  534. }
  535. return bibtex;
  536. })();
  537.  
  538. var libGenesisBibtex = (function() {
  539. var bibtex = clone(bibtexBase);
  540. bibtex.выпуск = { selector: 'issue' };
  541. bibtex.страницы = { selector: 'page' };
  542. return bibtex;
  543. })();
  544.  
  545. var wileyBibtex = (function() {
  546. var bibtex = clone(bibtexBase);
  547. bibtex.ссылка = { selector: 'url' };
  548. return bibtex;
  549. })();
  550.  
  551. var jstorBibtex = (function() {
  552. var bibtex = clone(bibtexBase);
  553. bibtex.ссылка = { selector: 'url' };
  554. bibtex.выпуск.selector = function(obj) {
  555. return obj['number'] || obj['jstor_issuetitle'];
  556. }
  557. bibtex.страницы.map = function(text) {
  558. return text.replace(/^p?p\. /, "").replace('-', '—');
  559. };
  560. return bibtex;
  561. })();
  562.  
  563. var getWpFromObj = function(name, rules, obj) {
  564. var article = new Template(name);
  565.  
  566. for(var name in rules) {
  567. var rule = rules[name];
  568.  
  569. var value;
  570. if (rule.const !== undefined)
  571. value = rule.const
  572. else {
  573. if (typeof rule.selector === "function")
  574. value = rule.selector(obj);
  575. else
  576. value = obj[rule.selector];
  577. if (!value)continue;
  578. }
  579.  
  580. if (rule.map)
  581. value = rule.map(value, obj);
  582.  
  583. article.add(name, value);
  584. }
  585.  
  586. return article.toWiki();
  587. }
  588.  
  589. var testUrl = function(regex) {
  590. return regex.exec(window.location.href)
  591. }
  592.  
  593. var createWpButton = function(onclick, tag) {
  594. var element = document.createElement(tag || 'a');
  595. element.setAttribute('href', '#');
  596. element.textContent = 'WP';
  597. element.addEventListener('click', function(e) {
  598. e.preventDefault();
  599. onclick();
  600. });
  601. return element;
  602. }
  603.  
  604. var pages = [
  605. // pubmed
  606. {
  607. test: function() {
  608. return testUrl(/\/pubmed\/(\d+)$/);
  609. },
  610. process: function(match) {
  611. var $ = unsafeWindow.jQuery;
  612. var id = match[1];
  613. $('#messagearea').after(
  614. $('<div>').append(
  615. $('<a>').attr('href', '#').text('WP').click(function(e) {
  616. e.preventDefault();
  617.  
  618. ajax({
  619. method: "GET",
  620. url: id + '?dopt=Abstract&report=xml&format=text',
  621. onload: function(response) {
  622. var html = new DOMParser().parseFromString(response.responseText, "text/html");
  623. var xml = new DOMParser().parseFromString(html.body.textContent, "text/xml");
  624. alert(getWpFromXml(templates.article, pubmed, xml));
  625. }
  626. });
  627. })
  628. )
  629. );
  630. },
  631. },
  632. // adsabs
  633. {
  634. test: function() {
  635. return testUrl(/adsabs\.harvard\.edu\/(abs|doi)\/(.*)$/);
  636. },
  637. process: function(match) {
  638. var id = match[2];
  639. var button = createWpButton(function() {
  640. ajax({
  641. method: "GET",
  642. url: '/cgi-bin/nph-bib_query?data_type=BIBTEX&bibcode=' + id,
  643. onload: function(response) {
  644. var index = response.responseText.indexOf('@ARTICLE{');
  645. if (index == -1) {
  646. alert('bibtex not found');
  647. return;
  648. }
  649.  
  650. try {
  651. alert(getWpFromObj(templates.article, adsabsBibcode, Bibtex(response.responseText, index, 'article')));
  652. } catch(e) {
  653. alert(e + '\n' + e.stack);
  654. }
  655. }
  656. });
  657. }, false);
  658. var heading = document.body.querySelector('h3');
  659. heading.appendChild(document.createTextNode(' '));
  660. heading.appendChild(button);
  661. },
  662. },
  663. // ufn
  664. {
  665. test: function() {
  666. return testUrl(/\/ufn\.ru\/ru\/articles\/(\d+\/\d+\/\w+)\//);
  667. },
  668. process: function(match) {
  669. var id = match[1];
  670.  
  671. var button = createWpButton(function() {
  672. ajax({
  673. method: "GET",
  674. url: '/ru/articles/' + id + '/citation/ru/bibtex.html',
  675. onload: function(response) {
  676. var html = new DOMParser().parseFromString(response.responseText, "text/html");
  677.  
  678. var node = html.body.querySelector('.cit_code > pre');
  679. if (!node) {
  680. alert('bibtex not found');
  681. return;
  682. }
  683.  
  684. try {
  685. alert(getWpFromObj(templates.article, ufnBibtex, Bibtex(node.textContent, 0, 'article')));
  686. } catch(e) {
  687. alert(e + '\n' + e.stack);
  688. }
  689. }
  690. });
  691. });
  692.  
  693. var node = document.body.querySelector('#print > table tr > td').nextSibling;
  694. var td = document.createElement('TD');
  695. td.appendChild(button);
  696. node.parentNode.insertBefore(td, node);
  697. },
  698. },
  699. // google books
  700. {
  701. test: function() {
  702. return window.self == window.top && testUrl(/http:\/\/books\.google\.\w+\/books\?id=([^&$]+)/);
  703. },
  704. process: function(match) {
  705. var id = match[1];
  706.  
  707. var button = createWpButton(function() {
  708. ajax({
  709. method: "GET",
  710. url: 'http://books.google.us/books/download/?id=' + id + '&output=bibtex',
  711. onload: function(response) {
  712. try {
  713. alert(getWpFromObj(templates.book, googleBibtex('http://books.google.com/books?id=' + id), Bibtex(response.responseText, 0, 'book')));
  714. } catch(e) {
  715. alert(e + '\n' + e.stack);
  716. }
  717. }
  718. });
  719. });
  720. button.setAttribute('class', 'gb-button')
  721. button.setAttribute('style', 'margin-left: 4px')
  722.  
  723. var item = document.body.querySelector('.metadata_value > .gb-button:last-child');
  724. if (item !== null)
  725. item.parentNode.appendChild(button);
  726. },
  727. },
  728. // sciencedirect
  729. {
  730. test: function() {
  731. return testUrl(/sciencedirect\.com\/science\/article\//);
  732. },
  733. process: function() {
  734. var $ = unsafeWindow.jQuery;
  735. var button = createWpButton(function() {
  736. var params = [];
  737. $('form[name=exportCite] input[type=hidden]').each(function(i, hidden) {
  738. params.push(encodeURIComponent($(hidden).attr('name')) + '=' + encodeURIComponent($(hidden).val()));
  739. })
  740. ajax({
  741. method: "GET",
  742. url: $('form[name=exportCite]').attr('action') + params.join('&') + '&citation-type=BIBTEX',
  743. onload: function(response) {
  744. try {
  745. alert(getWpFromObj(templates.article, sciencedirectBibtex, Bibtex(response.responseText, 0, 'article')));
  746. } catch(e) {
  747. alert(e + '\n' + e.stack);
  748. }
  749. }
  750. });
  751. }, 'input');
  752.  
  753. $('.exportTxt').after($('<div />').append(
  754. $(button).attr('type', 'button').val('WP').css({
  755. 'border-radius': '5px',
  756. 'padding': '3px 5px 3px 24px',
  757. 'border': '1px solid rgb(204, 204, 204)',
  758. 'color': '#0156AA',
  759. 'background': '#FFF',
  760. 'margin-left': '2px',
  761. 'cursor': 'pointer',
  762. 'height': '24px',
  763. 'margin-bottom': '5px',
  764. 'font-weight': 'bold',
  765. })
  766. ));
  767. },
  768. },
  769. // Library Genesis
  770. {
  771. test: function() {
  772. return testUrl(/gen\.lib\.rus\.ec\/scimag\//);
  773. },
  774. process: function() {
  775. var node = document.querySelector('form[name=search]');
  776. while(node && node.nodeName != 'TABLE') {
  777. node = node.nextSibling;
  778. }
  779. var rows = node.querySelectorAll('tr');
  780. for(var i = 0; i < rows.length; i++) {
  781. let doi = rows[i].querySelector('td:first-child').textContent;
  782. var button = createWpButton(function() {
  783. ajax({
  784. method: "GET",
  785. url: 'http://gen.lib.rus.ec/scimag/bibtex.php?doi=' + doi,
  786. onload: function(response) {
  787. var html = new DOMParser().parseFromString(response.responseText, "text/html");
  788. try {
  789. alert(getWpFromObj(templates.article, libGenesisBibtex, Bibtex(html.querySelector('textarea#bibtext').value, 0, 'article')));
  790. } catch(e) {
  791. alert(e + '\n' + e.stack);
  792. }
  793. }
  794. });
  795. });
  796. rows[i].querySelector('td:last-child').appendChild(button);
  797. button.style.fontWeight = 'bold';
  798. }
  799. }
  800. },
  801. // wiley
  802. {
  803. test: function() {
  804. return testUrl(/onlinelibrary\.wiley\.com\/doi\//)
  805. },
  806. process: function() {
  807. var $ = unsafeWindow.$;
  808. var doi = /^DOI:\s+(.+)$/.exec($('#doi').text().trim());
  809. if (!doi) return;
  810. doi = doi[1];
  811.  
  812. var button = createWpButton(function() {
  813. ajax({
  814. method: 'POST',
  815. url: '/documentcitationdownloadformsubmit',
  816. data: 'doi=' + encodeURIComponent(doi) + '&fileFormat=BIBTEX&hasAbstract=CITATION',
  817. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  818. onload: function(response) {
  819. try {
  820. var bibtex = Bibtex(response.responseText, 0);
  821. bibtex.url = window.location.href;
  822.  
  823. var template = {
  824. 'article': templates.article,
  825. }[bibtex.type.toLowerCase()];
  826.  
  827. if (!template) {
  828. alert('unknown type: ' + bibtex.type);
  829. return;
  830. }
  831. alert(getWpFromObj(template, wileyBibtex, bibtex));
  832. } catch(e) {
  833. alert(e + '\n' + e.stack);
  834. }
  835. }
  836. });
  837. });
  838. setTimeout(function() {
  839. $('#toggleAddInfo').append(button);
  840. }, 500);
  841. }
  842. },
  843. // jstor
  844. {
  845. test: function() {
  846. return testUrl(/www\.jstor\.org\/[^\/]+\/(.*?)($|\?)/)
  847. },
  848. process: function(doi) {
  849. doi = decodeURIComponent(doi[1]);
  850. var button = createWpButton(function() {
  851. ajax({
  852. method: 'GET',
  853. url: '/action/downloadSingleCitationSec?userAction=export&format=bibtex&include=abs&singleCitation=true&noDoi=yesDoi&doi=' + doi,
  854. onload: function(response) {
  855. try {
  856. var txt = response.responseText.trim();
  857. const header = 'JSTOR CITATION LIST';
  858.  
  859. var index = txt.indexOf(header);
  860. if (index == -1)
  861. throw new Error('header not found');
  862. index += header.length;
  863.  
  864. while(index < txt.length) {
  865. var bibtex = Bibtex(txt, index, [ 'article', 'comment', 'book' ]);
  866. if (bibtex.type != 'comment')
  867. break;
  868. index = bibtex._index;
  869. }
  870.  
  871. if (!bibtex)
  872. throw new Error('bibtex not found');
  873.  
  874. var template = {
  875. 'article': templates.article,
  876. 'book': templates.book,
  877. }[bibtex.type.toLowerCase()];
  878. alert(getWpFromObj(template, jstorBibtex, bibtex));
  879. } catch(e) {
  880. alert(e + '\n' + e.stack);
  881. }
  882. }
  883. });
  884. });
  885.  
  886. document.querySelector('#navSearchContainer').appendChild(button);
  887. button.style.marginLeft = "10px"
  888. }
  889. },
  890. ];
  891.  
  892. try {
  893. pages.forEach(function(page) {
  894. var res = page.test();
  895. if (res) {
  896. page.process(res);
  897. return false; // break
  898. }
  899. });
  900. } catch(e) {
  901. alert(e);
  902. }

QingJ © 2025

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