Created
December 14, 2025 09:23
-
-
Save 0x1d107/3fb99251b62d5086a4e2a510013238ec to your computer and use it in GitHub Desktop.
scripts for bibliography management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #1/bin/bash | |
| SHDIR=$(dirname $(readlink -f $0)) | |
| curl -LsH 'Accept: application/x-bibtex' "https://api.crossref.org/works/$(jq -sRr @uri)/transform"| awk -f $SHDIR/prettybib.awk |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| BEGIN{FS=""} | |
| { | |
| gsub(/^[ \t]+/,"",$0) | |
| for(i=1;i<=NF;i++) | |
| if($i=="{") { | |
| lvl++; | |
| printf("{"); | |
| }else if($i == "}"){ | |
| if(lvl == 1) | |
| print("") | |
| lvl--; | |
| printf("}"); | |
| if(lvl == 0) | |
| print(""); | |
| }else if($i == "," && lvl == 1){ | |
| print(","); | |
| for (k=0;k<lvl;k++) | |
| printf(" "); | |
| }else | |
| printf("%s",$i); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Sebzer | |
| // @namespace https://p1m.org/ | |
| // @version 0.2.8 | |
| // @description Средство экспорта библиографических записей из eLIBRARY.RU (СЕБЗЕР). Добавляет в eLIBRARY.RU возможности экспорта библиографических записей, подобные таковым в PubMed. В настоящее время поддерживается экспорт только со страниц выдачи, только с ограничением по типу публикации «статьи в журналах» и только в формате BibTeX. | |
| // @author Павел Желнов | |
| // @match http*://*.elibrary.ru/* | |
| // @grant none | |
| // @require https://cdn.rawgit.com/eligrey/FileSaver.js/v2.0.2/dist/FileSaver.min.js | |
| // @require https://cdn.jsdelivr.net/npm/citation-js@0.4.10/build/citation.min.js | |
| // ==/UserScript== | |
| $(function() { | |
| 'use strict'; | |
| var elibrary = "https://elibrary.ru"; | |
| const Cite = require('citation-js'); | |
| const record = new Cite(); | |
| var sebzer_bibtex = function () { | |
| let record = new Cite(); | |
| parseSearch(record); | |
| var text = record.format('bibtex'); | |
| var blob = new Blob([text], {type: mime}); | |
| saveAs(blob, filename+"."+ext); | |
| }; | |
| var sebzer_copy_bibtex = function () { | |
| let record = new Cite(); | |
| parseSearch(record); | |
| var text = record.format('bibtex'); | |
| navigator.clipboard.writeText(text); | |
| }; | |
| window.sebzer_copy_bibtex = sebzer_copy_bibtex; | |
| var canvas = '<div id="sebzer-canvas"></div>'; | |
| var style = "width: 630px; text-align: justify; padding: 10px; margin: 10px; background-color: #555555; color: white"; | |
| var button = '<div id="sebzer-button-canvas"><table>'; | |
| button+='<tr><td width="15%" align="center" valign="top"><a id="sebzer-button-pic" href="javascript:sebzer_bibtex()" style="color: white"><img src="images/but_orange.gif" width="15" height="15" hspace="3" border="0"></a></td><td width="85%" align="left" valign="middle"><a id="sebzer-button-text" href="javascript:sebzer_bibtex()" style="color: white">'; | |
| button += 'Экспортировать в файл (BibTeX)'; | |
| button += '</a></td></tr>'; | |
| button+='<tr><td width="15%" align="center" valign="top"><a id="sebzer-button-pic2" href="javascript:sebzer_copy_bibtex()" style="color: white"><img src="images/but_orange.gif" width="15" height="15" hspace="3" border="0"></a></td><td width="85%" align="left" valign="middle"><a id="sebzer-button-text2" href="javascript:sebzer_copy_bibtex()" style="color: white">'; | |
| button += 'Копировать BibTeX'; | |
| button += '</a></td></tr>'; | |
| button+='</table></div>'; | |
| var eSebzerNote = '<div id="sebzer-esebzernote" style="font-weight: bold; color: #F26C4F"><p style="text-indent: 0">'; | |
| eSebzerNote += 'СЕБЗЕР'; | |
| eSebzerNote += '</p></div>'; | |
| var eNotArticleNote = '<div id="sebzer-enotarticlenote"><p style="text-indent: 0">'; | |
| eNotArticleNote += 'В выдаче обнаружены записи с типом публикации, отличным от «статьи в журналах». Обращаем внимание, что такие записи не будут полноценно распарсены. Для исключения таких записей можно в параметрах поиска снять галочки со всех остальных типов публикации.'; | |
| eNotArticleNote += '</p></div>'; | |
| var eNotSearchNote = '<div id="sebzer-enotsearchnote"><p style="text-indent: 0">'; | |
| eNotSearchNote += 'Это не поисковая выдача, поэтому экспорт записей с этой страницы, если таковые на ней имеются, не будет возможен. Вы сможете выгрузить эти записи, если добавите их в какую-либо подборку публикаций, так как экспорт содержимого таких подборок — возможен.'; | |
| eNotSearchNote += '</p></div>'; | |
| var eItemAspNote = '<div id="sebzer-enotsearchnote"><p style="text-indent: 0">'; | |
| eItemAspNote += 'Экспорт со страниц отдельных записей не поддерживается. Чтобы преодолеть это ограничение, добавьте эту запись в какую-либо подборку и затем выгрузьте содержимое этой подборки.'; | |
| eItemAspNote += '</p></div>'; | |
| var e = { notSearch: false, itemAsp: false, popUpWindow: false, notArticle: false }; | |
| var mime = "application/x-bibtex;charset=utf-8"; | |
| var filename = 'elibrary_ru'; | |
| var ext = "bib"; | |
| var ref_regex = /^(.+)\. (\d{4})\. (Т\.? ([\d\wА-я.\-\(\) ]+)\. )?(№\.? ([\d\wА-я.\-\(\) ]+)\. )?(С)\. ([\d\w\-]+)\.$/i; | |
| var au_regex = /^(.*?) ?([^ ]+?)\.?$/i; | |
| var bib_regex = /^@\w+{.*,$/gmi; | |
| function parseSearch(record){ | |
| if (!$('#thepage').length || $('#thepage').prop('outerHTML').toLowerCase().search(/всего найдено публикаций:\s+<\/font>/) === -1) { | |
| e.notSearch = true; | |
| var pagename = location.pathname.substring(1); | |
| switch(pagename) { | |
| case 'item.asp': | |
| e.itemAsp = true; | |
| break; | |
| case 'itembox_item_add2.asp': | |
| case 'itembox_item_add.asp': | |
| e.popUpWindow = true; | |
| break; | |
| } | |
| } | |
| else $('tr').filter(function(){ | |
| return this.id.match(/^a\d+$/g); | |
| }) | |
| .children().filter('td[align="left"]').each(function(){ | |
| var bibjson = {type: "misc"}; | |
| var bibkey = $(this).parent().attr('id'); | |
| let checked = $('#tid'+bibkey.slice(1))[0].checked; | |
| console.log('#tid'+bibkey.slice(1)); | |
| console.log($('#tid'+bibkey.slice(1))[0].checked); | |
| if(!checked && checked !== undefined) | |
| return; | |
| var hasAuthor = ($('font',this).has('i').length == 1) ? true : false; | |
| if (hasAuthor) { | |
| var author = []; | |
| var austr = $('font',this).has('i').not(':has(b)').text().replace('et al.','').trim(); | |
| var auarr = austr.split(', '); | |
| auarr.forEach(function(val, i) { | |
| var au = val.match(au_regex); | |
| var name; | |
| if (au[1]) { | |
| var lastname = au[1]; | |
| var firstname = au[2].replace(/[^a-za-я\d]+/gi,'. ')+"."; | |
| name = lastname + ', ' + firstname; | |
| author.push({ | |
| lastname: lastname, | |
| firstname: firstname, | |
| name: name | |
| }); | |
| } | |
| else { | |
| name = au[2]; | |
| author.push({ | |
| lastname: name, | |
| firstname: name, | |
| name: name | |
| }); | |
| } | |
| }); | |
| bibjson.author = JSON.parse(JSON.stringify(author)); | |
| } | |
| var hasTitle = ($('span',this).has('b').length) ? true : false; | |
| if (hasTitle) | |
| bibjson.title = $('span',this).children().has('b').text().trim(); | |
| var hasRef = ($('span',this).children().not(':has(i),:has(b)').length) ? true : false; | |
| if (hasRef) { | |
| var refstr = $('span',this).children().not(':has(i),:has(b)').text().replace(/\s+/g,' ').trim(); | |
| var refarr = refstr.match(ref_regex); | |
| if (refarr) { | |
| bibjson.type = "article"; | |
| bibjson.journal = {name: refarr[1]}; | |
| bibjson.year = refarr[2]; | |
| if (refarr[4]) | |
| bibjson.journal.volume = refarr[4].replace(/^(\d+).*$/,"$1"); | |
| if (refarr[6]) | |
| bibjson.journal.issue = refarr[6].replace(/^(\d+).*$/,"$1"); | |
| bibjson.journal.pages = refarr[8].replace('-','--'); | |
| if (!hasAuthor) | |
| bibjson.author = [{name: "Б.а."}]; | |
| if (!hasTitle) | |
| bibjson.title = "Б.н."; | |
| } | |
| else { | |
| e.notArticle = true; | |
| bibjson.note = refstr; | |
| if (refstr.match(/^\d{4}$/)) | |
| bibjson.year = refstr; | |
| } | |
| } | |
| var hasUrl = ($('span',this).children().eq(0).has('[href]')) ? true : false; | |
| if (hasUrl) { | |
| var url = elibrary + $('span',this).children().eq(0).attr('href'); | |
| var link = [{url: url}]; | |
| bibjson.link = link; | |
| } | |
| var bibtex = new Cite(bibjson).format('bibtex'); | |
| var label = "@" + bibjson.type + "{" + bibkey + ","; | |
| bibtex = bibtex.replace(bib_regex, label).replace(/\{\\[^\}]+}/g,'�'); | |
| record.add(bibtex); | |
| }); | |
| } | |
| if (!e.popUpWindow) { | |
| $('table').before(canvas); | |
| $('#sebzer-canvas').attr("style", style); | |
| $('#sebzer-canvas').append(eSebzerNote); | |
| if(e.notSearch) { | |
| var note = (e.itemAsp) ? eItemAspNote : eNotSearchNote; | |
| $('#sebzer-canvas').append(note); | |
| } | |
| else { | |
| if(e.notArticle) | |
| $('#sebzer-canvas').append(eNotArticleNote); | |
| $('#sebzer-canvas').append(button); | |
| $('#sebzer-button-pic').click(sebzer_bibtex); | |
| $('#sebzer-button-text').click(sebzer_bibtex); | |
| } | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment