diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/biblatex-gb7714-2015/biblatex-map.py')
-rw-r--r-- | Master/texmf-dist/doc/latex/biblatex-gb7714-2015/biblatex-map.py | 2059 |
1 files changed, 1874 insertions, 185 deletions
diff --git a/Master/texmf-dist/doc/latex/biblatex-gb7714-2015/biblatex-map.py b/Master/texmf-dist/doc/latex/biblatex-gb7714-2015/biblatex-map.py index 4ab2325fcd8..ff6a76fbd70 100644 --- a/Master/texmf-dist/doc/latex/biblatex-gb7714-2015/biblatex-map.py +++ b/Master/texmf-dist/doc/latex/biblatex-gb7714-2015/biblatex-map.py @@ -1,44 +1,16 @@ #!/usr/bin/env python """ -python script to modify bib data - -features: -1. souce map of biblatex -2. generalize date - -history: -v1.0 2019/02/09 - -biblatex source map opts: - -已实现的选项: -typesource=⟨entrytype⟩ -typetarget=⟨entrytype⟩ -fieldsource=⟨entryfield⟩ -fieldtarget=⟨entryfield⟩ -match=⟨regexp⟩ -matchi=⟨regexp⟩ -notmatch=⟨regexp⟩ -notmatchi=⟨regexp⟩ -replace=⟨regexp⟩ - -未实现的选项 -notfield=⟨entryfield⟩ -fieldset=⟨entryfield⟩ -fieldvalue=⟨string⟩ -entryclone=⟨clonekey⟩ -entrynew=⟨entrynewkey⟩ -entrynewtype=⟨string⟩ -entrytarget=⟨string⟩ -entrynocite=true, false default: false -entrynull=true, false default: false -append=true, false default: false -final=true, false default: false -null=true, false default: false -origfield=true, false default: false -origfieldval=true, false default: false -origentrytype=true, false default: false +A python script to modify bib data and +to display references with specific bibliography standard + +two key features: + +两大核心功能 +1. bib文件抽取,bib文件内容的自定义修改 +2. 格式化文献表输出,包括json,bib,text,html,bbl文件,其中bbl文件可以在tex源代码中直接使用,利用natbib宏包可以实现不同的标注样式。 + + """ __author__ = "Hu zhenzhen" @@ -51,14 +23,21 @@ import re import sys import datetime import copy +import json +import operator + # # 为数据map设置参数 +# 选项的逻辑与biblatex基本一致, +# 差别包括:overwrite选项可以放到step步中表示 #[]=maps #[[],[]]=map in maps #[[[]],[]]=step in map in mpas #[[[{optionkey: }]],[]]=step in map in mpas +#注意python正则表达方式与perl的略有不同,比如unicode表示 +#python用\xHH,\uHHHH,\UHHHHHHHH表示,而perl直接用\x{HHHH}表示。 sourcemaps=[#maps [#map1:将ELECTRONIC类型转换为online类型 [{"typesource":"ELECTRONIC","typetarget":"online"}]#step1 @@ -70,14 +49,1267 @@ sourcemaps=[#maps [{"fieldsource":"urldate","match":r'(\d\d\d\d)\-(\d)\-(\d)',"replace":r'\1-0\2-0\3'}]#step1 ], [#map4:将urldate域的信息“yyyy-m-d”转换为“yyyy-mm-dd”,注意正则表达式直接写不用在外面套"" - [{"fieldsource":"date","match":r'(\d\d\d\d)\-(\d)\-(\d)',"replace":r'\1-0\2-0\3'}]#step1 + [{"fieldsource":"date","match":r'(\d\d\d\d)\-(\d)\-(\d)',"replace":r'\1-0\2-0\3',"overwrite":True}]#step1 ], [#map5:将refdate域转换为urldate域 [{"fieldsource":"refdate","fieldtarget":"urldate"}]#step1 ], - + [#map6:对于newspaper类型,设置note为news + [{"pertype":"newspaper"}],#step1 + [{"fieldset":"note","fieldvalue":"news","overwrite":True}]#step2 + ], + [#map7:设置edition域等于version + [{"fieldsource":"version","final":True}],#step1 + [{"fieldset":"edition","origfieldval":True}]#step2 + ], + [#map8:设置entrykey域设置给keywords + [{"fieldsource":"entrykey"}],#step1 + [{"fieldset":"keywords","origfieldval":True}]#step2 + ], + [#map9:对于存在note域的情况,将其值添加到keywords + [{"fieldsource":"note","final":True}],#step1 + [{"fieldset":"keywords","origfieldval":True,"overwrite":True,"append":True}]#step2 + ], + [#map10:根据标题的字符编码范围确定标题的语言类型 + [{"fieldsource":"title","match":r'[\u2FF0-\u9FA5]',"final":True}],#step1 + [{"fieldset":"userd","fieldvalue":"chinese"}]#step2 + ], ] +#重设新的任务处理 +sourcemaps=[ + [#map1:设置entrykey域设置给keywords + [{"fieldsource":"entrykey"}],#step1 + [{"fieldset":"keywords","origfieldval":True,"overwrite":True}]#step2 + ], +] + + +#重设新的任务 +sourcemaps=[ + [#map1:取消note域 + [{"fieldsource":"note","final":True}],#step1 + [{"fieldset":"note","null":True,"overwrite":True}]#step2 + ], + [#map2:取消abstract域 + [{"fieldsource":"abstract","final":True}],#step1 + [{"fieldset":"abstract","null":True,"overwrite":True}]#step2 + ], + [#map3:取消keywords域 + [{"fieldsource":"keywords","final":True}],#step1 + [{"fieldset":"keywords","null":True,"overwrite":True}]#step2 + ], + [#map4:取消keywords-plus域 + [{"fieldsource":"keywords-plus","final":True}],#step1 + [{"fieldset":"keywords-plus","null":True,"overwrite":True}]#step2 + ], + [#map5:取消affiliation域 + [{"fieldsource":"affiliation","final":True}],#step1 + [{"fieldset":"affiliation","null":True,"overwrite":True}]#step2 + ], + [#map6:取消funding-acknowledgement域 + [{"fieldsource":"funding-acknowledgement","final":True}],#step1 + [{"fieldset":"funding-acknowledgement","null":True,"overwrite":True}]#step2 + ], + [#map7:取消funding-text域 + [{"fieldsource":"funding-text","final":True}],#step1 + [{"fieldset":"funding-text","null":True,"overwrite":True}]#step2 + ], + ] + +#重设不处理 +sourcemaps=[] + + +##------------------------------------------ +## 参考文献表的制定格式设置,比如GB/T 7714-2015 +## + +#全局选项 +formatoptions={ +"style":'authoryear',#写bbl信息的设置选项,authoryear,'numeric' +"nameformat":'uppercase',#姓名处理选项:uppercase,lowercase,given-family,family-given,pinyin +"giveninits":'space',#使用名的缩写,space表示名见用空格分隔,dotspace用点加空格,dot用点,terse无分隔,false不使用缩写 +"maxbibnames":3,# +"minbibnames":3,# +"morenames":True,# +"maxbibitems":1,# +"minbibitems":1,# +"moreitems":False,# +"date":'year',#'日期处理选项':year,iso,等 +"urldate":'iso',#'日期处理选项':year,iso,等 +} + +#本地化字符串 +localstrings={ +'andothers':{'english':'et al.','chinese':'等'}, +'and':{'english':' and ','chinese':'和'}, +'edition':{'english':'th ed','chinese':'版'},#th ed. 中的点不要,为方便标点处理 +'in':{'english':'in: ','chinese':'见: '}, +'nolocation':{'english':'[S.l.]','chinese':'[出版地不详]'}, +'nopublisher':{'english':'[s.n.]','chinese':'[出版者不详]'}, +'bytranslator':{'english':'trans by','chinese':'译'}, +} + +#标点 +localpuncts={ +'multinamedelim':', ', +'finalnamedelim':', ', +'andothorsdelim':', ', +'finalitemdelim':', ', +'multiitemdelim':', ', +} + +#替换字符串 +replacestrings={ +'[出版地不详]: [出版者不详]':'[出版地不详 : 出版者不详]', +'[S.l.]: [s.n.]':'[S.l. : s.n.]', +'..':'.', +} + +#类型和载体字符串 +typestrings={ +'book':'[M]', +'inbook':'[M]', +'standard':'[S]', +'periodical':'[J]', +'article':'[J]', +'newspaper':'[N]', +'patent':'[P]', +'online':'[EB]', +'www':'[EB]', +'electronic':'[EB]', +'proceedings':'[C]', +'inproceedings':'[C]', +'conference':'[C]', +'collection':'[G]', +'incollection':'[G]', +'thesis':'[D]', +'mastersthsis':'[D]', +'phdthesis':'[D]', +'report':'[R]', +'techreport':'[R]', +'manual':'[A]', +'archive/manual':'[A]', +'database':'[DB]', +'dataset':'[DS]', +'software':'[CP]', +'map':'[CM]', +'unpublished':'[Z]', +'misc':'[Z]', +} + +#数据类型 +datatypeinfo={ +'namelist':['author','editor','translator','bookauthor'], +'literallist':['location','address','publisher','institution','organization','school','language','keywords'], +'literalfield':['title','journaltitle','journal','booktitle','subtitle','titleaddon','edition','version','url', + 'volume','number','endvolume','endnumber','type','note','labelnumber'], +'datefield':['date','year','urldate','enddate','origdate','eventdate'], +'rangefield':['pages'] +} + +#条目的著录格式 +bibliographystyle={ +"book":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['translator'],'options':{'nameformat':'uppercase'},'prepunct':". ",'posstring':r', \bibstring{bytranslator}'}, +{"fieldsource":['edition'],'numerformat':'arabic','prepunct':". ","posstringifnumber":r'\bibstring{edition}'}, +{"fieldsource":['location','address'],'prepunct':". ",'replstring':r"\bibstring{nolocation}"}, +{"fieldsource":['publisher'],'prepunct':": ",'replstring':r"\bibstring{nopublisher}",'prepunctifnolastfield':'. '}, +{"fieldsource":['date','year'],'prepunct':", "}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". ",'prestring':r'\url{','posstring':'}'}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"article":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['journaltitle','journal'],'prepunct':". "}, +{"fieldsource":['year','date'],'prepunct':", "}, +{"fieldsource":['volume'],'prepunct':", "}, +{"fieldsource":['number'],'prestring':"(",'posstring':")"}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"newspaper":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['journaltitle','journal'],'prepunct':". "}, +{"fieldsource":['date','year'],'prepunct':", ",'options':{'date':'iso'}}, +{"fieldsource":['number'],'prestring':"(",'posstring':")"}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"inbook":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['in'],'replstring':"//",'omitifnofield':['bookauthor','editor','booktitle']}, +{"fieldsource":['bookauthor','editor'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['booktitle'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':''}, +{"fieldsource":['edition'],'numerformat':'arabic','prepunct':". ","posstring":r'\bibstring{edition}'}, +{"fieldsource":['location','address'],'prepunct':". ",'replstring':r"\bibstring{nolocation}"}, +{"fieldsource":['publisher'],'prepunct':": ",'replstring':r"\bibstring{nopublisher}",'prepunctifnolastfield':'. '}, +{"fieldsource":['date','year'],'prepunct':", "}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"inproceedings":"inbook", +"incollection":"inbook", +"standard":"inbook", +"proceedings":"book", +"collection":"book", +"patent":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['number'],'prepunct':": "}, +{"fieldsource":['date','year'],'prepunct':", "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"online":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['organization','instiution'],'prepunct':". "}, +{"fieldsource":['date','year'],'prepunct':", ",'prepunctifnolastfield':'. ','omitifnofield':['enddate','eventdate']}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['date','enddate','eventdate'],'prepunct':". ",'options':{"date":"iso",'eventdate':'iso'},'prestring':"(","posstring":")"}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]",'prepunctifnolastfield':'. '}, +{"fieldsource":['url'],'prepunct':". ",'prepunctifnolastfield':''}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"www":"online", +"electronic":"online", +"report":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['translator'],'options':{'nameformat':'uppercase'},'prepunct':". "}, +{"fieldsource":['type'],'prepunct':". "}, +{"fieldsource":['number'],'prepunct':"",'prepunctifnolastfield':'. '}, +{"fieldsource":['version'],'prepunct':". "}, +{"fieldsource":['location','address'],'prepunct':". ",'replstring':r"\bibstring{nolocation}"}, +{"fieldsource":['institution','publisher'],'prepunct':": ",'replstring':r"\bibstring{nopublisher}",'prepunctifnolastfield':'. '}, +{"fieldsource":['date','year'],'prepunct':", ",'omitifnofield':['location','address','institution','publisher'],'omitiffield':['url']}, +{"fieldsource":['date','year'],'prepunct':". ",'prestring':'(','posstring':')','omitiffield':['location','address','institution','publisher']}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"techreport":"report", +"periodical":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['editor','author'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['year','date'],'prepunct':", "}, +{"fieldsource":['volume'],'prepunct':", "}, +{"fieldsource":['number'],'prestring':"(",'posstring':")-"}, +{"fieldsource":['endyear','enddate'],'prepunct':", "}, +{"fieldsource":['endvolume'],'prepunct':", "}, +{"fieldsource":['endnumber'],'prestring':"(",'posstring':")"}, +{"fieldsource":['location','address'],'prepunct':". ",'replstring':r"\bibstring{nolocation}"}, +{"fieldsource":['institution','publisher'],'prepunct':": ",'replstring':r"\bibstring{nopublisher}",'prepunctifnolastfield':'. '}, +{"fieldsource":['year','date'],'prepunct':", ",'posstring':'-'}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +#omitifnofield:必须所有的域都不存在才为true +#omitiffield:只要存在一个域就为true +"thesis":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['translator'],'options':{'nameformat':'uppercase'},'prepunct':". "}, +{"fieldsource":['location','address'],'prepunct':". "}, +{"fieldsource":['institution','publisher','school'],'prepunct':": ",'prepunctifnolastfield':'. '}, +{"fieldsource":['date','year'],'prepunct':", ",'omitifnofield':['location','address','institution','publisher'],'omitiffield':['url']}, +{"fieldsource":['date','year'],'prepunct':". ",'prestring':'(','posstring':')','omitiffield':['location','address','institution','publisher']}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". ",'prestring':r'\url{','posstring':'}'}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"manual":"thesis", +"unpublished":"thesis", +"database":"thesis", +"dataset":"thesis", +"software":"thesis", +"map":"thesis", +"archive":"thesis", +"misc":[ +#{"fieldsource":["labelnumber"],'prestring':"[","posstring":"]","pospunct":" "}, +{"fieldsource":['author','editor','translator'],'options':{'nameformat':'uppercase'}}, +{"fieldsource":['title'],'caseformat':'sentencecase','prepunct':". ",'prepunctifnolastfield':'','posstring':r"\typestring"}, +{"fieldsource":['howpublished'],'prepunct':". "}, +{"fieldsource":['location','address'],'prepunct':". "}, +{"fieldsource":['institution','publisher'],'prepunct':": ",'prepunctifnolastfield':'. '}, +{"fieldsource":['date','year'],'prepunct':", "}, +{"fieldsource":['pages'],'prepunct':": "}, +{"fieldsource":['urldate'],'prestring':"[","posstring":"]"}, +{"fieldsource":['url'],'prepunct':". "}, +{"fieldsource":['doi'],'prepunct':". "}, +{"fieldsource":['endpunct'],'replstring':"."} +], +"phdthesis":"thesis", +"mastersthesis":"thesis", +} + + +# +# +#打印格式化后的全部文献条目文本 +def printbibliography(): + + bibliographyentries=bibliographytext.split('\n') + + #md文件输出,直接用write写 + mdoutfile="newformatted"+inputbibfile.replace('.bib','.md') + fout = open(mdoutfile, 'w', encoding="utf8") + print("INFO: writing cited references to '" + mdoutfile + "'") + + biblabelnumber=0 + for prtbibentry in bibliographyentries: + if len(prtbibentry)>0: + biblabelnumber=biblabelnumber+1 + fout.write('['+str(biblabelnumber)+'] '+prtbibentry+'\n') + fout.close() + + #html文件输出,直接用write写 + mdoutfile="newformatted"+inputbibfile.replace('.bib','.html') + fout = open(mdoutfile, 'w', encoding="utf8") + print("INFO: writing cited references to '" + mdoutfile + "'") + fout.write('<html><head><title>references</title></head>') + fout.write('<body bgcolor="lightgray"><div align="top"><center>') + fout.write('<font color="blue">') + fout.write('<table border="0" cellPadding="10" cellSpacing="5" height="400" width="70%">') + fout.write('<tr><td height="1" width="566" align="center" colspan="1" bgcolor="teal"></td></tr>') + + biblabelnumber=0 + for prtbibentry in bibliographyentries: + if len(prtbibentry)>0: + biblabelnumber=biblabelnumber+1 + fout.write('<tr> <td width="480" height="15" colspan="6"><font color="blue">') + fout.write('<span style="font-family: 宋体; font-size: 14">') + fout.write('['+str(biblabelnumber)+'] '+prtbibentry) + fout.write('</span></font></td> </tr>') + + fout.write('<tr><td height="1" width="566" align="center" colspan="1" bgcolor="teal"></td></tr>') + fout.write('</table></div></body></html>') + fout.close() + + if auxfile: + bblfile=auxfile.replace('.aux','.bbl') + else: + bblfile=inputbibfile.replace('.bib','.bbl') + bbloutfile=bblfile + fout = open(bbloutfile, 'w', encoding="utf8") + print("INFO: writing cited references to '" + bbloutfile + "'") + + fout.write(r'\begin{thebibliography}{'+str(len(bibentries))+'}\n') + + biblabelnumber=0 + for prtbibentry in bibliographyentries: + if len(prtbibentry)>0: + biblabelnumber=biblabelnumber+1 + + entrysn=0 + for bibentry in bibentries: + entrysn=entrysn+1 + if entrysn==biblabelnumber: + entrykeystr=bibentry['entrykey'] + entryciteauthor=formatlabelauthor(bibentry) + entryciteyear=formatlabelyear(bibentry) + entrycitelabel=entryciteauthor[0]+'('+entryciteyear+')'+entryciteauthor[1] + #Baker et~al.(1995)Baker and Jackson + break + if formatoptions['style']=='authoryear': + fout.write(r'\bibitem['+entrycitelabel+']{'+entrykeystr+'}'+prtbibentry+'\n') + else: + fout.write(r'\bibitem['+str(biblabelnumber)+']{'+entrykeystr+'}'+prtbibentry+'\n') + + fout.write(r'\end{thebibliography}') + fout.close() + + + +# +#authoryear样式提供标注标签的作者信息 +# +def formatlabelauthor(bibentry): + + if 'author' in bibentry: + namelist=bibentry['author'] + elif 'editor' in bibentry: + namelist=bibentry['editor'] + elif 'translator' in bibentry: + namelist=bibentry['translator'] + else: + namelist='Anon' + + return [namelist,namelist] + +# +#authoryear样式提供标注标签的年份信息 +# +def formatlabelyear(bibentry): + + if 'year' in bibentry: + yearlist=bibentry['year'] + elif 'eventyear' in bibentry: + yearlist=bibentry['eventyear'] + elif 'origyear' in bibentry: + yearlist=bibentry['origyear'] + elif 'urlyear' in bibentry: + yearlist=bibentry['urlyear'] + else: + yearlist='N.D.' + + return yearlist + +# +# +#格式化全部文献条目文本 +def formatallbibliography(): + labelnumber=0 + global bibliographytext + bibliographytext='' + for bibentry in bibentries: + labelnumber=labelnumber+1 + bibentry['labelnumber']=labelnumber + bibentrytext='' + bibentrytext=formatbibentry(bibentry) + bibliographytext=bibliographytext+bibentrytext+'\n' + + print('\nreferecences') + print(bibliographytext) + +# +# +#格式化一个文献条目文本 +def formatbibentry(bibentry): + + print('--------------new entry---------') + print('\nbibentry:',bibentry) + #bibentrytext='entry:' + + # + # 由于volume和number域可能存在范围的特殊情况,首先做特殊处理 + # + if 'volume' in bibentry: + if '-' in bibentry['volume']: + multivolume=bibentry['volume'].split("-") + bibentry['volume']=multivolume[0] + bibentry['endvolume']=multivolume[1] + if 'number' in bibentry: + if '-' in bibentry['number']: + multinumber=bibentry['number'].split("-") + bibentry['number']=multinumber[0] + bibentry['endnumber']=multinumber[1] + + #四种日期域也做范围解析 + if 'date' in bibentry: + if '/' in bibentry['date']: + datestring=bibentry['date'].split('/') + bibentry['date']=datestring[0] + bibentry['enddate']=datestring[1] + + if 'urldate' in bibentry: + if '/' in bibentry['urldate']: + datestring=bibentry['urldate'].split('/') + bibentry['urldate']=datestring[0] + bibentry['endurldate']=datestring[1] + + if 'eventdate' in bibentry: + if '/' in bibentry['eventdate']: + datestring=bibentry['eventdate'].split('/') + bibentry['eventdate']=datestring[0] + bibentry['endeventdate']=datestring[1] + + if 'origdate' in bibentry: + if '/' in bibentry['origdate']: + datestring=bibentry['origdate'].split('/') + bibentry['origdate']=datestring[0] + bibentry['endorigdate']=datestring[1] + + # + #接着处理所有域到一个条目文本 + # + bibentrytext='' + + if bibentry['entrytype'] in bibliographystyle: + print('INFO: format style of entrytype',bibentry['entrytype'],'is defined.') + if isinstance(bibliographystyle[bibentry['entrytype']],str): + formattype=bibliographystyle[bibentry['entrytype']] + else: + formattype=bibentry['entrytype'] + + lastfield=True #前一域存在 + + for fieldinfo in bibliographystyle[formattype]: + + rtnfield=formatfield(bibentry,fieldinfo,lastfield) + fieldtext=rtnfield[0] + lastfield=rtnfield[1] + + bibentrytext=bibentrytext+fieldtext + + #对替换字符串做处理 + #包括对重复的标点做处理比如:..变为. + for k,v in replacestrings.items(): + print(k,v) + #m=re.search(k,bibentrytext) + #print(m) + #bibentrytext=re.sub(k,v,bibentrytext) + #利用正则反而不行,直接用字符串替换 + bibentrytext=bibentrytext.replace(k,v) + + print(bibentrytext) + return bibentrytext + + + +# +# +#格式化文献条目的域 +#不同类型的域不同处理 +#分5类:姓名列表,文本列表,文本域,日期域,范围域 +#其中姓名列表,文本列表,日期域,日期域,范围域,都需要进行特殊的解析 +#而volume,number如果需要特殊解析则在文件域的格式处理时增加新的处理逻辑。 +def formatfield(bibentry,fieldinfo,lastfield): + + print('fieldinfo:',fieldinfo) + #首先把域的内容先解析处理 + fieldcontents='' + + fieldsource=None + + #首先判断域是否忽略 + fieldomit=False + + if 'omitifnofield' in fieldinfo and 'omitiffield' in fieldinfo: + + fieldomita=True#假设忽略的条件满足 + for field in fieldinfo['omitifnofield']:#只要需要不存在的域有一个存在,那么条件就不满足 + if field in bibentry: + fieldomita=False + break + + fieldomitb=False#假设忽略的条件不满足 + for field in fieldinfo['omitiffield']:#只要需要存在的域中有一个存在,那么条件就满足 + if field not in bibentry: + fieldomitb=True + break + + fieldomit=fieldomita and fieldomitb + + elif 'omitifnofield' in fieldinfo: + + fieldomit=True#假设忽略的条件满足 + for field in fieldinfo['omitifnofield']:#只要需要不存在的域有一个存在,那么条件就不满足 + if field in bibentry: + fieldomit=False + break + + elif 'omitiffield' in fieldinfo: + + fieldomit=False#假设忽略的条件不满足 + for field in fieldinfo['omitiffield']:#只要需要存在的域中有一个存在,那么条件就满足 + if field not in bibentry: + fieldomit=True + break + + print(fieldomit) + + + #如果不忽略该域那么: + if not fieldomit: + + #当域为姓名列表域时: + if fieldinfo['fieldsource'][0] in datatypeinfo['namelist']: + #print('0',fieldinfo['fieldsource'][0]) + #print('author' in bibentry) + for field in fieldinfo['fieldsource']:# + #print(fieldinfo['fieldsource']) + #print('namelist:',field) + if field in bibentry:#当域存在域条目中时,确定要处理的域 + fieldsource=field + break + if fieldsource: + #传递条目给出的一些控制选项 + if 'options' in fieldinfo: + options=fieldinfo['options'] + else: + options={} + fieldcontents=namelistparser(bibentry,fieldsource,options) + + + #当域为文本列表域时: + elif fieldinfo['fieldsource'][0] in datatypeinfo['literallist']: + + for field in fieldinfo['fieldsource']:# + if field in bibentry:#当域存在域条目中时,确定要处理的域 + fieldsource=field + break + if fieldsource: + fieldcontents=literallistparser(bibentry,fieldsource) + + #当域为文本域时: + elif fieldinfo['fieldsource'][0] in datatypeinfo['literalfield']: + + for field in fieldinfo['fieldsource']:# + if field in bibentry:#当域存在域条目中时,确定要处理的域 + fieldsource=field + break + if fieldsource: + fieldcontents=literalfieldparser(bibentry,fieldsource) + + + #当域为日期域时: + elif fieldinfo['fieldsource'][0] in datatypeinfo['datefield']: + + for field in fieldinfo['fieldsource']:# + if field in bibentry:#当域存在域条目中时,确定要处理的域 + fieldsource=field + break + if fieldsource: + #传递条目给出的一些控制选项 + if 'options' in fieldinfo: + options=fieldinfo['options'] + else: + options={} + fieldcontents=datefieldparser(bibentry,fieldsource,options) + + + #当域为范围域时: + elif fieldinfo['fieldsource'][0] in datatypeinfo['rangefield']: + + for field in fieldinfo['fieldsource']:# + if field in bibentry:#当域存在域条目中时,确定要处理的域 + fieldsource=field + break + if fieldsource: + fieldcontents=rangefieldparser(bibentry,fieldsource) + + if not fieldsource: + if 'replstring' in fieldinfo and fieldinfo['replstring']: + print('replstring') + fieldsource=True + fieldcontents=fieldinfo['replstring'] + + + #接着做进一步的格式化,包括标点,格式,字体等 + fieldtext='' + + print(fieldsource) + if fieldsource: + if lastfield:#当前一个著录项存在,则正常输出 + if 'prepunct' in fieldinfo: + fieldtext=fieldtext+fieldinfo['prepunct'] + else:#当前一个著录项不存在,则首先输出'prepunctifnolastfield' + if 'prepunctifnolastfield' in fieldinfo: + fieldtext=fieldtext+fieldinfo['prepunctifnolastfield'] + elif 'prepunct' in fieldinfo: + fieldtext=fieldtext+fieldinfo['prepunct'] + + if 'prestring' in fieldinfo: + fieldtext=fieldtext+fieldinfo['prestring'] + + if 'fieldformat' in fieldinfo: + fieldtext=fieldtext+'{'+fieldinfo['fieldformat']+'{'+fieldcontents+'}}' + else: + fieldtext=fieldtext+str(fieldcontents) + + if 'posstring' in fieldinfo: + fieldtext=fieldtext+fieldinfo['posstring'] + + if 'posstringifnumber' in fieldinfo: + try: + numtemp=int(fieldcontents) + if isinstance(numtemp,int): + fieldtext=fieldtext+fieldinfo['posstringifnumber'] + except: + print('info:waring the field value can not convert to integer') + + if 'pospunct' in fieldinfo: + fieldtext=fieldtext+fieldinfo['pospunct'] + + #更新lastfiled + lastfield=True + else: + lastfield=False + + + #自定义标点的处理 + print('fieldtext:',fieldtext) + while r'\printdelim' in fieldtext: + + m = re.search(r'\\printdelim{([^\}]*)}',fieldtext)#注意贪婪算法的影响,所以要排除\}字符 + print('m.group(1):',m.group(1)) + fieldtext=re.sub(r'\\printdelim{[^\}]*}',localpuncts[m.group(1)],fieldtext,count=1) + print('fieldtext:',fieldtext) + + + #本地化字符串的处理 + print('fieldtext:',fieldtext) + while r'\bibstring' in fieldtext: + + language=languagejudgement(bibentry,fieldinfo,fieldsource) + m = re.search(r'\\bibstring{([^\}]*)}',fieldtext)#注意\字符的匹配,即便是在r''中也需要用\\表示 + fieldtext=re.sub(r'\\bibstring{[^\}]*}',localstrings[m.group(1)][language],fieldtext,count=1) + print('fieldtext:',fieldtext) + #下面这句不行因为,在字典取值是,不支持\1这样的正则表达式 + #fieldtext=re.sub(r'\\bibstring{(.*)}',localstrings[r'\1'][language],fieldtext,count=1) + + #标题的类型和载体标识符的处理 + if r'\typestring' in fieldtext:#当需要处理类型和载体时 + if bibentry['entrytype'] in typestrings:#当条目对应的类型存在时 + print(r'\typestring in',fieldtext) + typestring=typestrings[bibentry['entrytype']] + if 'url' in bibentry: + typestring=typestring.replace(']','/OL]') + elif 'medium' in bibentry: + rplctypestring=bibentry['medium']+']' + typestring=typestring.replace(']',rplctypestring) + else:#当条目对应的类型不存在时,当做其它类型处理 + typestring='[Z]' + + print(typestring) + fieldtext=fieldtext.replace(r'\typestring',typestring) + + return [fieldtext,lastfield] + + + + + +# +#根据作者域或者标题域确定条目的语言 +# +def languagejudgement(bibentry,fieldinfo,fieldsource): + + if fieldsource in datatypeinfo['namelist']:#当域是作者类时,利用作者域本身信息做判断 + + language=fieldlanguage(bibentry[fieldsource]) + + else:#其它情况,利用title域做判断 + if 'title' in bibentry: + language=fieldlanguage(bibentry['title']) + elif 'author' in bibentry: + language=fieldlanguage(bibentry['author']) + else: + language='english' + + return language + + +# +#根据域值所在的字符范围确定域的语言 +# +def fieldlanguage(fieldvalueinfo): + + if re.match(r'[\u2FF0-\u9FA5]', fieldvalueinfo): + language='chinese' + elif re.match(r'[\u3040-\u30FF\u31F0}-\u31FF]', fieldvalueinfo): + language='japanese' + elif re.match(r'[\u1100-\u11FF\u3130-\u318F\uAC00-\uD7AF]', fieldvalueinfo): + language='korean' + elif re.match(r'[\u0400-\u052F]', fieldvalueinfo): + language='russian' + elif re.match(r'[\u0100-\u017F]', fieldvalueinfo): + language='french' + else: + language='english' + + return language + + +# +# +#对存在{}做保护的字符串进行分割 +def safetysplit(strtosplt,seps): + + #首先查找{}保护的所有字符串 + s1=re.findall('\{.*?\}',strtosplt) + + #接着确定保护字符串中是否存在分割用字符串 + sepinbrace=False + for s1a in s1: + for sep in seps: + if sep in s1a: + sepinbrace=True + break + if sepinbrace: + break + #print(sepinbrace) + + #若保护字符串中存在分割字符串那么做特殊处理 + a=strtosplt + if sepinbrace: + + #保护字符串用特殊字符串代替,特殊字符串与分割字符串没有任何关联 + strsn=0 + for stra1 in s1: + strsn=strsn+1 + a=a.replace(stra1,'$'+str(strsn)+'$') + #print(a) + + #处理原字符串为只需要一个分隔字符串就能分隔 + if len(seps)>1: + for i in range(1,len(seps)): + a=a.replace(seps[i],seps[0]) + #print(a) + + #接着做分割 + names=a.split(seps[0]) + #print(names) + + #对分割后的字符串做还原,即把特殊字符串还原回保护字符串 + namesnew=[] + for name in names: + strsn=0 + for stra1 in s1: + strsn=strsn+1 + name=name.replace('$'+str(strsn)+'$',stra1) + #print(name) + namesnew.append(name.strip().lstrip()) + + else: + #处理原字符串为只需要一个分隔字符串就能分隔 + if len(seps)>1: + for i in range(1,len(seps)): + a=a.replace(seps[i],seps[0]) + #print(a) + + #直接分割 + names=a.split(seps[0]) + namesnew=[] + for name in names: + namesnew.append(name.strip().lstrip()) + + #print(namesnew) + return namesnew + +# +# +#姓名列表解析 +#增加条目给出的选项 +def namelistparser(bibentry,fieldsource,options): + fieldcontents=bibentry[fieldsource] + + #首先做针对{}保护的处理 + #{}有可能保护一部分,有可能保护全部 + #首先判断{}是否存在,若存在,那么可以确定需要做保护处理,否则用常规处理 + #当然这些事情可以在一个函数中处理 + + #首先姓名列表进行分解,包括用' and '和' AND '做分解 + #利用safetysplit函数实现安全的分解 + seps=[' and ',' AND '] + fieldcontents=fieldcontents.lstrip().strip() + fieldauthors=safetysplit(fieldcontents,seps) + + print('fieldauthors:',fieldauthors) + #接着从各个姓名得到更详细的分解信息 + fieldnames=[] + for name in fieldauthors: + if name.lower() == 'others': + nameinfo={'morename':True} + else: + if fieldlanguage(name)=='chinese':#当中文姓名中存在逗号先去除 + if ', ' in name: + name=name.replace(', ','') + else: + pass + nameinfo=singlenameparser(name) + fieldnames.append(nameinfo) + + #最后根据全局和局部选项进行格式化 + nameformattedstr='' + + #根据'maxbibnames'和'minbibnames'截短 + if 'maxbibnames' in options:#首先使用条目中的选项 + if len(fieldnames)>options['maxbibnames']: + fieldnamestrunc=fieldnames[:options['minbibnames']] + nameinfo={'morename':True} + fieldnamestrunc.append(nameinfo) + else: + fieldnamestrunc=fieldnames + elif 'maxbibnames' in formatoptions:#接着使用全局选项 + if len(fieldnames)>formatoptions['maxbibnames']: + fieldnamestrunc=fieldnames[:formatoptions['minbibnames']] + nameinfo={'morename':True} + fieldnamestrunc.append(nameinfo) + else: + fieldnamestrunc=fieldnames + else: + fieldnamestrunc=fieldnames + + #当条目选择中存在'nameformat' + if 'nameformat' in options: + option={'nameformat':options['nameformat']} + else: + option={} + + print('fieldnamestrunc:',fieldnamestrunc) + nameliststop=len(fieldnamestrunc) + nameliststart=1 + namelistcount=0 + for nameinfo in fieldnamestrunc: + namelistcount=namelistcount+1 + if 'morename' in nameinfo: + if formatoptions['morenames']:#只有设置morenames为true是才输出other的相关信息 + nameformattedstr=nameformattedstr+r'\printdelim{andothorsdelim}\bibstring{andothers}' + else: + if namelistcount==nameliststop and namelistcount>1:#当没有others时最后一个姓名前加的标点 + nameformattedstr=nameformattedstr+r'\printdelim{finalnamedelim}'+singlenameformat(nameinfo,option) + elif namelistcount==nameliststart: + nameformattedstr=singlenameformat(nameinfo,option) + else: + nameformattedstr=nameformattedstr+r'\printdelim{multinamedelim}'+singlenameformat(nameinfo,option) + + return nameformattedstr + + +# +# +#单个姓名格式化 +def singlenameformat(nameinfo,option): + + singlenamefmtstr='' + + + if 'nameformat' in option:#首先使用条目给出的选项 + nameformat=option['nameformat'] + elif 'nameformat' in formatoptions:#接着使用全局的选项 + nameformat=formatoptions['nameformat'] + else:#最后使用默认的选项 + nameformat='uppercase' + + + #根据单个姓名格式化选项来实现具体的格式 + if nameformat=='uppercase': + + if nameinfo['family'].startswith('{'): + singlenamefmtstr=nameinfo['family'] + else: + singlenamefmtstr=nameinfo['family'].upper() + + #根据选项确定使用名的缩写 + if formatoptions["giveninits"]=='space':#space表示名见用空格分隔, + if 'given' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['giveni'].upper() + if 'middle' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['middlei'].upper() + elif formatoptions["giveninits"]=='dotspace':#dotspace用点加空格, + if 'given' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['giveni'].upper() + if 'middle' in nameinfo: + singlenamefmtstr=singlenamefmtstr+'. '+nameinfo['middlei'].upper()+'.' + elif formatoptions["giveninits"]=='dot':#dot用点, + if 'given' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['giveni'].upper() + if 'middle' in nameinfo: + singlenamefmtstr=singlenamefmtstr+'.'+nameinfo['middlei'].upper()+'.' + elif formatoptions["giveninits"]=='terse':#terse无分隔, + if 'given' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['giveni'].upper() + if 'middle' in nameinfo: + singlenamefmtstr=singlenamefmtstr+nameinfo['middlei'].upper() + elif formatoptions["giveninits"]=='false':#false不使用缩写 + if 'given' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['given'].upper() + if 'middle' in nameinfo: + singlenamefmtstr=singlenamefmtstr+' '+nameinfo['middle'].upper() + + + elif nameformat=='lowercase': + pass + elif nameformat=='given-family': + pass + elif nameformat=='family-given': + pass + elif nameformat=='pinyin': + pass + else: + pass + + return singlenamefmtstr + + +# +# +#单个姓名解析 +def singlenameparser(name): + + singlename=name + + print('name:',name) + + #字典用于存储所有的姓名成分信息 + namepartsinfo={} + + nameparts=safetysplit(singlename,[',']) + + if len(nameparts)==3:#两个逗号的情况,表示存在family和suffix + + prefixfamily=safetysplit(nameparts[0].lstrip().strip(),[' ']) + if len(prefixfamily)>1: + namepartsinfo['prefix']=prefixfamily[0].lstrip().strip() + namepartsinfo['family']=prefixfamily[1].lstrip().strip() + else: + namepartsinfo['family']=prefixfamily[0].lstrip().strip() + + namepartsinfo['suffix']=nameparts[1].lstrip().strip() + + + givenmiddle=safetysplit(nameparts[2].lstrip().strip(),[' ']) + if len(givenmiddle)>1: + namepartsinfo['given']=givenmiddle[0].lstrip().strip() + namepartsinfo['middle']=givenmiddle[1].lstrip().strip() + else: + namepartsinfo['given']=givenmiddle[0].lstrip().strip() + + elif len(nameparts)==2: + + prefixfamily=safetysplit(nameparts[0].lstrip().strip(),[' ']) + if len(prefixfamily)>1: + namepartsinfo['prefix']=prefixfamily[0].lstrip().strip() + namepartsinfo['family']=prefixfamily[1].lstrip().strip() + else: + namepartsinfo['family']=prefixfamily[0].lstrip().strip() + + + givenmiddle=safetysplit(nameparts[1].lstrip().strip(),[' ']) + if len(givenmiddle)>1: + namepartsinfo['given']=givenmiddle[0].lstrip().strip() + namepartsinfo['middle']=givenmiddle[1].lstrip().strip() + else: + namepartsinfo['given']=givenmiddle[0].lstrip().strip() + + else: + givenmiddlefamily=safetysplit(nameparts[0].lstrip().strip(),[' ']) + if len(givenmiddlefamily)==3: + namepartsinfo['given']=givenmiddlefamily[0].lstrip().strip() + namepartsinfo['middle']=givenmiddlefamily[1].lstrip().strip() + namepartsinfo['family']=givenmiddlefamily[2].lstrip().strip() + elif len(givenmiddlefamily)==2: + namepartsinfo['given']=givenmiddlefamily[0].lstrip().strip() + namepartsinfo['family']=givenmiddlefamily[1].lstrip().strip() + elif len(givenmiddlefamily)==1: + namepartsinfo['family']=givenmiddlefamily[0].lstrip().strip() + + + print('nameparts:',namepartsinfo) + + if 'family' in namepartsinfo: + if namepartsinfo['family'].startswith('{'): + namepartsinfo['familyi']=namepartsinfo['family'] + else: + namepartsinfo['familyi']=namepartsinfo['family'][0].upper() + + if 'given' in namepartsinfo: + #print(namepartsinfo['given']) + if namepartsinfo['given'].startswith('{'): + namepartsinfo['giveni']=namepartsinfo['given'] + else: + namepartsinfo['giveni']=namepartsinfo['given'][0].upper() + + if 'middle' in namepartsinfo: + if namepartsinfo['middle'].startswith('{'): + namepartsinfo['middle']=namepartsinfo['middle'] + else: + namepartsinfo['middlei']=namepartsinfo['middle'][0].upper() + + return namepartsinfo + +# +# +#文本列表解析 +def literallistparser(bibentry,fieldsource): + fieldcontents=bibentry[fieldsource] + + + #首先从文本列表分解出各个项,包括用' and '和' AND '做分解 + #利用safetysplit函数实现安全的分解 + seps=[' and ',' AND '] + fieldcontents=fieldcontents.lstrip().strip() + fielditems=safetysplit(fieldcontents,seps) + + print('fielditems:',fielditems) + + #根据'maxbibitems'和'minbibitems'截短 + fielditemstrunc=[] + + if len(fielditems)>formatoptions['maxbibitems']: + fielditemstrunc=fielditems[:formatoptions['minbibitems']] + fielditemstrunc.append('others') + else: + fielditemstrunc=fielditems + + #重设一下others的大小写,因为可能输入的时大写的 + if fielditems[-1].lower() == 'others': + fielditems[-1]='others' + + #最后根据全局和局部选项进行格式化 + itemliststop=len(fielditemstrunc) + itemliststart=1 + itemlistcount=0 + itemformattedstr='' + for iteminfo in fielditemstrunc: + itemlistcount=itemlistcount+1 + if iteminfo == 'others': + if formatoptions['moreitems']:#只有设置moreitems为true是才输出other的相关信息 + itemformattedstr=itemformattedstr+r'\printdelim{andothorsdelim}\bibstring{andothers}' + else: + if itemlistcount==itemliststop and itemlistcount>1:#当没有others时最后一个项前加标点 + itemformattedstr=itemformattedstr+r'\printdelim{finalitemdelim}'+iteminfo + elif itemlistcount==itemliststart: + itemformattedstr=iteminfo + else: + itemformattedstr=itemformattedstr+r'\printdelim{multiitemdelim}'+iteminfo + + return itemformattedstr + +# +# +#文本域解析 +def literalfieldparser(bibentry,fieldsource): + fieldcontents=bibentry[fieldsource] + + return fieldcontents + +# +# +#日期域解析 +#条目设置的选项options: +def datefieldparser(bibentry,fieldsource,options): + fieldcontents=bibentry[fieldsource] + + #首先从日期域,解析日期类型: + dateparts={} + if fieldsource=='year': + datestring=bibentry[fieldsource] + datetype='' + else: + datetype=fieldsource.replace('date','') + datestring=bibentry[fieldsource] + + + #日期的年月日解析 + #日期一般很少用{}进行保护,当保护的时候通常是整个进行包括,所以通常{}会出现在域的起始和末尾 + #所以当出现{字符时通常不用再做解析 + if '{' in datestring: + datepartinfo=[datestring] + else: + datepartinfo=datestring.split('-') + + if len(datepartinfo)==3: + dateparts[datetype+'year']=datepartinfo[0].strip().lstrip() + dateparts[datetype+'month']=datepartinfo[1].strip().lstrip() + dateparts[datetype+'day']=datepartinfo[2].strip().lstrip() + elif len(datepartinfo)==2: + dateparts[datetype+'year']=datepartinfo[0].strip().lstrip() + dateparts[datetype+'month']=datepartinfo[1].strip().lstrip() + else: + dateparts[datetype+'year']=datepartinfo[0].strip().lstrip() + + print(dateparts) + + #判断解析的年月日是不是整数,若不是则表示日期不可解析 + datecanbeparse=True + for k,v in dateparts.items(): + try: + datepartisint=isinstance(int(v),int) + except: + print('INFO: WARNING'+fieldsource+'can not be parsed') + datecanbeparse=False + break + + + #然后根据全局选项进行格式化: + #如果解析的年月日不是整数,那么对于date域则忽略,对于year域则直接输出 + if datecanbeparse: + if datetype+'date' in options:#首先使用条目给出的选项 + fieldcontents=singledateformat(dateparts,datetype,options[datetype+'date']) + elif datetype+'date' in formatoptions:#接着使用全局给出的选项 + fieldcontents=singledateformat(dateparts,datetype,formatoptions[datetype+'date']) + else:#否则使用默认选项 + fieldcontents=singledateformat(dateparts,datetype,'default') + else: + if fieldsource=='year': + fieldcontents=bibentry[fieldsource] + else: + fieldcontents='' + + return fieldcontents + + +# +# +# 根据日期的设置选项格式化单个日期 +def singledateformat(dateparts,datetype,formatoption): + if formatoption=='year': + dateformatstr=dateparts[datetype+'year'] + elif formatoption=='iso': + dateformatstr=dateparts[datetype+'year'] + if len(dateparts[datetype+'month'])<2: + dateformatstr=dateformatstr+'-0'+dateparts[datetype+'month'] + else: + dateformatstr=dateformatstr+'-'+dateparts[datetype+'month'] + if len(dateparts[datetype+'day'])<2: + dateformatstr=dateformatstr+'-0'+dateparts[datetype+'day'] + else: + dateformatstr=dateformatstr+'-'+dateparts[datetype+'day'] + elif formatoption=='ymd': + dateformatstr=dateparts[datetype+'year'] + dateformatstr=dateformatstr+'-'+dateparts[datetype+'month'] + dateformatstr=dateformatstr+'-'+dateparts[datetype+'day'] + elif formatoption=='default': + dateformatstr=dateparts[datetype+'year'] + else: + pass + + return dateformatstr + + + + + +# +# +#范围域解析 +def rangefieldparser(bibentry,fieldsource): + fieldcontents=bibentry[fieldsource] + + return fieldcontents + + # # #打开bib文件 @@ -88,6 +1320,20 @@ def readfilecontents(bibFile): global bibfilecontents bibfilecontents=fIn.readlines() fIn.close() + + global usedIds + usedIds = set() + if auxfile: + fInAux = open(auxfile, 'r', encoding="utf8") + for line in fInAux: + if line.startswith("\\citation") or line.startswith("\\abx@aux@cite"): + ids = line.split("{")[1].rstrip("} \n").split(", ") + for id in ids: + if (id != ""): + usedIds.add(id) + fInAux.close() + print('references:',usedIds) + except IOError: print("ERROR: Input bib file '" + bibFile + "' doesn't exist or is not readable") @@ -98,83 +1344,330 @@ def readfilecontents(bibFile): def printfilecontents(): for line in bibfilecontents: print(line) - + + + # #输出修改后的bib文件 def writefilenewbib(bibFile): + + print(datetime.datetime.now().isoformat(timespec='seconds')) + + #json文件输出,用dump方法 + jsonoutfile="new"+bibFile.replace('.bib','.json') + print("INFO: writing all references to '" + jsonoutfile + "'") + fout = open(jsonoutfile, 'w', encoding="utf8") + json.dump(bibentries, fout) + fout.close() + + #json文件输出,直接用write写 + jsonoutfile="new"+bibFile.replace('.bib','cited.json') + fout = open(jsonoutfile, 'w', encoding="utf8") + print("INFO: writing cited references to '" + jsonoutfile + "'") + fout.write('[\n') + for bibentry in bibentries: + if bibentry["entrykey"] in usedIds or not usedIds: + fout.write(repr(bibentry)+',\n') + fout.write(']\n') + fout.close() + + #bib文件输出 biboutfile="new"+bibFile - print("INFO: writing references from '" + biboutfile + "'") + try: fout = open(biboutfile, 'w', encoding="utf8") fout.write("%% \n") - fout.write("%% bib file modified by bibmap.py\n") - print(datetime.datetime.now().isoformat(timespec='seconds')) + fout.write("%% bib file modified by biblatex-map.py\n") + fout.write("%% "+datetime.datetime.now().isoformat(timespec='seconds')+"\n") fout.write("%% \n\n\n") - for bibentry in bibentries: - fout.write('@'+bibentry["entrytype"]+'{'+bibentry["entrykey"]+',\n') - for k,v in bibentry.items(): - if k=="entrytype" or k=="entrykey" or v=='""': - pass + + for bibcomment in bibcomments: + for k,v in bibcomment.items(): + if k=="entrytype": + fout.write('@'+bibcomment["entrytype"]+'{') + else: + fout.write(str(v)) + fout.write('}\n\n') + + for bibstring in bibstrings: + for k,v in bibstring.items(): + if k=="entrytype": + fout.write('@'+bibstring["entrytype"]+'{') else: - fout.write('\t'+k+' = '+v+',\n') + fout.write(str(v)) fout.write('}\n\n') + writebibentrycounter=0 + if auxfile: + print("INFO: writing cited references in aux to '" + biboutfile + "'") + + for bibentry in bibentries: + if bibentry["entrykey"] in usedIds: + writebibentrycounter=writebibentrycounter+1 + fout.write('@'+bibentry["entrytype"]+'{'+bibentry["entrykey"]+',\n') + for k,v in bibentry.items(): + if k=="entrytype" or k=="entrykey" or v=='""' or v==None or k=='entrysn': + pass + else: + fout.write('\t'+str(k)+' = {'+str(v)+'},\n') + fout.write('}\n\n') + else: + print("INFO: writing all references to '" + biboutfile + "'") + for bibentry in bibentries: + writebibentrycounter=writebibentrycounter+1 + fout.write('@'+bibentry["entrytype"]+'{'+bibentry["entrykey"]+',\n') + for k,v in bibentry.items(): + if k=="entrytype" or k=="entrykey" or v=='""' or k=='entrysn' or v==None: + pass + else: + fout.write('\t'+k+' = {'+v+'},\n') + fout.write('}\n\n') + fout.close() + print("INFO: " + str(writebibentrycounter) + " references writed") except IOError: print("ERROR: Input bib file '" + bibFile + "' doesn't exist or is not readable") sys.exit(-1) + + + # #将条目解析放到bibentries列表中 #每个条目是一个dict字典 def bibentryparsing(): global bibentries - bibentries=[] - bibentry={} - entrysn=0 - for line in bibfilecontents: + global bibcomments + global bibstrings + bibentries=[]#用于记录所有条目 + bibentry={}#用于记录当前条目 + + bibcomments=[]#用于记录所有@comment条目 + bibcomment={}#用于记录当前@comment条目 + + bibstrings=[]#用于记录所有@stirng条目 + bibstring={}#用于记录当前@stirng条目 + + entrysn=0 #用于标记条目序号 + bibentrycounter=0##用于标记条目总数 + commentsn=0 #用于标记@comment条目序号 + bibcommentcounter=0#用于标记@comment条目总数 + stringsn=0 #用于标记@stirng条目序号 + bibstringcounter=0#用于标记@stirng条目总数 + + entrystated=False #用于标记条目开始 + fieldvalended=True #用于标记域的值当前行是否已经结束 + fieldvalue="" #用于记录当前域的值 + counterbracket=0 #用于追踪{}符号 + counterquotes=0 #用于追踪“”符号 + enclosebracket=True #用于记录是用{}还是用“”做为域的值的包围符号 + enclosenone=False #用于记录域的值无包围符号的情况 + + for line in bibfilecontents:#遍历所有行 #print(line) - if line.startswith("@"):#条目开始行 + + if line.startswith("@") and not "@comment" in line.lower() and not "@string" in line.lower():#判断条目开始行 entrysn=entrysn+1 + entrystated=True #新条目开始 + print('entrysn=',entrysn) entrynow=line.lstrip('@').split(sep='{', maxsplit=1) #print(entrynow) entrytype=entrynow[0] - bibentry['entrytype']=entrytype + bibentry['entrytype']=entrytype.lower()#条目类型小写,方便比较 entrykey=entrynow[1].split(sep=',', maxsplit=1)[0] bibentry['entrykey']=entrykey - else: - if '=' in line:#条目域信息行 - entryline=line.lstrip() - entrynow=entryline.split(sep='=', maxsplit=1) - #print(entrynow) - entryfield=entrynow[0].strip().lstrip() - #print(entrynow[1]) - entryfieldline=entrynow[1].split(sep=',', maxsplit=1) - entryfieldvalue=entryfieldline[0].lstrip() - if entryfieldvalue=='': - pass + bibentry['entrysn']=entrysn + elif entrystated: #只有新条目开始了才有意义 + + if fieldvalended: #当前行不是前面的未结束域的值 + if '=' in line and not line.lstrip().startswith("}"): + #排除以'}'开头的行后根据=号判断条目域信息行,不可能出现=号无法判断信息行的问题, + #因为是域值中存在=的特殊情况已经在未结束逻辑处理 + entryline=line.lstrip() + entrynow=entryline.split(sep='=', maxsplit=1) + #print(entrynow) + entryfield=entrynow[0].strip().lstrip().lower()#域名小写,方便比较 + entryfieldline=entrynow[1].lstrip() + + if entryfieldline.startswith("{"): + enclosebracket=True + elif entryfieldline.startswith('"'): + enclosebracket=False + else:#当没有符号包围是设置enclosenone以便特殊处理 + enclosenone=True + + fieldvalcontinued=True #临时标记,用于记录域值是否还未结束,先假设未结束 + for chari in entryfieldline.strip():#遍历域值中的每个字符 + fieldvalue=fieldvalue+chari + if chari =='{':#对{符号进行追踪 + counterbracket=counterbracket+1 + elif chari =='}':#对}符号进行追踪 + counterbracket=counterbracket-1 + if enclosebracket: + if counterbracket==0:#当}与域开始的{配对,那么说明域值已经结束 + bibentry[entryfield]=fieldvalue[1:-1]#利用strip可能会消多次,因此用list的方式处理 + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + break #直接跳出循环 + elif chari =='"': + counterquotes=counterquotes+1 + if not enclosebracket: + if operator.mod(counterquotes,2)==0: + bibentry[entryfield]=fieldvalue[1:-1] + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + break + elif chari ==',':#若域值没有包围符号那么遇到,号即为域值结束 + if enclosenone: + bibentry[entryfield]=fieldvalue[:-1] + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + enclosenone=False + + #测试:输出看是否正确 + #if entryfield=='abstract': + # print('val=',fieldvalue) + # print('counterbracket=',counterbracket) + + if fieldvalcontinued: + fieldvalended=False + + elif '}' in line:#条目结束行 + + #global bibentryglobal + #bibentryglobal=copy.deepcopy(bibentry) + #print('entry:',bibentryglobal) + #bibentries.append(bibentryglobal) + print('entry:',bibentry) + bibentries.append(bibentry) + bibentry={} + entrystated=False + + else: #当前行是前面的未结束域的值,因此直接往前面的域值添加即可 + fieldvalcontinued=True + + entryfieldline=line + + if enclosenone:#当域没有包围符号时,接续的行可能是用逗号结束的域,也可能没有逗号,而用}直接结束条目信息 + for chari in entryfieldline.strip(): + fieldvalue=fieldvalue+chari + if chari ==',': + bibentry[entryfield]=fieldvalue[:-1] + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + enclosenone=False + elif chari =='}': + bibentry[entryfield]=fieldvalue[:-1] + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + enclosenone=False + print('entry:',bibentry) + bibentries.append(bibentry) + bibentry={} + entrystated=False + else: - bibentry[entryfield]=entryfieldvalue.strip() - elif '}' in line:#条目结束行 - print('entrysn=',entrysn) - global bibentryglobal - bibentryglobal=copy.deepcopy(bibentry) - bibentries.append(bibentryglobal) - bibentry={} - else: - pass + for chari in entryfieldline.strip(): + fieldvalue=fieldvalue+chari + if chari =='{': + counterbracket=counterbracket+1 + elif chari =='}': + counterbracket=counterbracket-1 + if enclosebracket: + if counterbracket==0: + bibentry[entryfield]=fieldvalue[1:-1] + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + break + elif chari =='"': + counterquotes=counterquotes+1 + if not enclosebracket: + if mod(counterquotes,2)==0: + bibentry[entryfield]=fieldvalue[1:-1] + fieldvalue="" + counterbracket=0 + counterquotes=0 + fieldvalended=True + fieldvalcontinued=False + break + + + if fieldvalcontinued: + fieldvalended=False + elif line.startswith("@") and "@comment" in line.lower():#@comment的起始 + commentsn=commentsn+1 + entrynow=line.lstrip('@').split(sep='{', maxsplit=1) + entrytype=entrynow[0] + bibcomment['entrytype']=entrytype.lower()#条目类型小写,方便比较 + entrycontents=entrynow[1].strip()[:-1] + bibcomment['entrycontents']=entrycontents + print(bibcomment) + bibcomments.append(bibcomment) + bibcomment={} + + elif line.startswith("@") and "@string" in line.lower():#@string的起始 + stringsn=stringsn+1 + entrynow=line.lstrip('@').split(sep='{', maxsplit=1) + entrytype=entrynow[0] + bibstring['entrytype']=entrytype.lower()#条目类型小写,方便比较 + entrycontents=entrynow[1].strip()[:-1] + bibstring['entrycontents']=entrycontents + print(bibstring) + bibstrings.append(bibstring) + bibstring={} + + bibentrycounter=len(bibentries) + bibcommentcounter=len(bibcomments) + bibstringcounter=len(bibstrings) + print('entrysn=',entrysn,' commentsn=',commentsn,' stringsn=',stringsn) + print('entryct=',bibentrycounter,' commentct=',bibcommentcounter,' stringct=',bibstringcounter) + + if not bibentrycounter==entrysn or not bibcommentcounter==commentsn or not bibstringcounter==stringsn: + try: + raise BibParsingError('bib file parsing went wrong!') + except BibParsingError as e: + raise BibParsingError(e.message) print('entrytotal=',bibentrycounter) - for bibentryi in bibentries: - print(bibentryi) - + + #输出解析后的bib文件信息 + #for bibentryi in bibentries: + #print(bibentryi) + + +# +#打印bibentries列表中的所有条目 def printbibentries(): for bibentryi in bibentries: print(bibentryi) +# +#自定义异常类 +class BibParsingError(Exception): + def __init__(self,message): + Exception.__init__(self) + self.message=message # # 执行数据映射操作 @@ -185,164 +1678,345 @@ def execsourcemap(): for bibentry in bibentries:#每个映射都需要遍历所有条目,对每个条目做map mapcontinue=1#大于0表示正常,继续当前条目的map - fieldsrcinfo={}#用于接收fieldsource相关处理的结果 - print("map info=",map) + typesrcinfo={}#用于记录typesource相关处理结果 + fieldsrcinfo={}#用于记录fieldsource相关处理的结果 + constraintinfo={}#用于记录类型等限制信息记录 + constraintinfo['pertype']=[] + constraintinfo['pernottype']=[] + + #print("map info=",map) for step in map:#every step in map - if mapcontinue>0: + if mapcontinue>0:#对前面已经final完成的情况做限制 for keyvals in step:#key-vals in step for k,v in keyvals.items():#step 是有迹可循的,每个step总是存在一些东西,找到这些做其中的逻辑即可 #print(k,v) + if k=="typesource":#条目类型设置 - mapcontinue=maptypesource(keyvals,bibentry)#coef is dict + mapcontinue=maptypesource(keyvals,bibentry,typesrcinfo)#coef is dict + elif k=="fieldsource":#域查找或设置 - mapcontinue=mapfieldsource(keyvals,bibentry,fieldsrcinfo)#coef is dict - pass + mapcontinue=mapfieldsource(keyvals,bibentry,fieldsrcinfo,constraintinfo)# + #print("fieldsource step:",fieldsrcinfo) + elif k=="fieldset":#域设置 - pass - elif k=="pertype":#类型限制 - pass + mapcontinue=mapfieldset(keyvals,bibentry,typesrcinfo,fieldsrcinfo,constraintinfo)# + + elif k=="pertype": #类型限制 + mapcontinue=mappertype(keyvals,constraintinfo) + elif k=="pernottype":#类型限制 - pass + mapcontinue=mappernottype(keyvals,constraintinfo) + elif k=="notfield":#域限制 - pass + mapcontinue=mapnotfield(keyvals,bibentry,fieldsrcinfo,constraintinfo)# else: pass + +# +#域限制,若域确定不存在则终止map +def mapnotfield(keyvals,bibentry,fieldsrcinfo,constraintinfo): + + setcontinue=True + print(setcontinue) + if len(constraintinfo['pertype'])>0: + if bibentry['entrytype'] not in constraintinfo['pertype']:# + setcontinue=False + if len(constraintinfo['pernottype'])>0: + if bibentry['entrytype'] in constraintinfo['pernottype']:# + setcontinue=False + print(setcontinue) + + + print("constraints:notfield") + if setcontinue: + for k,v in keyvals.items(): + #print(k,v) + if k=='notfield': + notfield=v.lower() + elif k=='final': + fieldfinal=v + else: + pass + + if notfield not in bibentry:#当notfield不存在,则判断为true,若存在final则终止,否则继续 + if fieldfinal: + return 0 + else: + return 1 + else: + return 1 + + else: + return 0 + + + + # +#条目类型限制,将类型限制信息放入字典 +def mappertype(keyvals,constraintinfo): + + print("constraints:pertype") + for k,v in keyvals.items(): + #print(k,v) + if k=='pertype': + pertype=v.lower()#因为大小写区分,所以全部小写方便比较 + else: + pass + print('pertype=',pertype) + + constraintinfo['pertype'].append(pertype) + return 1 + +# +#条目类型限制,将类型限制信息放入字典 +def mappernottype(keyvals,constraintinfo): + + print("constraints:pernottype") + for k,v in keyvals.items(): + #print(k,v) + if k=='pernottype': + pernottype=v.lower()#因为大小写区分,所以全部小写方便比较 + else: + pass + print('pertype=',pertype) + + constraintinfo['pernottype'].append(pernottype) + return 1 + + # #条目类型转换 -def maptypesource(keyvals,bibentry): +def maptypesource(keyvals,bibentry,typesrcinfo): retrunval=1 for k,v in keyvals.items(): #print(k,v) if k=='typesource': - typesource=v + typesource=v.lower() elif k=='typetarget': - typetarget=v + typetarget=v.lower() elif k=='final': retrunval=0 else: pass - - if bibentry['entrytype']==typesource: - bibentry['entrytype']=typetarget + + typesrcinfo + if typetarget: + if bibentry['entrytype']==typesource: + bibentry['entrytype']=typetarget + typesrcinfo['typesource']=typesource + return 1 + else: + return retrunval #存在final时,且不匹配则终止map + else: + if bibentry['entrytype']==typesource: + typesrcinfo['typesource']=typesource + else: + typesrcinfo['typesource']=None + return retrunval +# +# +# 域信息设置 +def mapfieldset(keyvals,bibentry,typesrcinfo,fieldsrcinfo,constraintinfo): + overwrite=False + append=False + + setcontinue=True + print(setcontinue) + if len(constraintinfo['pertype'])>0: + if bibentry['entrytype'] not in constraintinfo['pertype']:# + setcontinue=False + if len(constraintinfo['pernottype'])>0: + if bibentry['entrytype'] in constraintinfo['pernottype']:# + setcontinue=False + print(setcontinue) + + if setcontinue: + + for k,v in keyvals.items(): + #print(k,v) + if k=='fieldset': + fieldset=v.lower() + elif k=='fieldvalue': + fieldvalue=v + elif k=='origfieldval': + fieldvalue=fieldsrcinfo[fieldsrcinfo['fieldsource']] + print(fieldvalue) + elif k=='origentrytype': + fieldvalue=typesrcinfo['typesource'] + print(fieldvalue) + elif k=='origfield': + fieldvalue=fieldsrcinfo['fieldsource'] + print(fieldvalue) + elif k=='null': + fieldvalue=None + print(fieldvalue) + elif k=='append': + append=v + elif k=='overwrite': + overwrite=v + else: + pass + + + print("fieldset=",fieldset) + if overwrite: + if append: + oldvalue=bibentry[fieldset] + newvalue=oldvalue+","+fieldvalue + bibentry[fieldset]=newvalue + else: + bibentry[fieldset]=fieldvalue + else: + if fieldset in bibentry: + pass + else: + bibentry[fieldset]=fieldvalue return 1 + else: - return retrunval #存在final时,且不匹配则终止map + return 1 # #域名转换或判断域是否存在或match -def mapfieldsource(keyvals,bibentry,fieldsrcinfo): +def mapfieldsource(keyvals,bibentry,fieldsrcinfo,constraintinfo): mapfieldtype=0 #域名map的类型设置 fieldmatch=''#匹配模式默认为空 fieldmatchi=''#匹配模式默认为空 - + + + setcontinue=True + print(setcontinue) + if len(constraintinfo['pertype'])>0: + if bibentry['entrytype'] not in constraintinfo['pertype']:# + setcontinue=False + if len(constraintinfo['pernottype'])>0: + if bibentry['entrytype'] in constraintinfo['pernottype']:# + setcontinue=False + print(setcontinue) + + + overwrite=False for k,v in keyvals.items(): #print(k,v) if k=='fieldsource': - fieldsource=v + fieldsource=v.lower() elif k=='fieldtarget': - fieldtarget=v + fieldtarget=v.lower() mapfieldtype=1 #域map类型1,直接做域名转换 elif k=='replace': fieldreplace=v mapfieldtype=2 #域map类型2,直接做域信息转换 elif k=='final': - if v=='false': - fieldfinal=v - else: - fieldfinal='true' - mapfieldtype=3 #域map类型3,做final判断可以终止map + fieldfinal=v #final要么选项不给出,要么选项给出为true + if fieldfinal:#当为true时则做终止判断 + mapfieldtype=3 #域map类型3,做final判断可以终止map + elif k=='overwrite':# + overwrite=v elif k=='match':#不区分大小写的match fieldmatch=v elif k=='matchi':#区分大小写的match fieldmatchi=v - elif k=='notmatch':#区分大小写的match + elif k=='notmatch':#不区分大小写的notmatch,下面这两个选项的逻辑没有实现 + fieldnotmatch=v + elif k=='notmatchi':#区分大小写的notmatch fieldnotmatch=v else: pass - if mapfieldtype==0:#第0中情况即,不做信息转换,也不终止map,仅返回一些信息 - - if fieldsource in bibentry: - if fieldmatch=='': - m = re.match(fieldmatch, bibentry[fieldsource]) - if m: - fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatch] - else: - fieldsrcinfo[fieldsource]=[None] #正则不匹配,则返回为None + if setcontinue: - elif fieldmatchi=='': - m = re.match(fieldmatchi, bibentry[fieldsource]) - if m: - fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatchi] + #返回字典的第一项是fieldsource信息 + fieldsrcinfo['fieldsource']=fieldsource + + if mapfieldtype==0:#第0中情况即,不做信息转换,也不终止map,仅返回一些信息 + + if fieldsource in bibentry: + if fieldmatch: + m = re.match(fieldmatch, bibentry[fieldsource]) + if m: + fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatch] + else: + fieldsrcinfo[fieldsource]=[None] #正则不匹配,则返回为None + + elif fieldmatchi: + m = re.match(fieldmatchi, bibentry[fieldsource]) + if m: + fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatchi] + else: + fieldsrcinfo[fieldsource]=[None] #正则不匹配,则返回为None + else: - fieldsrcinfo[fieldsource]=[None] #正则不匹配,则返回为None - + fieldsrcinfo[fieldsource]=bibentry[fieldsource]#将域的值记录下来,用于下一step + else: - fieldsrcinfo[fieldsource]=bibentry[fieldsource]#将域的值记录下来,用于下一step + fieldsrcinfo[fieldsource]=[None] #域不存在则返回为None + return 1 + - else: - fieldsrcinfo[fieldsource]=[None] #域不存在则返回为None - return 1 + elif mapfieldtype==1:#第1中情况即,做域名转换 + print('fieldsource=',fieldsource,'fieldtarget=',fieldtarget) + if fieldsource in bibentry: + bibentry[fieldtarget]=bibentry[fieldsource] + del bibentry[fieldsource] + fieldsrcinfo[fieldsource]=bibentry[fieldtarget] + else: + fieldsrcinfo[fieldsource]=[None] + return 1 - - elif mapfieldtype==1:#第1中情况即,做域名转换 - print('fieldsource=',fieldsource,'fieldtarget=',fieldtarget) - if fieldsource in bibentry: - bibentry[fieldtarget]=bibentry[fieldsource] - del bibentry[fieldsource] - fieldsrcinfo[fieldsource]=bibentry[fieldtarget] - else: - fieldsrcinfo[fieldsource]=[None] - return 1 - - elif mapfieldtype==2:#域map类型2,直接做域信息转换 - print('fieldsource=',fieldsource) - print('fieldmatch=',fieldmatch) - print('fieldreplace=',fieldreplace) - if fieldsource in bibentry: - if fieldmatch: - #strafrpl=re.sub(r'(\d\d\d\d)\-(\d)\-(\d)',r'\1-0\2-0\3','2015-1-3') - #strafrpl=re.sub(r'(\d\d\d\d)\-(\d)\-(\d)',r'\1-0\2-0\3',bibentry[fieldsource]) - strafrpl=re.sub(fieldmatch,fieldreplace,bibentry[fieldsource]) #执行替换 - print('strafterreplace=',strafrpl) - bibentry[fieldsource]=strafrpl - elif fieldmatchi: - strafrpl=re.sub(fieldmatchi, fieldreplace,bibentry[fieldsource]) - bibentry[fieldsource]=strafrpl + + elif mapfieldtype==2:#域map类型2,直接做域信息转换,真正操作需要overwrite选项支持 + print('fieldsource=',fieldsource) + print('fieldmatch=',fieldmatch) + print('fieldreplace=',fieldreplace) + if overwrite: + if fieldsource in bibentry: + if fieldmatch: + #strafrpl=re.sub(r'(\d\d\d\d)\-(\d)\-(\d)',r'\1-0\2-0\3','2015-1-3') + #strafrpl=re.sub(r'(\d\d\d\d)\-(\d)\-(\d)',r'\1-0\2-0\3',bibentry[fieldsource]) + strafrpl=re.sub(fieldmatch,fieldreplace,bibentry[fieldsource]) #执行替换 + print('strafterreplace=',strafrpl) + bibentry[fieldsource]=strafrpl + elif fieldmatchi: + strafrpl=re.sub(fieldmatchi, fieldreplace,bibentry[fieldsource]) + bibentry[fieldsource]=strafrpl + else: + fieldsrcinfo[fieldsource]=[None] + else: + fieldsrcinfo[fieldsource]=[None] else: fieldsrcinfo[fieldsource]=[None] - else: - fieldsrcinfo[fieldsource]=[None] - return 1 + return 1 - - elif mapfieldtype==3:#域map类型3,当没有匹配则终止map - if fieldsource in bibentry: - if fieldmatch: - m = re.match(fieldmatch, bibentry[fieldsource]) - if m: - fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatch] - return 1 - else: - return 0 + + elif mapfieldtype==3:#域map类型3,当没有匹配则终止map + if fieldsource in bibentry: + if fieldmatch: + m = re.match(fieldmatch, bibentry[fieldsource]) + if m: + fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatch] + return 1 + else: + return 0 - elif fieldmatchi: - if m: - fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatchi] - return 1 + elif fieldmatchi: + if m: + fieldsrcinfo[fieldsource]=[bibentry[fieldsource],fieldmatchi] + return 1 + else: + return 0 + else: - return 0 - + fieldsrcinfo[fieldsource]=bibentry[fieldsource]#将域的值记录下来,用于下一step + return 1 + else: - fieldsrcinfo[fieldsource]=bibentry[fieldsource]#将域的值记录下来,用于下一step - return 1 - - else: - return 0 + return 0 - + else: + fieldsrcinfo[fieldsource]=[None] + return 1 @@ -350,21 +2024,36 @@ def mapfieldsource(keyvals,bibentry,fieldsrcinfo): #运行脚本测试 if __name__=="__main__": - print('hello') - print(b'hello') - readfilecontents("biblatex-map-test.bib") - printfilecontents() + #设置需要修改的bib文件 + #inputbibfile='example.bib' + #inputbibfile='biblatex-map-test.bib' + inputbibfile='eg-thesis.bib' + + #auxfile="opt-gbpub-true.aux" + #set the aux file + #this is not necessary + auxfile='' + #auxfile="opt-gbpub-true.aux" + + readfilecontents(inputbibfile) + + #printfilecontents() bibentryparsing() - printbibentries() + #printbibentries() execsourcemap() - printbibentries() + #printbibentries() + + writefilenewbib(inputbibfile) + + #print(bibentries[0]) + + #print(formatbibentry(bibentries[0])) - writefilenewbib("biblatex-map-test.bib") - - + formatallbibliography() + printbibliography()
\ No newline at end of file |