Fix bug #3686, by collecting information about missing prerequisites for

document classes, etc. Patch from Julien Rioux.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@33838 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2010-03-22 12:25:16 +00:00
parent 0ac2542679
commit cf8646083f
7 changed files with 72 additions and 27 deletions

View File

@ -57,9 +57,9 @@
\newcommand{\prefix}{+} % the character used by grep to filter 'good' output \newcommand{\prefix}{+} % the character used by grep to filter 'good' output
\newcommand{\AddLayout}[4][\default]{ \newcommand{\AddLayout}[5][\default]{
\def\default{#2} \def\default{#2}
\immediate\write\layouts{"#2" "#1" "#3" "#4"}} \immediate\write\layouts{"#2" "#1" "#3" "#4" "#5"}}
\newcommand{\AddVariable}[2]{ \newcommand{\AddVariable}[2]{
\immediate\write\vars{chk_#1='#2'}} \immediate\write\vars{chk_#1='#2'}}
@ -76,14 +76,28 @@
\def\files{#1} \def\files{#1}
\message{^^J\prefix checking for #3 #2 [#1]...} \message{^^J\prefix checking for #3 #2 [#1]...}
\let\firstelement\relax \let\firstelement\relax
\let\missingelements\empty
\existstrue \existstrue
\@for\file:=\files\do{ \@for\file:=\files\do{
\ifx\firstelement\relax \ifx\firstelement\relax
\edef\firstelement{\file} \edef\firstelement{\file}
\fi \fi
\IfFileExists{\file} \@expandtwoargs\in@{.}{\file}
\ifin@
\def\myfile{\file}
\else
\def\myfile{\file.#4}
\fi
\IfFileExists{\myfile}
{} {}
{\IfFileExists{\file.#4}{}{\existsfalse}} {
\existsfalse
\ifx\missingelements\empty
\edef\missingelements{\myfile}
\else
\edef\missingelements{\missingelements, \myfile}
\fi
}
} }
\ifexists \ifexists
\message{yes^^J} \message{yes^^J}
@ -108,8 +122,8 @@
\newcommand{\DeclareLaTeXClass}[2][\default]{ \newcommand{\DeclareLaTeXClass}[2][\default]{
\TestItem[#1]{\layoutname}{document class}{cls} \TestItem[#1]{\layoutname}{document class}{cls}
{\AddLayout[\firstelement]{\layoutname}{#2}{true}} {\AddLayout[\firstelement]{\layoutname}{#2}{true}{\missingelements}}
{\AddLayout[\firstelement]{\layoutname}{#2}{false}} {\AddLayout[\firstelement]{\layoutname}{#2}{false}{\missingelements}}
} }
% Only for compatibility. Will be removed later. % Only for compatibility. Will be removed later.
@ -119,9 +133,9 @@
\message{^^J\prefix checking for docbook\space\space class \layoutname... } \message{^^J\prefix checking for docbook\space\space class \layoutname... }
\@ifundefined{hasdocbook} \@ifundefined{hasdocbook}
{\message{no^^J} {\message{no^^J}
\AddLayout[#1]{\layoutname}{#2}{false}} \AddLayout[#1]{\layoutname}{#2}{false}{docbook}}
{\message{yes^^J} {\message{yes^^J}
\AddLayout[#1]{\layoutname}{#2}{true}} \AddLayout[#1]{\layoutname}{#2}{true}{}}
} }
% Stolen from article.cls % Stolen from article.cls

View File

@ -890,10 +890,17 @@ def processLayoutFile(file, bool_docbook):
we expect output: we expect output:
"article" "article" "article" "false" "article" "article" "article" "false" "article.cls"
"scrbook" "scrbook" "book (koma-script)" "false" "scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls"
"svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjour.cls, svjog.clo"
''' '''
def checkForClassExtension(x):
'''if the extension for a latex class is not
provided, add .cls to the classname'''
if not '.' in x:
return x.strip() + '.cls'
else:
return x.strip()
classname = file.split(os.sep)[-1].split('.')[0] classname = file.split(os.sep)[-1].split('.')[0]
# return ('LaTeX', '[a,b]', 'a', ',b,c', 'article') for \DeclareLaTeXClass[a,b,c]{article} # return ('LaTeX', '[a,b]', 'a', ',b,c', 'article') for \DeclareLaTeXClass[a,b,c]{article}
p = re.compile(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}') p = re.compile(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
@ -904,7 +911,14 @@ def processLayoutFile(file, bool_docbook):
avai = {'LaTeX':'false', 'DocBook':bool_docbook}[classtype] avai = {'LaTeX':'false', 'DocBook':bool_docbook}[classtype]
if opt == None: if opt == None:
opt = classname opt = classname
return '"%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai) prereq_latex = checkForClassExtension(classname)
else:
prereq_list = optAll[1:-1].split(',')
prereq_list = map(checkForClassExtension, prereq_list)
prereq_latex = ', '.join(prereq_list)
prereq_docbook = {'true':'', 'false':'docbook'}[bool_docbook]
prereq = {'LaTeX':prereq_latex, 'DocBook':prereq_docbook}[classtype]
return '"%s" "%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai, prereq)
logger.warning("Layout file " + file + " has no \DeclareXXClass line. ") logger.warning("Layout file " + file + " has no \DeclareXXClass line. ")
return "" return ""

View File

@ -1278,7 +1278,7 @@ contributers = [
"Re: #6361: configure.py ignores packages required by user-defined modules", "Re: #6361: configure.py ignores packages required by user-defined modules",
"m=125986505101722", "m=125986505101722",
"3 December 2009", "3 December 2009",
u"Bug fix"), u"Bug fixes"),
contributer(u"Bernhard Roider", contributer(u"Bernhard Roider",
"bernhard.roider () sonnenkinder ! org", "bernhard.roider () sonnenkinder ! org",

View File

@ -522,13 +522,12 @@ string BufferParams::readToken(Lexer & lex, string const & token,
docstring const msg = docstring const msg =
bformat(_("The layout file requested by this document,\n" bformat(_("The layout file requested by this document,\n"
"%1$s.layout,\n" "%1$s.layout,\n"
"is not usable. This is probably because a LaTeX\n" "is not usable. The following prerequisites\n"
"class or style file required by it is not\n" "are missing:\n%2$s\n"),
"available. See the Customization documentation\n" from_utf8(classname), from_utf8(baseClass()->prerequisites()));
"for more information.\n"), from_utf8(classname));
frontend::Alert::warning(_("Document class not available"), frontend::Alert::warning(_("Document class not available"),
msg + _("LyX will not be able to produce output.")); msg + _("LyX will not be able to produce output."));
} }
} else if (token == "\\begin_preamble") { } else if (token == "\\begin_preamble") {
readPreamble(lex); readPreamble(lex);
} else if (token == "\\begin_local_layout") { } else if (token == "\\begin_local_layout") {

View File

@ -42,14 +42,17 @@ using boost::regex;
using boost::smatch; using boost::smatch;
LayoutFile::LayoutFile(string const & fn, string const & cln, LayoutFile::LayoutFile(string const & fn, string const & cln,
string const & desc, bool texClassAvail ) string const & desc, string const & prereq,
bool texclassavail)
{ {
name_ = fn; name_ = fn;
latexname_ = cln; latexname_ = cln;
description_ = desc; description_ = desc;
texClassAvail_ = texClassAvail; prerequisites_ = prereq;
texClassAvail_ = texclassavail;
} }
LayoutFileList::~LayoutFileList() LayoutFileList::~LayoutFileList()
{ {
ClassMap::const_iterator it = classmap_.begin(); ClassMap::const_iterator it = classmap_.begin();
@ -59,6 +62,7 @@ LayoutFileList::~LayoutFileList()
} }
} }
LayoutFileList & LayoutFileList::get() LayoutFileList & LayoutFileList::get()
{ {
static LayoutFileList baseclasslist; static LayoutFileList baseclasslist;
@ -151,9 +155,13 @@ bool LayoutFileList::read()
break; break;
bool avail = lex.getBool(); bool avail = lex.getBool();
LYXERR(Debug::TCLASS, "Avail: " << avail); LYXERR(Debug::TCLASS, "Avail: " << avail);
if (!lex.next())
break;
string const prereq = lex.getString();
LYXERR(Debug::TCLASS, "Prereq: " << prereq);
// This code is run when we have // This code is run when we have
// fname, clname, desc, and avail // fname, clname, desc, prereq, and avail
LayoutFile * tmpl = new LayoutFile(fname, clname, desc, avail); LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, avail);
if (lyxerr.debugging(Debug::TCLASS)) { if (lyxerr.debugging(Debug::TCLASS)) {
// only system layout files are loaded here so no // only system layout files are loaded here so no
// buffer path is needed. // buffer path is needed.
@ -190,7 +198,7 @@ void LayoutFileList::reset(LayoutFileIndex const & classname) {
LayoutFile * tc = classmap_[classname]; LayoutFile * tc = classmap_[classname];
LayoutFile * tmpl = LayoutFile * tmpl =
new LayoutFile(tc->name(), tc->latexname(), tc->description(), new LayoutFile(tc->name(), tc->latexname(), tc->description(),
tc->isTeXClassAvailable()); tc->prerequisites(), tc->isTeXClassAvailable());
classmap_[classname] = tmpl; classmap_[classname] = tmpl;
delete tc; delete tc;
} }
@ -228,7 +236,8 @@ LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
// We do not know if a LaTeX class is available for this document, but setting // We do not know if a LaTeX class is available for this document, but setting
// the last parameter to true will suppress a warning message about missing // the last parameter to true will suppress a warning message about missing
// tex class. // tex class.
LayoutFile * tc = new LayoutFile(textclass, textclass, "Unknown text class " + textclass, true); LayoutFile * tc = new LayoutFile(textclass, textclass,
"Unknown text class " + textclass, textclass + ".cls", true);
if (!tc->load(tempLayout.absFilename())) { if (!tc->load(tempLayout.absFilename())) {
// The only way this happens is because the hardcoded layout file above // The only way this happens is because the hardcoded layout file above
// is wrong. // is wrong.
@ -268,9 +277,13 @@ LayoutFileIndex
// returns: whole string, classtype (not used here), class name, description // returns: whole string, classtype (not used here), class name, description
LASSERT(sub.size() == 4, /**/); LASSERT(sub.size() == 4, /**/);
// now, create a TextClass with description containing path information // now, create a TextClass with description containing path information
string className(sub.str(2) == "" ? textclass : sub.str(2)); string class_name(sub.str(2) == "" ? textclass : sub.str(2));
string class_prereq(class_name + ".cls");
LayoutFile * tmpl = LayoutFile * tmpl =
new LayoutFile(textclass, className, textclass, true); new LayoutFile(textclass, class_name, textclass, class_prereq, true);
//FIXME: The prerequisites are available from the layout file and
// can be extracted from the above regex, but for now this
// field is simply set to class_name + ".cls"
// This textclass is added on request so it will definitely be // This textclass is added on request so it will definitely be
// used. Load it now because other load() calls may fail if they // used. Load it now because other load() calls may fail if they
// are called in a context without buffer path information. // are called in a context without buffer path information.

View File

@ -79,7 +79,8 @@ private:
explicit LayoutFile(std::string const & filename, explicit LayoutFile(std::string const & filename,
std::string const & className = std::string(), std::string const & className = std::string(),
std::string const & description = std::string(), std::string const & description = std::string(),
bool texClassAvail = false); std::string const & prerequisites = std::string(),
bool texclassavail = false);
/// The only class that should create a LayoutFile is /// The only class that should create a LayoutFile is
/// LayoutFileList, which calls the private constructor. /// LayoutFileList, which calls the private constructor.
friend class LayoutFileList; friend class LayoutFileList;

View File

@ -189,6 +189,8 @@ public:
std::string const & description() const { return description_; } std::string const & description() const { return description_; }
/// ///
std::string const & latexname() const { return latexname_; } std::string const & latexname() const { return latexname_; }
///
std::string const & prerequisites() const { return prerequisites_; }
/// Can be LaTeX, DocBook, etc. /// Can be LaTeX, DocBook, etc.
OutputType outputType() const { return outputType_; } OutputType outputType() const { return outputType_; }
/// Can be latex, docbook ... (the name of a format) /// Can be latex, docbook ... (the name of a format)
@ -238,6 +240,8 @@ protected:
mutable bool loaded_; mutable bool loaded_;
/// Is the TeX class available? /// Is the TeX class available?
bool texClassAvail_; bool texClassAvail_;
/// document class prerequisites
std::string prerequisites_;
/// ///
std::string opt_fontsize_; std::string opt_fontsize_;
/// ///