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

QingJ © 2025

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