Disentangle CiteEngines and Modules

These two are different beasts and thus should be handled differently.
This commit is contained in:
Juergen Spitzmueller 2016-12-30 16:22:08 +01:00
parent ed0e4064d2
commit ff8fe6aaf8
17 changed files with 640 additions and 17 deletions

View File

@ -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 \

View File

@ -492,6 +492,7 @@
% configure script.
\input{chklayouts}
\input{chkmodules}
\input{chkciteengines}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% END ACTUAL CONFIGURATION INSPECTION CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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()

View File

@ -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

View File

@ -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:

View File

@ -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
View 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 &eng;
}
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 &eng;
}
return 0;
}
} // namespace lyx

156
src/CiteEnginesList.h Normal file
View 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

View File

@ -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;

View File

@ -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 \

View File

@ -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;
}

View File

@ -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

View File

@ -83,6 +83,7 @@ updatetests: tex2lyx
LINKED_FILES = \
../Author.cpp \
../CiteEnginesList.cpp \
../Color.cpp \
../Counters.cpp \
../Encoding.cpp \

View File

@ -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;
}