commit ff8fe6aaf87882f629a8865fc02f55001f427605 Author: Juergen Spitzmueller <sp...@lyx.org> Date: Fri Dec 30 16:22:08 2016 +0100
Disentangle CiteEngines and Modules These two are different beasts and thus should be handled differently. --- lib/Makefile.am | 9 +- lib/chkconfig.ltx | 1 + lib/citeengines/basic.citeengine | 43 ++++++ lib/citeengines/jurabib.citeengine | 105 ++++++++++++++ lib/citeengines/natbib.citeengine | 106 ++++++++++++++ lib/configure.py | 131 +++++++++++++++++- lib/layouts/basic.module | 44 ------ lib/layouts/jurabib.module | 106 -------------- lib/layouts/natbib.module | 107 -------------- po/Rules-lyx | 2 +- po/lyx_pot.py | 7 + src/BufferParams.cpp | 5 +- src/CiteEnginesList.cpp | 280 ++++++++++++++++++++++++++++++++++++ src/CiteEnginesList.h | 156 ++++++++++++++++++++ src/LyX.cpp | 8 +- src/Makefile.am | 2 + src/TextClass.cpp | 40 +++++ src/TextClass.h | 3 + src/tex2lyx/Makefile.am | 1 + src/tex2lyx/tex2lyx.cpp | 3 +- 20 files changed, 891 insertions(+), 268 deletions(-) diff --git a/lib/Makefile.am b/lib/Makefile.am index ee7e2b1..36c9c0c 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2107,7 +2107,6 @@ dist_layouts_DATA =\ layouts/arab-article.layout \ layouts/article.layout \ layouts/article-beamer.layout \ - layouts/basic.module \ layouts/beamer.layout \ layouts/beamerposter.layout \ layouts/bicaption.module \ @@ -2185,7 +2184,6 @@ dist_layouts_DATA =\ layouts/jsarticle.layout \ layouts/jsbook.layout \ layouts/jss.layout \ - layouts/jurabib.module \ layouts/kluwer.layout \ layouts/knitr.module \ layouts/latex8.layout \ @@ -2205,7 +2203,6 @@ dist_layouts_DATA =\ layouts/mwart.layout \ layouts/mwbk.layout \ layouts/mwrep.layout \ - layouts/natbib.module \ layouts/natbibapa.module \ layouts/noweb.module \ layouts/numarticle.inc \ @@ -2302,6 +2299,12 @@ dist_layouts_DATA =\ layouts/tufte-handout.layout \ layouts/varwidth.module +citeenginesdir = $(pkgdatadir)/citeengines +dist_citeengines_DATA = \ + citeengines/basic.citeengine \ + citeengines/jurabib.citeengine \ + citeengines/natbib.citeengine + scriptsdir = $(pkgdatadir)/scripts dist_scripts_DATA = \ scripts/bash_completion \ diff --git a/lib/chkconfig.ltx b/lib/chkconfig.ltx index 140014a..9daca8f 100644 --- a/lib/chkconfig.ltx +++ b/lib/chkconfig.ltx @@ -492,6 +492,7 @@ % configure script. \input{chklayouts} \input{chkmodules} +\input{chkciteengines} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%% END ACTUAL CONFIGURATION INSPECTION CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/citeengines/basic.citeengine b/lib/citeengines/basic.citeengine new file mode 100644 index 0000000..dc4941b --- /dev/null +++ b/lib/citeengines/basic.citeengine @@ -0,0 +1,43 @@ +# \DeclareLyXCiteEngine{BibTeX (basic)} +# DescriptionBegin +# Use the basic citation capabilities provided by plain LaTeX. +# DescriptionEnd +# Excludes: jurabib | natbib + +# Author: Julien Rioux <jri...@lyx.org> + +Format 62 + +CiteEngineType default +DefaultBiblio plain + +CiteEngine default + cite[] + nocite +End + +CiteFormat default + # translatable bits + _notcited not cited + _addtobib Add to bibliography only. + + # macros + !open [ + !sep , + !close ] + + !startlink {!<a href='#LyXCite-%clean:key%'>!} + !endlink {!</a>!} + + !cite %!startlink%{%label%[[%label%]][[{%numericallabel%[[%numericallabel%]][[#%key%]]}]]}%!endlink%%!nextcite% + + !nextcite {%next%[[%!sep% %!cite%]]} + !nexthashkey {%next%[[%!sep% #%key%%!nexthashkey%]]} + !nextkey {%next%[[%!sep% %key%%!nextkey%]]} + + !textafter {%textafter%[[, %textafter%]]} + + # cite styles + cite %!open%{%dialog%[[#ID]][[%!cite%]]}%!textafter%%!close% + nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]} +End diff --git a/lib/citeengines/jurabib.citeengine b/lib/citeengines/jurabib.citeengine new file mode 100644 index 0000000..13bbc6f --- /dev/null +++ b/lib/citeengines/jurabib.citeengine @@ -0,0 +1,105 @@ +# \DeclareLyXCiteEngine[jurabib.sty]{Jurabib} +# DescriptionBegin +# Loads the LaTeX package jurabib, a citation engine. Jurabib supports annotations, +# author-year style citations and hyphenation patterns for bibliography entries in +# English, German, French, Dutch, Spanish and Italian. +# DescriptionEnd +# Excludes: basic | natbib + +# Author: Julien Rioux <jri...@lyx.org> + +Format 62 + +Requires jurabib + +CiteEngineType authoryear +DefaultBiblio jurabib + +# FIXME: support for these jurabib styles (fileformat) +# citefield []{} +# footcite [][] +# footcitetitle [][] +# footcitet [][] +# footcitep [][] +# footcitealt [][] +# footcitealp [][] +# footciteauthor [][] +# footciteyear [][] +# footciteyearpar [][] +# footfullcite [][] + +CiteEngine authoryear + # \cite* is not implemented: use \cite instead, it's the same + cite [][] + citetitle [][] + citet [][] + citep [][] + citealt [][] + citealp [][] + citeauthor [][] + citeyear [][] + citeyearpar [][] + fullcite [][] + nocite +End + +CiteFormat authoryear + # translatable bits + _notcited not cited + _addtobib Add to bibliography only. + _fullcite bibliography entry + _bibentry Bibliography entry. + _before before + _shorttitle short title + + # macros + !open ( + !sep ; + !close ) + + !startlink {!<a href='#LyXCite-%clean:key%'>!} + !endlink {!</a>!} + + !cite %!startlink%%!shortauthor%%!endlink%%!textbefore2%%!textafter2%%!nextcite% + !citetitle %!startlink%%!shortauthor%%!endlink%%!textbefore2%%!shorttitle%%!textafter2%%!nextcitetitle% + !citet %!textbefore%%!startlink%%!shortauthor%%!endlink% %!open%%!year%%!textafter%%!close%%!nextcitet% + !citep %!open%%!citealp%%!close% + !citealt %!textbefore%%!startlink%%!shortauthor% %!year%%!endlink%%!textafter%%!nextcitealt% + !citealp %!textbefore%%!startlink%%!shortauthor%, %!year%%!endlink%%!textafter%%!nextcitealp% + !citeauthor %!textbefore%%!startlink%%!shortauthor%%!endlink%%!textafter%%!nextauthor% + !citeyear %!textbefore%%!startlink%%!year%%!endlink%%!textafter%%!nextyear% + !citeyearpar %!textbefore%%!open%%!startlink%%!year%%!endlink%%!close%%!textafter%%!nextyearpar% + !fullcite {%textbefore%[[%textbefore% in: ]]}%bibentry%{%textafter%[[ %textafter%]]}%!nextfullcite% + + !nextcite {%next%[[%!sep% %!startlink%%!shortauthor%%!endlink%%!textafter2%%!nextcite%]]} + !nextcitetitle {%next%[[%!sep% %!startlink%%!shortauthor%%!endlink%%!shorttitle%%!textafter2%%!nextcitetitle%]]} + !nextcitet {%next%[[%!sep% %!citet%]]} + !nextcitealt {%next%[[%!sep% %!citealt%]]} + !nextcitealp {%next%[[%!sep% %!citealp%]]} + !nextauthor {%next%[[%!sep% %!citeauthor%]]} + !nextyear {%next%[[%!sep% %!citeyear%]]} + !nextyearpar {%next%[[%!sep% %!citeyearpar%]]} + !nextfullcite {%next%[[%!sep% %bibentry%{%textafter%[[ %textafter%]]}%!nextfullcite%]]} + !nextkey {%next%[[%!sep% %key%%!nextkey%]]} + + !shortauthor {%shortauthor%[[%shortauthor%]][[??]]} + !shorttitle {%shorttitle%[[ %shorttitle%]][[{%dialog%[[ <%_shorttitle%>]]}]]} + !textbefore {%textbefore%[[%textbefore% ]]} + !textbefore2 {%textbefore%[[/%textbefore%]][[{%dialog%[[/<%_before%>]]}]]} + !textafter {%textafter%[[, %textafter%]]} + !textafter2 {%textafter%[[ %textafter%]]} + !year {%year%[[%year%]][[??]]}{%modifier%[[%modifier%]]} + + # cite styles + cite %!cite% + citetitle %!citetitle% + citet %!citet% + citep %!citep% + citealt %!citealt% + citealp %!citealp% + citeauthor %!citeauthor% + citeyear %!citeyear% + citeyearpar %!citeyearpar% + fullcite {%dialog%[[%_bibentry%]][[{%label%[[%!fullcite%]][[%key%%!nextkey% (%_fullcite%)]]}]]} + nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]} +End diff --git a/lib/citeengines/natbib.citeengine b/lib/citeengines/natbib.citeengine new file mode 100644 index 0000000..63bf1cb --- /dev/null +++ b/lib/citeengines/natbib.citeengine @@ -0,0 +1,106 @@ +# \DeclareLyXCiteEngine[natbib.sty]{Natbib} +# DescriptionBegin +# Loads the LaTeX package natbib, a citation engine. Natbib supports +# both author-year and numerical styles for citations, automatic sorting +# and merging of numerical citations, annotations, capitalization of the +# `van' part of author names, shortened and full author lists, and more. +# DescriptionEnd +# Excludes: basic | jurabib + +# Author: Julien Rioux <jri...@lyx.org> + +Format 62 + +Requires natbib + +CiteEngineType authoryear|numerical +DefaultBiblio plainnat + +CiteEngine authoryear + Citet*[][] + Citep*[][] + Citealt*[][] + Citealp*[][] + Citeauthor*[] + citeyear[] + citeyearpar[][] + nocite +End + +CiteEngine numerical + Citep*[][] + Citealp*[][] + Citet*[][] + Citealt*[][] + Citeauthor* + citeyearpar[][] + citeyear + nocite +End + +CiteFormat default + # translatable bits + _notcited not cited + _addtobib Add to bibliography only. + + # macros + !startlink {!<a href='#LyXCite-%clean:key%'>!} + !endlink {!</a>!} + + !nextauthor {%next%[[%!sep% %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%]]} + !nextkey {%next%[[%!sep% %key%%!nextkey%]]} + !nextyear {%next%[[%!sep% %!startlink%%!year%%!endlink%%!nextyear%]]} + + !abbrvauthor {%abbrvauthor%[[%abbrvauthor%]][[??]]} + !textbefore {%textbefore%[[%textbefore% ]]} + !textafter {%textafter%[[, %textafter%]]} + !year {%year%[[%year%]][[??]]}{%modifier%[[%modifier%]]} + + # cite styles + citet %!citet%%!textafter%%!close% + citealt %!citealt%%!textafter% + citeyearpar %!open%%!textbefore%%!startlink%%!year%%!endlink%%!nextyear%%!textafter%%!close% + nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]} +End + +CiteFormat authoryear + !open ( + !sep ; + !close ) + + !citet %!startlink%%!abbrvauthor%%!endlink% %!open%%!textbefore%%!year%%!nextcitet% + !citealt %!startlink%%!abbrvauthor% %!textbefore%%!year%%!endlink%%!nextcitealt% + !citealp %!startlink%%!abbrvauthor%, %!year%%!endlink%%!nextcitealp% + + !nextcitet {%next%[[%!close%%!sep% %!citet%]]} + !nextcitealt {%next%[[%!sep% %!citealt%]]} + !nextcitealp {%next%[[%!sep% %!citealp%]]} + + cite %!citet%%!textafter%%!close% + citep %!open%%!textbefore%%!citealp%%!textafter%%!close% + citealp %!textbefore%%!citealp%%!textafter% + citeauthor %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%%!textafter% + citeyear %!startlink%%!year%%!endlink%%!nextyear%%!textafter% +End + +CiteFormat numerical + !open [ + !sep , + !close ] + + !citet %!abbrvauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet% + !citealt %!abbrvauthor% %!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt% + + !hashkey {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]} + + !nextcitet {%next%[[%!close%%!sep% %!citet%]]} + !nextcitealt {%next%[[%!sep% %!citealt%]]} + !nexthashid {%next%[[%!sep% #ID%!nexthashid%]]} + !nexthashkey {%next%[[%!sep% %!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]} + + cite %!open%%!textbefore%%!hashkey%%!textafter%%!close% + citep %!open%%!textbefore%%!hashkey%%!textafter%%!close% + citealp %!textbefore%%!hashkey%%!textafter% + citeauthor %!startlink%%!abbrvauthor%%!endlink%%!nextauthor% + citeyear %!startlink%%!year%%!endlink%%!nextyear% +End diff --git a/lib/configure.py b/lib/configure.py index fb1abd3..680e32a 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -1502,6 +1502,132 @@ def processModuleFile(file, filename, bool_docbook): return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, desc, pkgs, req, excl, catgy) +def checkCiteEnginesConfig(): + removeFiles(['lyxciteengines.lst', 'chkciteengines.tex']) + + logger.info('+checking list of cite engines... ') + tx = open('lyxciteengines.lst', 'w') + tx.write('''## This file declares cite engines and their associated definition files. +## It has been automatically generated by configure +## Use "Options/Reconfigure" if you need to update it after a +## configuration change. +## "CiteEngineName" "filename" "CiteEngineType" "Description" "Packages" "Requires" "Excludes" +''') + + # build the list of available modules + seen = [] + # note that this searches the local directory first, then the + # system directory. that way, we pick up the user's version first. + for file in glob.glob( os.path.join('citeengines', '*.citeengine') ) + \ + glob.glob( os.path.join(srcdir, 'citeengines', '*.citeengine' ) ) : + # valid file? + logger.info(file) + if not os.path.isfile(file): + continue + + filename = file.split(os.sep)[-1] + filename = filename[:-11] + if seen.count(filename): + continue + + seen.append(filename) + retval = processCiteEngineFile(file, filename, bool_docbook) + if retval != "": + tx.write(retval) + tx.close() + logger.info('\tdone') + + +def processCiteEngineFile(file, filename, bool_docbook): + ''' process cite engines file and get a line of result + + The top of a cite engine file should look like this: + #\DeclareLyXCiteEngine[LaTeX Packages]{CiteEngineName} + #DescriptionBegin + #...body of description... + #DescriptionEnd + #Requires: [list of required engines] + #Excludes: [list of excluded engines] + The last two lines are optional. + We expect output: + "CiteEngineName" "filename" "CiteEngineType" "Description" "Packages" "Requires" "Excludes" + ''' + remods = re.compile(r'\DeclareLyXCiteEngine\s*(?:\[([^]]*?)\])?{(.*)}') + rereqs = re.compile(r'#+\s*Requires: (.*)') + reexcs = re.compile(r'#+\s*Excludes: (.*)') + redbeg = re.compile(r'#+\s*DescriptionBegin\s*$') + redend = re.compile(r'#+\s*DescriptionEnd\s*$') + recet = re.compile(r'\s*CiteEngineType (.*)') + + modname = desc = pkgs = req = excl = cet = "" + readingDescription = False + descLines = [] + + for line in open(file).readlines(): + if readingDescription: + res = redend.search(line) + if res != None: + readingDescription = False + desc = " ".join(descLines) + # Escape quotes. + desc = desc.replace('"', '\\"') + continue + descLines.append(line[1:].strip()) + continue + res = redbeg.search(line) + if res != None: + readingDescription = True + continue + res = remods.search(line) + if res != None: + (pkgs, modname) = res.groups() + if pkgs == None: + pkgs = "" + else: + tmp = [s.strip() for s in pkgs.split(",")] + pkgs = ",".join(tmp) + continue + res = rereqs.search(line) + if res != None: + req = res.group(1) + tmp = [s.strip() for s in req.split("|")] + req = "|".join(tmp) + continue + res = reexcs.search(line) + if res != None: + excl = res.group(1) + tmp = [s.strip() for s in excl.split("|")] + excl = "|".join(tmp) + continue + res = recet.search(line) + if res != None: + cet = res.group(1) + continue + + if modname == "": + logger.warning("Cite Engine File file without \DeclareLyXCiteEngine line. ") + return "" + + if pkgs != "": + # this cite engine has some latex dependencies: + # append the dependencies to chkciteengines.tex, + # which is \input'ed by chkconfig.ltx + testpackages = list() + for pkg in pkgs.split(","): + if "->" in pkg: + # this is a converter dependency: skip + continue + if pkg.endswith(".sty"): + pkg = pkg[:-4] + testpackages.append("\\TestPackage{%s}" % (pkg,)) + cm = open('chkciteengines.tex', 'a') + for line in testpackages: + cm.write(line + '\n') + cm.close() + + return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, cet, desc, pkgs, req, excl) + + def checkTeXAllowSpaces(): ''' Let's check whether spaces are allowed in TeX file names ''' tex_allows_spaces = 'false' @@ -1543,8 +1669,8 @@ def removeTempFiles(): # Final clean-up if not lyx_keep_temps: removeFiles(['chkconfig.vars', 'chklatex.ltx', 'chklatex.log', - 'chklayouts.tex', 'chkmodules.tex', 'missfont.log', - 'wrap_chkconfig.ltx', 'wrap_chkconfig.log']) + 'chklayouts.tex', 'chkmodules.tex', 'chkciteengines.tex', + 'missfont.log', 'wrap_chkconfig.ltx', 'wrap_chkconfig.log']) if __name__ == '__main__': @@ -1623,6 +1749,7 @@ Format %i if lyx_kpsewhich: rescanTeXFiles() checkModulesConfig() + checkCiteEnginesConfig() # --without-latex-config can disable lyx_check_config ret = checkLatexConfig(lyx_check_config and LATEX != '', bool_docbook) removeTempFiles() diff --git a/lib/layouts/basic.module b/lib/layouts/basic.module deleted file mode 100644 index 8e0ed1c..0000000 --- a/lib/layouts/basic.module +++ /dev/null @@ -1,44 +0,0 @@ -# \DeclareLyXModule{Default (basic)} -# DescriptionBegin -# Use the basic citation capabilities provided by plain LaTeX. -# DescriptionEnd -# Excludes: jurabib | natbib -# Category: Citation engine - -# Author: Julien Rioux <jri...@lyx.org> - -Format 62 - -CiteEngineType default -DefaultBiblio plain - -CiteEngine default - cite[] - nocite -End - -CiteFormat default - # translatable bits - _notcited not cited - _addtobib Add to bibliography only. - - # macros - !open [ - !sep , - !close ] - - !startlink {!<a href='#LyXCite-%clean:key%'>!} - !endlink {!</a>!} - - !cite %!startlink%{%label%[[%label%]][[{%numericallabel%[[%numericallabel%]][[#%key%]]}]]}%!endlink%%!nextcite% - - !nextcite {%next%[[%!sep% %!cite%]]} - !nexthashkey {%next%[[%!sep% #%key%%!nexthashkey%]]} - !nextkey {%next%[[%!sep% %key%%!nextkey%]]} - - !textafter {%textafter%[[, %textafter%]]} - - # cite styles - cite %!open%{%dialog%[[#ID]][[%!cite%]]}%!textafter%%!close% - nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]} -End diff --git a/lib/layouts/jurabib.module b/lib/layouts/jurabib.module deleted file mode 100644 index 63bae5a..0000000 --- a/lib/layouts/jurabib.module +++ /dev/null @@ -1,106 +0,0 @@ -# \DeclareLyXModule[jurabib.sty]{Jurabib} -# DescriptionBegin -# Loads the LaTeX package jurabib, a citation engine. Jurabib supports annotations, -# author-year style citations and hyphenation patterns for bibliography entries in -# English, German, French, Dutch, Spanish and Italian. -# DescriptionEnd -# Excludes: basic | natbib -# Category: Citation engine - -# Author: Julien Rioux <jri...@lyx.org> - -Format 62 - -Requires jurabib - -CiteEngineType authoryear -DefaultBiblio jurabib - -# FIXME: support for these jurabib styles (fileformat) -# citefield []{} -# footcite [][] -# footcitetitle [][] -# footcitet [][] -# footcitep [][] -# footcitealt [][] -# footcitealp [][] -# footciteauthor [][] -# footciteyear [][] -# footciteyearpar [][] -# footfullcite [][] - -CiteEngine authoryear - # \cite* is not implemented: use \cite instead, it's the same - cite [][] - citetitle [][] - citet [][] - citep [][] - citealt [][] - citealp [][] - citeauthor [][] - citeyear [][] - citeyearpar [][] - fullcite [][] - nocite -End - -CiteFormat authoryear - # translatable bits - _notcited not cited - _addtobib Add to bibliography only. - _fullcite bibliography entry - _bibentry Bibliography entry. - _before before - _shorttitle short title - - # macros - !open ( - !sep ; - !close ) - - !startlink {!<a href='#LyXCite-%clean:key%'>!} - !endlink {!</a>!} - - !cite %!startlink%%!shortauthor%%!endlink%%!textbefore2%%!textafter2%%!nextcite% - !citetitle %!startlink%%!shortauthor%%!endlink%%!textbefore2%%!shorttitle%%!textafter2%%!nextcitetitle% - !citet %!textbefore%%!startlink%%!shortauthor%%!endlink% %!open%%!year%%!textafter%%!close%%!nextcitet% - !citep %!open%%!citealp%%!close% - !citealt %!textbefore%%!startlink%%!shortauthor% %!year%%!endlink%%!textafter%%!nextcitealt% - !citealp %!textbefore%%!startlink%%!shortauthor%, %!year%%!endlink%%!textafter%%!nextcitealp% - !citeauthor %!textbefore%%!startlink%%!shortauthor%%!endlink%%!textafter%%!nextauthor% - !citeyear %!textbefore%%!startlink%%!year%%!endlink%%!textafter%%!nextyear% - !citeyearpar %!textbefore%%!open%%!startlink%%!year%%!endlink%%!close%%!textafter%%!nextyearpar% - !fullcite {%textbefore%[[%textbefore% in: ]]}%bibentry%{%textafter%[[ %textafter%]]}%!nextfullcite% - - !nextcite {%next%[[%!sep% %!startlink%%!shortauthor%%!endlink%%!textafter2%%!nextcite%]]} - !nextcitetitle {%next%[[%!sep% %!startlink%%!shortauthor%%!endlink%%!shorttitle%%!textafter2%%!nextcitetitle%]]} - !nextcitet {%next%[[%!sep% %!citet%]]} - !nextcitealt {%next%[[%!sep% %!citealt%]]} - !nextcitealp {%next%[[%!sep% %!citealp%]]} - !nextauthor {%next%[[%!sep% %!citeauthor%]]} - !nextyear {%next%[[%!sep% %!citeyear%]]} - !nextyearpar {%next%[[%!sep% %!citeyearpar%]]} - !nextfullcite {%next%[[%!sep% %bibentry%{%textafter%[[ %textafter%]]}%!nextfullcite%]]} - !nextkey {%next%[[%!sep% %key%%!nextkey%]]} - - !shortauthor {%shortauthor%[[%shortauthor%]][[??]]} - !shorttitle {%shorttitle%[[ %shorttitle%]][[{%dialog%[[ <%_shorttitle%>]]}]]} - !textbefore {%textbefore%[[%textbefore% ]]} - !textbefore2 {%textbefore%[[/%textbefore%]][[{%dialog%[[/<%_before%>]]}]]} - !textafter {%textafter%[[, %textafter%]]} - !textafter2 {%textafter%[[ %textafter%]]} - !year {%year%[[%year%]][[??]]}{%modifier%[[%modifier%]]} - - # cite styles - cite %!cite% - citetitle %!citetitle% - citet %!citet% - citep %!citep% - citealt %!citealt% - citealp %!citealp% - citeauthor %!citeauthor% - citeyear %!citeyear% - citeyearpar %!citeyearpar% - fullcite {%dialog%[[%_bibentry%]][[{%label%[[%!fullcite%]][[%key%%!nextkey% (%_fullcite%)]]}]]} - nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]} -End diff --git a/lib/layouts/natbib.module b/lib/layouts/natbib.module deleted file mode 100644 index d4d250e..0000000 --- a/lib/layouts/natbib.module +++ /dev/null @@ -1,107 +0,0 @@ -# \DeclareLyXModule[natbib.sty]{Natbib} -# DescriptionBegin -# Loads the LaTeX package natbib, a citation engine. Natbib supports -# both author-year and numerical styles for citations, automatic sorting -# and merging of numerical citations, annotations, capitalization of the -# `van' part of author names, shortened and full author lists, and more. -# DescriptionEnd -# Excludes: basic | jurabib -# Category: Citation engine - -# Author: Julien Rioux <jri...@lyx.org> - -Format 62 - -Requires natbib - -CiteEngineType authoryear|numerical -DefaultBiblio plainnat - -CiteEngine authoryear - Citet*[][] - Citep*[][] - Citealt*[][] - Citealp*[][] - Citeauthor*[] - citeyear[] - citeyearpar[][] - nocite -End - -CiteEngine numerical - Citep*[][] - Citealp*[][] - Citet*[][] - Citealt*[][] - Citeauthor* - citeyearpar[][] - citeyear - nocite -End - -CiteFormat default - # translatable bits - _notcited not cited - _addtobib Add to bibliography only. - - # macros - !startlink {!<a href='#LyXCite-%clean:key%'>!} - !endlink {!</a>!} - - !nextauthor {%next%[[%!sep% %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%]]} - !nextkey {%next%[[%!sep% %key%%!nextkey%]]} - !nextyear {%next%[[%!sep% %!startlink%%!year%%!endlink%%!nextyear%]]} - - !abbrvauthor {%abbrvauthor%[[%abbrvauthor%]][[??]]} - !textbefore {%textbefore%[[%textbefore% ]]} - !textafter {%textafter%[[, %textafter%]]} - !year {%year%[[%year%]][[??]]}{%modifier%[[%modifier%]]} - - # cite styles - citet %!citet%%!textafter%%!close% - citealt %!citealt%%!textafter% - citeyearpar %!open%%!textbefore%%!startlink%%!year%%!endlink%%!nextyear%%!textafter%%!close% - nocite {%dialog%[[%_addtobib%]][[%key%%!nextkey% (%_notcited%)]]} -End - -CiteFormat authoryear - !open ( - !sep ; - !close ) - - !citet %!startlink%%!abbrvauthor%%!endlink% %!open%%!textbefore%%!year%%!nextcitet% - !citealt %!startlink%%!abbrvauthor% %!textbefore%%!year%%!endlink%%!nextcitealt% - !citealp %!startlink%%!abbrvauthor%, %!year%%!endlink%%!nextcitealp% - - !nextcitet {%next%[[%!close%%!sep% %!citet%]]} - !nextcitealt {%next%[[%!sep% %!citealt%]]} - !nextcitealp {%next%[[%!sep% %!citealp%]]} - - cite %!citet%%!textafter%%!close% - citep %!open%%!textbefore%%!citealp%%!textafter%%!close% - citealp %!textbefore%%!citealp%%!textafter% - citeauthor %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%%!textafter% - citeyear %!startlink%%!year%%!endlink%%!nextyear%%!textafter% -End - -CiteFormat numerical - !open [ - !sep , - !close ] - - !citet %!abbrvauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet% - !citealt %!abbrvauthor% %!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt% - - !hashkey {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]} - - !nextcitet {%next%[[%!close%%!sep% %!citet%]]} - !nextcitealt {%next%[[%!sep% %!citealt%]]} - !nexthashid {%next%[[%!sep% #ID%!nexthashid%]]} - !nexthashkey {%next%[[%!sep% %!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]} - - cite %!open%%!textbefore%%!hashkey%%!textafter%%!close% - citep %!open%%!textbefore%%!hashkey%%!textafter%%!close% - citealp %!textbefore%%!hashkey%%!textafter% - citeauthor %!startlink%%!abbrvauthor%%!endlink%%!nextauthor% - citeyear %!startlink%%!year%%!endlink%%!nextyear% -End diff --git a/po/Rules-lyx b/po/Rules-lyx index 42998f2..23d4c06 100644 --- a/po/Rules-lyx +++ b/po/Rules-lyx @@ -34,7 +34,7 @@ layouts_l10n.pot: $(top_srcdir)/lib/layouts/*.layout \ # Read translatable strings from layouts and translations from the po files and # create the layouttranslations file containing all LaTeX relevant translations $(top_srcdir)/lib/layouttranslations: $(POFILES) $(top_srcdir)/lib/layouts/*.layout \ - $(top_srcdir)/lib/layouts/*.inc $(top_srcdir)/lib/layouts/*.module + $(top_srcdir)/lib/layouts/*.inc $(top_srcdir)/lib/layouts/*.module $(top_srcdir)/lib/citeengines/*.citeengines $(LYX_POT) -o $@ -t layouttranslations ${top_srcdir}/lib/layouts/*.layout ${top_srcdir}/lib/layouts/*.inc ${top_srcdir}/lib/layouts/*.module languages_l10n.pot: $(top_srcdir)/lib/languages diff --git a/po/lyx_pot.py b/po/lyx_pot.py index 761e3dd..0fc7ee4 100755 --- a/po/lyx_pot.py +++ b/po/lyx_pot.py @@ -91,6 +91,7 @@ def layouts_l10n(input_files, output, base, layouttranslations): ListName = re.compile(r'^\s*ListName\s+(.*\S)\s*$', re.IGNORECASE) CategoryName = re.compile(r'^\s*Category\s+(.*\S)\s*$', re.IGNORECASE) NameRE = re.compile(r'^\s*#\s*\\DeclareLyXModule.*{(.*)}$', re.IGNORECASE) + CiteNameRE = re.compile(r'^\s*#\s*\\DeclareLyXCiteEngine.*{(.*)}$', re.IGNORECASE) InsetLayout = re.compile(r'^InsetLayout\s+\"?(.*)\"?\s*$', re.IGNORECASE) FlexCheck = re.compile(r'^Flex:(.*)', re.IGNORECASE) CaptionCheck = re.compile(r'^Caption:(.*)', re.IGNORECASE) @@ -234,6 +235,12 @@ def layouts_l10n(input_files, output, base, layouttranslations): if not layouttranslations: writeString(out, src, base, lineno + 1, string) continue + res = CiteNameRE.search(line) + if res != None: + string = res.group(1) + if not layouttranslations: + writeString(out, src, base, lineno + 1, string) + continue res = Style.search(line) if res != None: string = res.group(1) diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index fa0b7c3..326d487 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -2333,6 +2333,7 @@ void BufferParams::makeDocumentClass(bool const clone) invalidateConverterCache(); LayoutModuleList mods; + LayoutModuleList ces; LayoutModuleList::iterator it = layout_modules_.begin(); LayoutModuleList::iterator en = layout_modules_.end(); for (; it != en; ++it) @@ -2341,9 +2342,9 @@ void BufferParams::makeDocumentClass(bool const clone) it = cite_engine_.begin(); en = cite_engine_.end(); for (; it != en; ++it) - mods.push_back(*it); + ces.push_back(*it); - doc_class_ = getDocumentClass(*baseClass(), mods, clone); + doc_class_ = getDocumentClass(*baseClass(), mods, ces, clone); TextClass::ReturnValues success = TextClass::OK; if (!forced_local_layout_.empty()) diff --git a/src/CiteEnginesList.cpp b/src/CiteEnginesList.cpp new file mode 100644 index 0000000..48222cb --- /dev/null +++ b/src/CiteEnginesList.cpp @@ -0,0 +1,280 @@ +// -*- C++ -*- +/** + * \file CiteEnginesList.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Richard Heck + * \author Jürgen Spitzmüller + * + * Full author contact details are available in file CREDITS. + */ + +#include <config.h> + +#include "CiteEnginesList.h" + +#include "LaTeXFeatures.h" +#include "Lexer.h" + +#include "support/debug.h" +#include "support/FileName.h" +#include "support/gettext.h" +#include "support/filetools.h" +#include "support/lstrings.h" + +#include <algorithm> + +using namespace std; +using namespace lyx::support; + +namespace lyx { + + +//global variable: cite engine list +CiteEnginesList theCiteEnginesList; + + +LyXCiteEngine::LyXCiteEngine(string const & n, string const & i, + vector<string> const & cet, string const & d, + vector<string> const & p, + vector<string> const & r, vector<string> const & e): + name_(n), id_(i), engine_types_(cet), description_(d), package_list_(p), + required_engines_(r), excluded_engines_(e), + checked_(false), available_(false) +{ + filename_ = id_ + ".citeengine"; +} + + +vector<string> LyXCiteEngine::prerequisites() const +{ + if (!checked_) + isAvailable(); + return prerequisites_; +} + + +bool LyXCiteEngine::isAvailable() const +{ + if (package_list_.empty()) + return true; + if (checked_) + return available_; + checked_ = true; + available_ = true; + //check whether all of the required packages are available + vector<string>::const_iterator it = package_list_.begin(); + vector<string>::const_iterator end = package_list_.end(); + for (; it != end; ++it) { + if (!LaTeXFeatures::isAvailable(*it)) { + available_ = false; + prerequisites_.push_back(*it); + } + } + return available_; +} + + +bool LyXCiteEngine::isCompatible(string const & cename) const +{ + // do we exclude it? + if (find(excluded_engines_.begin(), excluded_engines_.end(), cename) != + excluded_engines_.end()) + return false; + + LyXCiteEngine const * const lm = theCiteEnginesList[cename]; + if (!lm) + return true; + + // does it exclude us? + vector<string> const excengs = lm->getExcludedEngines(); + if (find(excengs.begin(), excengs.end(), id_) != excengs.end()) + return false; + + return true; +} + + +bool LyXCiteEngine::areCompatible(string const & eng1, string const & eng2) +{ + LyXCiteEngine const * const lm1 = theCiteEnginesList[eng1]; + if (lm1) + return lm1->isCompatible(eng2); + LyXCiteEngine const * const lm2 = theCiteEnginesList[eng2]; + if (lm2) + return lm2->isCompatible(eng1); + // Can't check it either way. + return true; +} + + +// used when sorting the cite engine list. +class EngineSorter { +public: + int operator()(LyXCiteEngine const & ce1, LyXCiteEngine const & ce2) const + { + return _(ce1.getName()) < _(ce2.getName()); + } +}; + + +// Much of this is borrowed from LayoutFileList::read() +bool CiteEnginesList::read() +{ + FileName const real_file = libFileSearch("", "lyxciteengines.lst"); + LYXERR(Debug::TCLASS, "Reading cite engines from `" << real_file << '\''); + + if (real_file.empty()) { + LYXERR0("unable to find cite engines file `citeengines.lst'.\n" + << "No cite engines will be available."); + return false; + } + + Lexer lex; + if (!lex.setFile(real_file)) { + LYXERR0("lyxlex was not able to set file: " + << real_file << ".\nNo cite engines will be available."); + return false; + } + + if (!lex.isOK()) { + LYXERR0("unable to open cite engines file `" + << to_utf8(makeDisplayPath(real_file.absFileName(), 1000)) + << "'\nNo cite engines will be available."); + return false; + } + + bool finished = false; + // Parse cite engines files + LYXERR(Debug::TCLASS, "Starting parsing of lyxciteengines.lst"); + while (lex.isOK() && !finished) { + LYXERR(Debug::TCLASS, "\tline by line"); + switch (lex.lex()) { + case Lexer::LEX_FEOF: + finished = true; + break; + default: + string const cename = lex.getString(); + LYXERR(Debug::TCLASS, "Engine name: " << cename); + if (!lex.next()) + break; + string const fname = lex.getString(); + LYXERR(Debug::TCLASS, "Filename: " << fname); + if (!lex.next(true)) + break; + string cet = lex.getString(); + LYXERR(Debug::TCLASS, "Engine Type: " << cet); + vector<string> cets; + while (!cet.empty()) { + string p; + cet = split(cet, p, '|'); + cets.push_back(p); + } + if (!lex.next(true)) + break; + string const desc = lex.getString(); + LYXERR(Debug::TCLASS, "Description: " << desc); + //FIXME Add packages + if (!lex.next()) + break; + string str = lex.getString(); + LYXERR(Debug::TCLASS, "Packages: " << str); + vector<string> pkgs; + while (!str.empty()) { + string p; + str = split(str, p, ','); + pkgs.push_back(p); + } + if (!lex.next()) + break; + str = lex.getString(); + LYXERR(Debug::TCLASS, "Required: " << str); + vector<string> req; + while (!str.empty()) { + string p; + str = split(str, p, '|'); + req.push_back(p); + } + if (!lex.next()) + break; + str = lex.getString(); + LYXERR(Debug::TCLASS, "Excluded: " << str); + vector<string> exc; + while (!str.empty()) { + string p; + str = split(str, p, '|'); + exc.push_back(p); + } + // This code is run when we have + // cename, fname, desc, pkgs, req and exc + addCiteEngine(cename, fname, cets, desc, pkgs, req, exc); + } // end switch + } //end while + + LYXERR(Debug::TCLASS, "End of parsing of lyxciteengines.lst"); + + if (!theCiteEnginesList.empty()) + sort(theCiteEnginesList.begin(), theCiteEnginesList.end(), EngineSorter()); + return true; +} + + +void CiteEnginesList::addCiteEngine(string const & cename, + string const & filename, vector<string> const & cets, string const & description, + vector<string> const & pkgs, vector<string> const & req, + vector<string> const & exc) +{ + LyXCiteEngine ce(cename, filename, cets, description, pkgs, req, exc); + englist_.push_back(ce); +} + + +LyXCiteEnginesList::const_iterator CiteEnginesList::begin() const +{ + return englist_.begin(); +} + + +LyXCiteEnginesList::iterator CiteEnginesList::begin() +{ + return englist_.begin(); +} + + +LyXCiteEnginesList::const_iterator CiteEnginesList::end() const +{ + return englist_.end(); +} + + +LyXCiteEnginesList::iterator CiteEnginesList::end() +{ + return englist_.end(); +} + + +LyXCiteEngine const * CiteEnginesList::operator[](string const & str) const +{ + LyXCiteEnginesList::const_iterator it = englist_.begin(); + for (; it != englist_.end(); ++it) + if (it->getID() == str) { + LyXCiteEngine const & eng = *it; + return ŋ + } + return 0; +} + + +LyXCiteEngine * CiteEnginesList::operator[](string const & str) +{ + LyXCiteEnginesList::iterator it = englist_.begin(); + for (; it != englist_.end(); ++it) + if (it->getID() == str) { + LyXCiteEngine & eng = *it; + return ŋ + } + return 0; +} + +} // namespace lyx diff --git a/src/CiteEnginesList.h b/src/CiteEnginesList.h new file mode 100644 index 0000000..0e6d119 --- /dev/null +++ b/src/CiteEnginesList.h @@ -0,0 +1,156 @@ +// -*- C++ -*- +/** + * \file CiteEnginesList.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Richard Heck + * \author Jürgen Spitzmüller + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef CITEENGINESLIST_H +#define CITEENGINESLIST_H + +#include <string> +#include <vector> + +namespace lyx { + +/** + * This class represents a particular LyX "cite engine", which defines the features + * of a particular citation backend such as natbib or biblatex. In that sense, it is more like + * a LaTeX package, where a layout file corresponds to a LaTeX class. + * + * In general, a given cite engine can be used with any document class. That said, + * one cite engine may `require' another, or it may `exclude' some other cite engine. + * The requires and excludes are given in comments within the cite engine file, + * which must begin roughly so: + * # \DeclareLyXCiteEngine[natbib.sty]{Natbib} + * # DescriptionBegin + * # Loads the LaTeX package natbib, a citation engine. Natbib supports + * # both author-year and numerical styles for citations, automatic sorting + * # and merging of numerical citations, annotations, capitalization of the + * # `van' part of author names, shortened and full author lists, and more. + * # DescriptionEnd + * # Excludes: basic | jurabib + * The description might be used in the gui to give information to the user. The + * Requires and Excludes lines are read by the configuration script + * and written to a file citeengines.lst in the user configuration directory. + * That file is then read on startup to populate the CiteEnginesList, below. + * + * Engines can also be "provided" or "excluded" by document classes, using + * the ProvidesEngine and ExcludesEngine tags. + */ + +class LyXCiteEngine { +public: + /// + LyXCiteEngine(std::string const & name, std::string const & id, + std::vector<std::string> const & enginetypes, + std::string const & description, + std::vector<std::string> const & packagelist, + std::vector<std::string> const & requires, + std::vector<std::string> const & excludes); + /// whether the required packages are available + bool isAvailable() const; + /// the missing prerequisites, if any + std::vector<std::string> prerequisites() const; + /// + std::string const & getName() const { return name_; } + /// + std::string const & getID() const { return id_; } + /// + std::string const & getFilename() const { return filename_; } + /// + std::vector<std::string> const & getEngineType() const { return engine_types_; } + /// + std::string const & getDescription() const { return description_; } + /// + std::vector<std::string> const & getPackageList() const + { return package_list_; } + /// + std::vector<std::string> const & getRequiredEngines() const + { return required_engines_; } + /// Engines this one excludes: the list should be treated disjunctively + std::vector<std::string> const & getExcludedEngines() const + { return excluded_engines_; } + /// \return true if the engine is compatible with this one, i.e., + /// it does not exclude us and we do not exclude it. + /// this will also return true if cename is unknown and we do not + /// exclude it, since in that case we cannot check its exclusions. + bool isCompatible(std::string const & cename) const; + /// + static bool areCompatible(std::string const & eng1, std::string const & eng2); +private: + /// what appears in the ui + std::string name_; + /// the engine's unique identifier + /// at present, this is the filename, without the extension + std::string id_; + /// the filename + std::string filename_; + /// the engine type(s) + std::vector<std::string> engine_types_; + /// a short description for use in the ui + std::string description_; + /// the LaTeX packages on which this depends, if any + std::vector<std::string> package_list_; + /// Engines this one requires: at least one + std::vector<std::string> required_engines_; + /// Engines this one excludes: none of these + std::vector<std::string> excluded_engines_; + // these are mutable because they are used to cache the results + // or an otherwise const operation. + /// + mutable bool checked_; + /// + mutable bool available_; + /// + mutable std::vector<std::string> prerequisites_; +}; + +typedef std::vector<LyXCiteEngine> LyXCiteEnginesList; + +/** + * The CiteEnginesList represents the various LyXCiteEngine's that are available at + * present. + */ +class CiteEnginesList { +public: + /// + CiteEnginesList() {} + /// reads the engines from a file generated by configure.py + bool read(); + /// + LyXCiteEnginesList::const_iterator begin() const; + /// + LyXCiteEnginesList::iterator begin(); + /// + LyXCiteEnginesList::const_iterator end() const; + /// + LyXCiteEnginesList::iterator end(); + /// + bool empty() const { return englist_.empty(); } + /// Returns a pointer to the LyXCiteEngine with filename str. + /// Returns a null pointer if no such engine is found. + LyXCiteEngine const * operator[](std::string const & str) const; + /// + LyXCiteEngine * operator[](std::string const & str); + private: + /// noncopyable + CiteEnginesList(CiteEnginesList const &); + /// + void operator=(CiteEnginesList const &); + /// add an engine to the list + void addCiteEngine(std::string const &, std::string const &, + std::vector<std::string> const &, std::string const &, std::vector<std::string> const &, + std::vector<std::string> const &, std::vector<std::string> const &); + /// + std::vector<LyXCiteEngine> englist_; +}; + +extern CiteEnginesList theCiteEnginesList; +} +#endif diff --git a/src/LyX.cpp b/src/LyX.cpp index 047e265..157d432 100644 --- a/src/LyX.cpp +++ b/src/LyX.cpp @@ -22,6 +22,7 @@ #include "Buffer.h" #include "BufferList.h" #include "CmdDef.h" +#include "CiteEnginesList.h" #include "ColorSet.h" #include "ConverterCache.h" #include "Converter.h" @@ -935,8 +936,10 @@ bool LyX::init() LYXERR(Debug::INIT, "Reading layouts..."); // Load the layouts LayoutFileList::get().read(); - //...and the modules + //... the modules theModuleList.read(); + //... and the cite engines + theCiteEnginesList.read(); // read keymap and ui files in batch mode as well // because InsetInfo needs to know these to produce @@ -1020,7 +1023,8 @@ bool LyX::queryUserLyXDir(bool explicit_userdir) return configFileNeedsUpdate("lyxrc.defaults") || configFileNeedsUpdate("lyxmodules.lst") || configFileNeedsUpdate("textclass.lst") - || configFileNeedsUpdate("packages.lst"); + || configFileNeedsUpdate("packages.lst") + || configFileNeedsUpdate("lyxciteengines.lst"); } first_start = !explicit_userdir; diff --git a/src/Makefile.am b/src/Makefile.am index f87d029..4cb38b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -108,6 +108,7 @@ SOURCEFILESCORE = \ Bullet.cpp \ Changes.cpp \ Chktex.cpp \ + CiteEnginesList.cpp \ CmdDef.cpp \ Color.cpp \ ConverterCache.cpp \ @@ -201,6 +202,7 @@ HEADERFILESCORE = \ BufferView.h \ Bullet.h \ Citation.h \ + CiteEnginesList.h \ Changes.h \ Chktex.h \ CmdDef.h \ diff --git a/src/TextClass.cpp b/src/TextClass.cpp index 46a96e4..d14ef29 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -17,6 +17,7 @@ #include "TextClass.h" #include "LayoutFile.h" +#include "CiteEnginesList.h" #include "Color.h" #include "Counters.h" #include "Floating.h" @@ -123,6 +124,8 @@ string translateReadType(TextClass::ReadType rt) return "input file"; case TextClass::MODULE: return "module file"; + case TextClass::CITE_ENGINE: + return "cite engine"; case TextClass::VALIDATION: return "validation"; } @@ -1585,6 +1588,7 @@ Layout TextClass::createBasicLayout(docstring const & name, bool unknown) const DocumentClassPtr getDocumentClass( LayoutFile const & baseClass, LayoutModuleList const & modlist, + LayoutModuleList const & celist, bool const clone) { DocumentClassPtr doc_class = @@ -1623,6 +1627,42 @@ DocumentClassPtr getDocumentClass( frontend::Alert::warning(_("Read Error"), msg); } } + + LayoutModuleList::const_iterator cit = celist.begin(); + LayoutModuleList::const_iterator cen = celist.end(); + for (; cit != cen; ++cit) { + string const ceName = *cit; + LyXCiteEngine * ce = theCiteEnginesList[ceName]; + if (!ce) { + docstring const msg = + bformat(_("The cite engine %1$s has been requested by\n" + "this document but has not been found in the list of\n" + "available engines. If you recently installed it, you\n" + "probably need to reconfigure LyX.\n"), from_utf8(ceName)); + if (!clone) + frontend::Alert::warning(_("Cite Engine not available"), msg); + continue; + } + if (!ce->isAvailable() && !clone) { + docstring const prereqs = from_utf8(getStringFromVector(ce->prerequisites(), "\n\t")); + docstring const msg = + bformat(_("The cite engine %1$s requires a package that is not\n" + "available in your LaTeX installation, or a converter that\n" + "you have not installed. LaTeX output may not be possible.\n" + "Missing prerequisites:\n" + "\t%2$s\n" + "See section 3.1.2.3 (Modules) of the User's Guide for more information."), + from_utf8(ceName), prereqs); + frontend::Alert::warning(_("Package not available"), msg, true); + } + FileName layout_file = libFileSearch("citeengines", ce->getFilename()); + if (!doc_class->read(layout_file, TextClass::CITE_ENGINE)) { + docstring const msg = + bformat(_("Error reading cite engine %1$s\n"), from_utf8(ceName)); + frontend::Alert::warning(_("Read Error"), msg); + } + } + return doc_class; } diff --git a/src/TextClass.h b/src/TextClass.h index 22d426c..d082e10 100644 --- a/src/TextClass.h +++ b/src/TextClass.h @@ -151,6 +151,7 @@ public: BASECLASS, //>This is a base class, i.e., top-level layout file MERGE, //>This is a file included in a layout file MODULE, //>This is a layout module + CITE_ENGINE, //>This is a cite engine VALIDATION //>We're just validating }; /// return values for read() @@ -498,6 +499,7 @@ private: /// The only way to make a DocumentClass is to call this function. friend DocumentClassPtr getDocumentClass(LayoutFile const &, LayoutModuleList const &, + LayoutModuleList const &, bool const clone); }; @@ -508,6 +510,7 @@ private: /// on the CutStack. DocumentClassPtr getDocumentClass(LayoutFile const & baseClass, LayoutModuleList const & modlist, + LayoutModuleList const & celist, bool const clone = false); /// convert page sides option to text 1 or 2 diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am index bf2d66d..a4a5fdc 100644 --- a/src/tex2lyx/Makefile.am +++ b/src/tex2lyx/Makefile.am @@ -83,6 +83,7 @@ updatetests: tex2lyx LINKED_FILES = \ ../Author.cpp \ + ../CiteEnginesList.cpp \ ../Color.cpp \ ../Counters.cpp \ ../Encoding.cpp \ diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp index 7a6bbb0..3f6fe73 100644 --- a/src/tex2lyx/tex2lyx.cpp +++ b/src/tex2lyx/tex2lyx.cpp @@ -282,10 +282,11 @@ void initModules() for (; it != end; ++it) { string const module = it->getID(); LayoutModuleList m; + LayoutModuleList c; vector<string> v; if (!addModule(module, baseClass, m, v)) continue; - modules[module] = getDocumentClass(baseClass, m); + modules[module] = getDocumentClass(baseClass, m, c); } init = false; }