mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-26 19:25:39 +00:00
Disentangle CiteEngines and Modules
These two are different beasts and thus should be handled differently.
This commit is contained in:
parent
ec2520677c
commit
0e6a3ac404
@ -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 \
|
||||
|
@ -492,6 +492,7 @@
|
||||
% configure script.
|
||||
\input{chklayouts}
|
||||
\input{chkmodules}
|
||||
\input{chkciteengines}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%% END ACTUAL CONFIGURATION INSPECTION CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -1,9 +1,8 @@
|
||||
# \DeclareLyXModule{Default (basic)}
|
||||
# \DeclareLyXCiteEngine{BibTeX (basic)}
|
||||
# DescriptionBegin
|
||||
# Use the basic citation capabilities provided by plain LaTeX.
|
||||
# DescriptionEnd
|
||||
# Excludes: jurabib | natbib
|
||||
# Category: Citation engine
|
||||
|
||||
# Author: Julien Rioux <jrioux@lyx.org>
|
||||
|
@ -1,11 +1,10 @@
|
||||
# \DeclareLyXModule[jurabib.sty]{Jurabib}
|
||||
# \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
|
||||
# Category: Citation engine
|
||||
|
||||
# Author: Julien Rioux <jrioux@lyx.org>
|
||||
|
@ -1,4 +1,4 @@
|
||||
# \DeclareLyXModule[natbib.sty]{Natbib}
|
||||
# \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
|
||||
@ -6,7 +6,6 @@
|
||||
# `van' part of author names, shortened and full author lists, and more.
|
||||
# DescriptionEnd
|
||||
# Excludes: basic | jurabib
|
||||
# Category: Citation engine
|
||||
|
||||
# Author: Julien Rioux <jrioux@lyx.org>
|
||||
|
131
lib/configure.py
131
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()
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
@ -229,6 +230,12 @@ def layouts_l10n(input_files, output, base, layouttranslations):
|
||||
readingI18nPreamble = True
|
||||
continue
|
||||
res = NameRE.search(line)
|
||||
if res != None:
|
||||
string = res.group(1)
|
||||
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:
|
||||
|
@ -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())
|
||||
|
280
src/CiteEnginesList.cpp
Normal file
280
src/CiteEnginesList.cpp
Normal file
@ -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
|
156
src/CiteEnginesList.h
Normal file
156
src/CiteEnginesList.h
Normal file
@ -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
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -83,6 +83,7 @@ updatetests: tex2lyx
|
||||
|
||||
LINKED_FILES = \
|
||||
../Author.cpp \
|
||||
../CiteEnginesList.cpp \
|
||||
../Color.cpp \
|
||||
../Counters.cpp \
|
||||
../Encoding.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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user