2003-08-22 09:44:59 +00:00
|
|
|
/**
|
2007-04-29 19:53:54 +00:00
|
|
|
* \file TextClass.cpp
|
2003-08-22 09:44:59 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 17:27:08 +00:00
|
|
|
*
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Lars Gullik Bjønnes
|
2003-08-22 09:44:59 +00:00
|
|
|
* \author Jean-Marc Lasgouttes
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Angus Leeming
|
|
|
|
* \author John Levon
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
2002-03-21 17:27:08 +00:00
|
|
|
*
|
2003-08-22 09:44:59 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2001-12-28 13:26:54 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
#include "TextClass.h"
|
2007-10-25 12:41:02 +00:00
|
|
|
|
2008-03-07 03:53:21 +00:00
|
|
|
#include "LayoutFile.h"
|
2016-12-30 15:22:08 +00:00
|
|
|
#include "CiteEnginesList.h"
|
2007-10-25 12:41:02 +00:00
|
|
|
#include "Color.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Counters.h"
|
2003-09-04 03:54:04 +00:00
|
|
|
#include "Floating.h"
|
2002-09-11 07:39:55 +00:00
|
|
|
#include "FloatList.h"
|
2007-10-25 12:41:02 +00:00
|
|
|
#include "Layout.h"
|
|
|
|
#include "Lexer.h"
|
2007-12-08 11:07:43 +00:00
|
|
|
#include "Font.h"
|
2009-02-11 23:22:10 +00:00
|
|
|
#include "ModuleList.h"
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2007-07-11 13:39:08 +00:00
|
|
|
#include "frontends/alert.h"
|
|
|
|
|
2008-04-30 08:26:40 +00:00
|
|
|
#include "support/lassert.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/debug.h"
|
2013-04-25 21:27:10 +00:00
|
|
|
#include "support/ExceptionMessage.h"
|
2007-12-17 16:04:46 +00:00
|
|
|
#include "support/FileName.h"
|
2001-12-28 13:26:54 +00:00
|
|
|
#include "support/filetools.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/gettext.h"
|
|
|
|
#include "support/lstrings.h"
|
2006-06-30 13:54:01 +00:00
|
|
|
#include "support/os.h"
|
2014-06-09 11:05:50 +00:00
|
|
|
#include "support/TempFile.h"
|
2006-06-30 13:54:01 +00:00
|
|
|
|
2008-03-07 19:43:17 +00:00
|
|
|
#include <algorithm>
|
2008-03-24 12:31:07 +00:00
|
|
|
#include <fstream>
|
2005-10-21 16:11:36 +00:00
|
|
|
#include <sstream>
|
|
|
|
|
2009-10-11 10:30:00 +00:00
|
|
|
#ifdef ERROR
|
|
|
|
#undef ERROR
|
|
|
|
#endif
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
using namespace lyx::support;
|
2007-10-28 18:51:54 +00:00
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
namespace lyx {
|
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
// Keep the changes documented in the Customization manual.
|
2010-07-18 11:58:38 +00:00
|
|
|
//
|
|
|
|
// If you change this format, then you MUST also make sure that
|
2011-12-03 22:15:11 +00:00
|
|
|
// your changes do not invalidate the hardcoded layout file in
|
2010-07-18 11:58:38 +00:00
|
|
|
// LayoutFile.cpp. Additions will never do so, but syntax changes
|
|
|
|
// could. See LayoutFileList::addEmptyClass() and, especially, the
|
2011-12-03 22:15:11 +00:00
|
|
|
// definition of the layoutpost string.
|
2014-11-16 11:43:52 +00:00
|
|
|
// You should also run the development/tools/updatelayouts.py script,
|
|
|
|
// to update the format of all of our layout files.
|
2010-07-18 11:58:38 +00:00
|
|
|
//
|
2018-01-01 11:27:08 +00:00
|
|
|
int const LAYOUT_FORMAT = 66; //spitz: New layout tag AutoNests
|
2011-12-03 22:15:11 +00:00
|
|
|
|
2016-07-23 14:29:40 +00:00
|
|
|
|
|
|
|
// Layout format for the current lyx file format. Controls which format is
|
|
|
|
// targeted by Local Layout > Convert. In master, equal to LAYOUT_FORMAT.
|
|
|
|
int const LYXFILE_LAYOUT_FORMAT = LAYOUT_FORMAT;
|
|
|
|
|
|
|
|
|
2004-01-31 15:30:24 +00:00
|
|
|
namespace {
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
class LayoutNamesEqual : public unary_function<Layout, bool> {
|
2004-01-31 15:30:24 +00:00
|
|
|
public:
|
2007-07-11 13:39:08 +00:00
|
|
|
LayoutNamesEqual(docstring const & name)
|
2003-03-14 11:57:12 +00:00
|
|
|
: name_(name)
|
|
|
|
{}
|
2008-03-06 20:01:30 +00:00
|
|
|
bool operator()(Layout const & c) const
|
2003-03-14 11:57:12 +00:00
|
|
|
{
|
2008-03-06 20:01:30 +00:00
|
|
|
return c.name() == name_;
|
2002-06-24 20:28:12 +00:00
|
|
|
}
|
2004-01-31 15:30:24 +00:00
|
|
|
private:
|
2007-07-11 13:39:08 +00:00
|
|
|
docstring name_;
|
2002-06-24 20:28:12 +00:00
|
|
|
};
|
|
|
|
|
2005-10-21 16:11:36 +00:00
|
|
|
|
2016-07-23 14:29:40 +00:00
|
|
|
bool layout2layout(FileName const & filename, FileName const & tempfile,
|
|
|
|
int const format = LAYOUT_FORMAT)
|
2005-10-21 16:11:36 +00:00
|
|
|
{
|
2006-11-26 21:30:39 +00:00
|
|
|
FileName const script = libFileSearch("scripts", "layout2layout.py");
|
2005-10-21 16:11:36 +00:00
|
|
|
if (script.empty()) {
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0("Could not find layout conversion "
|
2016-07-23 14:29:40 +00:00
|
|
|
"script layout2layout.py.");
|
2005-10-21 16:11:36 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
ostringstream command;
|
2007-12-12 19:57:42 +00:00
|
|
|
command << os::python() << ' ' << quoteName(script.toFilesystemEncoding())
|
2016-07-23 14:29:40 +00:00
|
|
|
<< " -t " << format
|
|
|
|
<< ' ' << quoteName(filename.toFilesystemEncoding())
|
|
|
|
<< ' ' << quoteName(tempfile.toFilesystemEncoding());
|
2005-10-21 16:11:36 +00:00
|
|
|
string const command_str = command.str();
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::TCLASS, "Running `" << command_str << '\'');
|
2005-10-21 16:11:36 +00:00
|
|
|
|
2008-04-03 21:36:57 +00:00
|
|
|
cmd_ret const ret = runCommand(command_str);
|
2005-10-21 16:11:36 +00:00
|
|
|
if (ret.first != 0) {
|
2016-07-23 14:29:40 +00:00
|
|
|
if (format == LAYOUT_FORMAT)
|
|
|
|
LYXERR0("Conversion of layout with layout2layout.py has failed.");
|
2005-10-21 16:11:36 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-02-05 16:20:18 +00:00
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
string translateReadType(TextClass::ReadType rt)
|
2008-02-05 16:20:18 +00:00
|
|
|
{
|
|
|
|
switch (rt) {
|
|
|
|
case TextClass::BASECLASS:
|
|
|
|
return "textclass";
|
|
|
|
case TextClass::MERGE:
|
|
|
|
return "input file";
|
|
|
|
case TextClass::MODULE:
|
|
|
|
return "module file";
|
2016-12-30 15:22:08 +00:00
|
|
|
case TextClass::CITE_ENGINE:
|
|
|
|
return "cite engine";
|
2008-03-24 12:31:07 +00:00
|
|
|
case TextClass::VALIDATION:
|
|
|
|
return "validation";
|
2008-02-05 16:20:18 +00:00
|
|
|
}
|
2008-02-06 09:37:37 +00:00
|
|
|
// shutup warning
|
|
|
|
return string();
|
2008-02-05 16:20:18 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 11:11:54 +00:00
|
|
|
} // namespace
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
// This string should not be translated here,
|
2008-04-15 15:32:46 +00:00
|
|
|
// because it is a layout identifier.
|
2015-04-17 13:58:14 +00:00
|
|
|
docstring const TextClass::plain_layout_ = from_ascii(N_("Plain Layout"));
|
This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required.
At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do.
There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-29 02:45:33 +00:00
|
|
|
|
|
|
|
|
2008-04-16 21:23:45 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// TextClass
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required.
At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do.
There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-29 02:45:33 +00:00
|
|
|
TextClass::TextClass()
|
2015-09-12 21:11:35 +00:00
|
|
|
: loaded_(false), tex_class_avail_(false),
|
|
|
|
opt_enginetype_("authoryear|numerical"), opt_fontsize_("10|11|12"),
|
|
|
|
opt_pagestyle_("empty|plain|headings|fancy"), pagestyle_("default"),
|
|
|
|
columns_(1), sides_(OneSide), secnumdepth_(3), tocdepth_(3),
|
2017-09-01 08:27:12 +00:00
|
|
|
outputType_(LATEX), outputFormat_("latex"), has_output_format_(false),
|
2015-09-12 21:11:35 +00:00
|
|
|
defaultfont_(sane_font),
|
|
|
|
titletype_(TITLE_COMMAND_AFTER), titlename_("maketitle"),
|
2017-01-07 15:44:27 +00:00
|
|
|
min_toclevel_(0), max_toclevel_(0), maxcitenames_(2),
|
2015-09-12 21:11:35 +00:00
|
|
|
cite_full_author_list_(true)
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-11 02:43:02 +00:00
|
|
|
bool TextClass::readStyle(Lexer & lexrc, Layout & lay) const
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::TCLASS, "Reading style " << to_utf8(lay.name()));
|
2008-02-14 04:12:15 +00:00
|
|
|
if (!lay.read(lexrc, *this)) {
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0("Error parsing style `" << to_utf8(lay.name()) << '\'');
|
2008-02-13 14:39:16 +00:00
|
|
|
return false;
|
2002-03-21 17:27:08 +00:00
|
|
|
}
|
2008-02-13 14:39:16 +00:00
|
|
|
// Resolve fonts
|
|
|
|
lay.resfont = lay.font;
|
This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required.
At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do.
There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-29 02:45:33 +00:00
|
|
|
lay.resfont.realize(defaultfont_);
|
2008-02-13 14:39:16 +00:00
|
|
|
lay.reslabelfont = lay.labelfont;
|
This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required.
At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do.
There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-29 02:45:33 +00:00
|
|
|
lay.reslabelfont.realize(defaultfont_);
|
2008-02-13 14:39:16 +00:00
|
|
|
return true; // no errors
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enum TextClassTags {
|
|
|
|
TC_OUTPUTTYPE = 1,
|
2009-05-28 08:59:25 +00:00
|
|
|
TC_OUTPUTFORMAT,
|
2001-12-28 13:26:54 +00:00
|
|
|
TC_INPUT,
|
|
|
|
TC_STYLE,
|
2015-12-04 02:06:28 +00:00
|
|
|
TC_MODIFYSTYLE,
|
|
|
|
TC_PROVIDESTYLE,
|
2002-03-02 16:39:54 +00:00
|
|
|
TC_DEFAULTSTYLE,
|
2007-08-13 12:13:17 +00:00
|
|
|
TC_INSETLAYOUT,
|
2013-02-09 19:31:26 +00:00
|
|
|
TC_NOINSETLAYOUT,
|
2001-12-28 13:26:54 +00:00
|
|
|
TC_NOSTYLE,
|
|
|
|
TC_COLUMNS,
|
|
|
|
TC_SIDES,
|
|
|
|
TC_PAGESTYLE,
|
|
|
|
TC_DEFAULTFONT,
|
|
|
|
TC_SECNUMDEPTH,
|
|
|
|
TC_TOCDEPTH,
|
|
|
|
TC_CLASSOPTIONS,
|
|
|
|
TC_PREAMBLE,
|
2009-06-05 17:26:30 +00:00
|
|
|
TC_HTMLPREAMBLE,
|
2011-12-06 22:38:46 +00:00
|
|
|
TC_HTMLSTYLES,
|
2007-04-06 09:02:23 +00:00
|
|
|
TC_PROVIDES,
|
2008-01-07 16:59:10 +00:00
|
|
|
TC_REQUIRES,
|
2013-05-23 13:25:40 +00:00
|
|
|
TC_PKGOPTS,
|
2001-12-28 13:26:54 +00:00
|
|
|
TC_LEFTMARGIN,
|
2002-09-04 06:52:26 +00:00
|
|
|
TC_RIGHTMARGIN,
|
2002-09-06 14:48:01 +00:00
|
|
|
TC_FLOAT,
|
2002-09-11 07:39:55 +00:00
|
|
|
TC_COUNTER,
|
2011-01-12 22:53:41 +00:00
|
|
|
TC_NOCOUNTER,
|
2009-08-12 14:50:01 +00:00
|
|
|
TC_IFCOUNTER,
|
2003-02-13 17:49:09 +00:00
|
|
|
TC_NOFLOAT,
|
|
|
|
TC_TITLELATEXNAME,
|
2005-10-21 16:11:36 +00:00
|
|
|
TC_TITLELATEXTYPE,
|
2008-03-24 13:11:16 +00:00
|
|
|
TC_FORMAT,
|
2008-07-25 15:51:27 +00:00
|
|
|
TC_ADDTOPREAMBLE,
|
2009-06-19 12:49:08 +00:00
|
|
|
TC_ADDTOHTMLPREAMBLE,
|
2011-12-06 22:38:46 +00:00
|
|
|
TC_ADDTOHTMLSTYLES,
|
2008-10-23 00:27:03 +00:00
|
|
|
TC_DEFAULTMODULE,
|
|
|
|
TC_PROVIDESMODULE,
|
2010-01-12 19:38:31 +00:00
|
|
|
TC_EXCLUDESMODULE,
|
2010-03-29 18:37:25 +00:00
|
|
|
TC_HTMLTOCSECTION,
|
2012-03-01 00:41:30 +00:00
|
|
|
TC_CITEENGINE,
|
|
|
|
TC_CITEENGINETYPE,
|
|
|
|
TC_CITEFORMAT,
|
2016-12-31 18:44:32 +00:00
|
|
|
TC_CITEFRAMEWORK,
|
2017-01-07 15:44:27 +00:00
|
|
|
TC_MAXCITENAMES,
|
2012-03-01 00:41:30 +00:00
|
|
|
TC_DEFAULTBIBLIO,
|
2015-11-03 16:47:25 +00:00
|
|
|
TC_FULLAUTHORLIST,
|
|
|
|
TC_OUTLINERNAME
|
2001-12-28 13:26:54 +00:00
|
|
|
};
|
|
|
|
|
2005-10-21 16:11:36 +00:00
|
|
|
|
2008-03-24 12:31:07 +00:00
|
|
|
namespace {
|
2005-10-21 16:11:36 +00:00
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
LexerKeyword textClassTags[] = {
|
|
|
|
{ "addtohtmlpreamble", TC_ADDTOHTMLPREAMBLE },
|
|
|
|
{ "addtohtmlstyles", TC_ADDTOHTMLSTYLES },
|
|
|
|
{ "addtopreamble", TC_ADDTOPREAMBLE },
|
|
|
|
{ "citeengine", TC_CITEENGINE },
|
|
|
|
{ "citeenginetype", TC_CITEENGINETYPE },
|
|
|
|
{ "citeformat", TC_CITEFORMAT },
|
2016-12-31 18:44:32 +00:00
|
|
|
{ "citeframework", TC_CITEFRAMEWORK },
|
2012-10-27 13:45:27 +00:00
|
|
|
{ "classoptions", TC_CLASSOPTIONS },
|
|
|
|
{ "columns", TC_COLUMNS },
|
|
|
|
{ "counter", TC_COUNTER },
|
|
|
|
{ "defaultbiblio", TC_DEFAULTBIBLIO },
|
|
|
|
{ "defaultfont", TC_DEFAULTFONT },
|
|
|
|
{ "defaultmodule", TC_DEFAULTMODULE },
|
|
|
|
{ "defaultstyle", TC_DEFAULTSTYLE },
|
|
|
|
{ "excludesmodule", TC_EXCLUDESMODULE },
|
|
|
|
{ "float", TC_FLOAT },
|
|
|
|
{ "format", TC_FORMAT },
|
|
|
|
{ "fullauthorlist", TC_FULLAUTHORLIST },
|
|
|
|
{ "htmlpreamble", TC_HTMLPREAMBLE },
|
|
|
|
{ "htmlstyles", TC_HTMLSTYLES },
|
|
|
|
{ "htmltocsection", TC_HTMLTOCSECTION },
|
|
|
|
{ "ifcounter", TC_IFCOUNTER },
|
|
|
|
{ "input", TC_INPUT },
|
|
|
|
{ "insetlayout", TC_INSETLAYOUT },
|
|
|
|
{ "leftmargin", TC_LEFTMARGIN },
|
2017-01-07 15:44:27 +00:00
|
|
|
{ "maxcitenames", TC_MAXCITENAMES },
|
2015-12-04 02:06:28 +00:00
|
|
|
{ "modifystyle", TC_MODIFYSTYLE },
|
2012-10-27 13:45:27 +00:00
|
|
|
{ "nocounter", TC_NOCOUNTER },
|
|
|
|
{ "nofloat", TC_NOFLOAT },
|
2013-02-09 19:31:26 +00:00
|
|
|
{ "noinsetlayout", TC_NOINSETLAYOUT },
|
2012-10-27 13:45:27 +00:00
|
|
|
{ "nostyle", TC_NOSTYLE },
|
2015-11-03 16:47:25 +00:00
|
|
|
{ "outlinername", TC_OUTLINERNAME },
|
2012-10-27 13:45:27 +00:00
|
|
|
{ "outputformat", TC_OUTPUTFORMAT },
|
|
|
|
{ "outputtype", TC_OUTPUTTYPE },
|
2015-05-22 08:37:14 +00:00
|
|
|
{ "packageoptions", TC_PKGOPTS },
|
2012-10-27 13:45:27 +00:00
|
|
|
{ "pagestyle", TC_PAGESTYLE },
|
|
|
|
{ "preamble", TC_PREAMBLE },
|
|
|
|
{ "provides", TC_PROVIDES },
|
|
|
|
{ "providesmodule", TC_PROVIDESMODULE },
|
2015-12-04 02:06:28 +00:00
|
|
|
{ "providestyle", TC_PROVIDESTYLE },
|
2012-10-27 13:45:27 +00:00
|
|
|
{ "requires", TC_REQUIRES },
|
|
|
|
{ "rightmargin", TC_RIGHTMARGIN },
|
|
|
|
{ "secnumdepth", TC_SECNUMDEPTH },
|
|
|
|
{ "sides", TC_SIDES },
|
|
|
|
{ "style", TC_STYLE },
|
|
|
|
{ "titlelatexname", TC_TITLELATEXNAME },
|
|
|
|
{ "titlelatextype", TC_TITLELATEXTYPE },
|
|
|
|
{ "tocdepth", TC_TOCDEPTH }
|
|
|
|
};
|
2011-12-03 22:15:11 +00:00
|
|
|
|
2017-07-23 11:11:54 +00:00
|
|
|
} // namespace
|
2008-03-24 12:31:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::convertLayoutFormat(support::FileName const & filename, ReadType rt)
|
|
|
|
{
|
2010-07-18 11:52:12 +00:00
|
|
|
LYXERR(Debug::TCLASS, "Converting layout file to " << LAYOUT_FORMAT);
|
2014-06-09 11:05:50 +00:00
|
|
|
TempFile tmp("convertXXXXXX.layout");
|
|
|
|
FileName const tempfile = tmp.name();
|
2008-10-06 12:16:17 +00:00
|
|
|
bool success = layout2layout(filename, tempfile);
|
|
|
|
if (success)
|
2009-02-17 20:25:56 +00:00
|
|
|
success = readWithoutConv(tempfile, rt) == OK;
|
2008-10-06 12:16:17 +00:00
|
|
|
return success;
|
2008-03-24 12:31:07 +00:00
|
|
|
}
|
|
|
|
|
2009-02-17 20:25:56 +00:00
|
|
|
|
2011-05-08 00:54:17 +00:00
|
|
|
std::string TextClass::convert(std::string const & str)
|
|
|
|
{
|
2014-06-09 11:05:50 +00:00
|
|
|
TempFile tmp1("localXXXXXX.layout");
|
|
|
|
FileName const fn = tmp1.name();
|
2011-05-08 00:54:17 +00:00
|
|
|
ofstream os(fn.toFilesystemEncoding().c_str());
|
|
|
|
os << str;
|
|
|
|
os.close();
|
2014-06-09 11:05:50 +00:00
|
|
|
TempFile tmp2("convert_localXXXXXX.layout");
|
|
|
|
FileName const tempfile = tmp2.name();
|
2016-07-23 14:29:40 +00:00
|
|
|
bool success = layout2layout(fn, tempfile, LYXFILE_LAYOUT_FORMAT);
|
2011-05-08 00:54:17 +00:00
|
|
|
if (!success)
|
|
|
|
return "";
|
|
|
|
ifstream is(tempfile.toFilesystemEncoding().c_str());
|
|
|
|
string ret;
|
|
|
|
string tmp;
|
|
|
|
while (!is.eof()) {
|
|
|
|
getline(is, tmp);
|
|
|
|
ret += tmp + '\n';
|
|
|
|
}
|
|
|
|
is.close();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-17 20:25:56 +00:00
|
|
|
TextClass::ReturnValues TextClass::readWithoutConv(FileName const & filename, ReadType rt)
|
2008-03-24 12:31:07 +00:00
|
|
|
{
|
|
|
|
if (!filename.isReadableFile()) {
|
|
|
|
lyxerr << "Cannot read layout file `" << filename << "'."
|
|
|
|
<< endl;
|
2009-02-17 20:25:56 +00:00
|
|
|
return ERROR;
|
2008-03-24 12:31:07 +00:00
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2010-08-05 20:25:04 +00:00
|
|
|
LYXERR(Debug::TCLASS, "Reading " + translateReadType(rt) + ": " +
|
2010-04-21 01:19:09 +00:00
|
|
|
to_utf8(makeDisplayPath(filename.absFileName())));
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
// Define the plain layout used in table cells, ert, etc. Note that
|
|
|
|
// we do this before loading any layout file, so that classes can
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
// override features of this layout if they should choose to do so.
|
2008-08-01 21:03:45 +00:00
|
|
|
if (rt == BASECLASS && !hasLayout(plain_layout_))
|
2008-08-01 21:13:03 +00:00
|
|
|
layoutlist_.push_back(createBasicLayout(plain_layout_));
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2008-04-02 23:06:22 +00:00
|
|
|
Lexer lexrc(textClassTags);
|
2002-03-21 17:27:08 +00:00
|
|
|
lexrc.setFile(filename);
|
2008-03-24 12:31:07 +00:00
|
|
|
ReturnValues retval = read(lexrc, rt);
|
2011-12-03 22:15:11 +00:00
|
|
|
|
2010-08-05 20:25:04 +00:00
|
|
|
LYXERR(Debug::TCLASS, "Finished reading " + translateReadType(rt) + ": " +
|
2010-04-21 01:19:09 +00:00
|
|
|
to_utf8(makeDisplayPath(filename.absFileName())));
|
2009-02-17 20:25:56 +00:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::read(FileName const & filename, ReadType rt)
|
|
|
|
{
|
|
|
|
ReturnValues const retval = readWithoutConv(filename, rt);
|
|
|
|
if (retval != FORMAT_MISMATCH)
|
2008-03-24 12:31:07 +00:00
|
|
|
return retval == OK;
|
2009-02-17 20:25:56 +00:00
|
|
|
|
2008-03-24 12:31:07 +00:00
|
|
|
bool const worx = convertLayoutFormat(filename, rt);
|
2011-05-08 00:54:17 +00:00
|
|
|
if (!worx)
|
2011-12-03 22:15:11 +00:00
|
|
|
LYXERR0 ("Unable to convert " << filename <<
|
2010-07-18 11:52:12 +00:00
|
|
|
" to format " << LAYOUT_FORMAT);
|
2011-05-08 00:54:17 +00:00
|
|
|
return worx;
|
2008-03-24 12:31:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-08 00:54:17 +00:00
|
|
|
TextClass::ReturnValues TextClass::validate(std::string const & str)
|
2008-03-24 12:31:07 +00:00
|
|
|
{
|
|
|
|
TextClass tc;
|
|
|
|
return tc.read(str, VALIDATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-08 00:54:17 +00:00
|
|
|
TextClass::ReturnValues TextClass::read(std::string const & str, ReadType rt)
|
2008-03-24 12:31:07 +00:00
|
|
|
{
|
2008-04-02 23:06:22 +00:00
|
|
|
Lexer lexrc(textClassTags);
|
2008-03-24 12:31:07 +00:00
|
|
|
istringstream is(str);
|
|
|
|
lexrc.setStream(is);
|
|
|
|
ReturnValues retval = read(lexrc, rt);
|
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
if (retval != FORMAT_MISMATCH)
|
2011-05-08 00:54:17 +00:00
|
|
|
return retval;
|
2008-03-24 12:31:07 +00:00
|
|
|
|
|
|
|
// write the layout string to a temporary file
|
2014-06-09 11:05:50 +00:00
|
|
|
TempFile tmp("TextClass_read");
|
|
|
|
FileName const tempfile = tmp.name();
|
2008-03-24 12:31:07 +00:00
|
|
|
ofstream os(tempfile.toFilesystemEncoding().c_str());
|
|
|
|
if (!os) {
|
2008-07-23 09:41:26 +00:00
|
|
|
LYXERR0("Unable to create temporary file");
|
2011-05-08 00:54:17 +00:00
|
|
|
return ERROR;
|
2008-03-24 12:31:07 +00:00
|
|
|
}
|
|
|
|
os << str;
|
|
|
|
os.close();
|
|
|
|
|
2016-07-23 14:29:40 +00:00
|
|
|
// now try to convert it to LAYOUT_FORMAT
|
|
|
|
if (!convertLayoutFormat(tempfile, rt)) {
|
2011-12-03 22:15:11 +00:00
|
|
|
LYXERR0("Unable to convert internal layout information to format "
|
2010-07-18 11:52:12 +00:00
|
|
|
<< LAYOUT_FORMAT);
|
2011-05-08 00:54:17 +00:00
|
|
|
return ERROR;
|
2008-03-24 12:31:07 +00:00
|
|
|
}
|
2016-07-23 14:29:40 +00:00
|
|
|
|
2011-05-08 00:54:17 +00:00
|
|
|
return OK_OLDFORMAT;
|
2008-03-24 12:31:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Reads a textclass structure from file.
|
2011-12-03 22:15:11 +00:00
|
|
|
TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
|
2008-03-24 12:31:07 +00:00
|
|
|
{
|
2010-04-18 20:37:07 +00:00
|
|
|
if (!lexrc.isOK())
|
|
|
|
return ERROR;
|
2005-10-21 16:11:36 +00:00
|
|
|
|
2017-07-13 17:03:06 +00:00
|
|
|
// The first usable line should be
|
|
|
|
// Format LAYOUT_FORMAT
|
|
|
|
if (lexrc.lex() != TC_FORMAT || !lexrc.next()
|
|
|
|
|| lexrc.getInteger() != LAYOUT_FORMAT)
|
|
|
|
return FORMAT_MISMATCH;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
// parsing
|
2017-07-13 17:03:06 +00:00
|
|
|
bool error = false;
|
2001-12-28 13:26:54 +00:00
|
|
|
while (lexrc.isOK() && !error) {
|
|
|
|
int le = lexrc.lex();
|
2003-03-14 12:08:15 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
switch (le) {
|
2007-04-26 11:30:54 +00:00
|
|
|
case Lexer::LEX_FEOF:
|
2002-03-21 17:27:08 +00:00
|
|
|
continue;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2007-04-26 11:30:54 +00:00
|
|
|
case Lexer::LEX_UNDEF:
|
2001-12-28 13:26:54 +00:00
|
|
|
lexrc.printError("Unknown TextClass tag `$$Token'");
|
|
|
|
error = true;
|
2002-03-21 17:27:08 +00:00
|
|
|
continue;
|
2003-03-14 12:08:15 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
2003-03-14 12:08:15 +00:00
|
|
|
|
2009-08-12 14:50:01 +00:00
|
|
|
// used below to track whether we are in an IfStyle or IfCounter tag.
|
2015-12-04 02:06:28 +00:00
|
|
|
bool modifystyle = false;
|
|
|
|
bool providestyle = false;
|
|
|
|
bool ifcounter = false;
|
2009-08-12 14:50:01 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
switch (static_cast<TextClassTags>(le)) {
|
2003-03-14 12:08:15 +00:00
|
|
|
|
2005-10-21 16:11:36 +00:00
|
|
|
case TC_FORMAT:
|
2017-07-13 17:03:06 +00:00
|
|
|
lexrc.next();
|
|
|
|
lexrc.printError("Duplicate Format directive");
|
2005-10-21 16:11:36 +00:00
|
|
|
break;
|
|
|
|
|
2009-05-28 08:59:25 +00:00
|
|
|
case TC_OUTPUTFORMAT:
|
2017-09-01 08:27:12 +00:00
|
|
|
if (lexrc.next()) {
|
2009-05-28 08:59:25 +00:00
|
|
|
outputFormat_ = lexrc.getString();
|
2017-09-01 08:27:12 +00:00
|
|
|
has_output_format_ = true;
|
|
|
|
}
|
2009-05-28 08:59:25 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TC_OUTPUTTYPE:
|
2001-12-28 13:26:54 +00:00
|
|
|
readOutputType(lexrc);
|
2009-05-28 08:59:25 +00:00
|
|
|
switch(outputType_) {
|
|
|
|
case LATEX:
|
|
|
|
outputFormat_ = "latex";
|
|
|
|
break;
|
|
|
|
case DOCBOOK:
|
|
|
|
outputFormat_ = "docbook";
|
|
|
|
break;
|
|
|
|
case LITERATE:
|
|
|
|
outputFormat_ = "literate";
|
|
|
|
break;
|
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
case TC_INPUT: // Include file
|
2002-03-21 17:27:08 +00:00
|
|
|
if (lexrc.next()) {
|
Allow Input of local includes from local layout files
When including files, LyX always searches the user and the system
directory, in that order. This means that when using local layout
files broken down into multiple includes, the various includes should
be specified with a path relative to the user layouts directory
(typically ~/.lyx/layouts), making this very impractical.
This commit allows including local files by specifying their path
as explicitly relative to the main layout file position, i.e., by
specifying their path with either "./" or "../". If the main layout
is not loaded from a local file, the usual search order is used,
even if the path are explicitly relative. So, for system layouts,
both "Input ./name.inc" and "Input name.inc" are equivalent.
2017-03-01 08:19:18 +00:00
|
|
|
FileName tmp;
|
2006-10-04 16:22:38 +00:00
|
|
|
string const inc = lexrc.getString();
|
Allow Input of local includes from local layout files
When including files, LyX always searches the user and the system
directory, in that order. This means that when using local layout
files broken down into multiple includes, the various includes should
be specified with a path relative to the user layouts directory
(typically ~/.lyx/layouts), making this very impractical.
This commit allows including local files by specifying their path
as explicitly relative to the main layout file position, i.e., by
specifying their path with either "./" or "../". If the main layout
is not loaded from a local file, the usual search order is used,
even if the path are explicitly relative. So, for system layouts,
both "Input ./name.inc" and "Input name.inc" are equivalent.
2017-03-01 08:19:18 +00:00
|
|
|
if (!path().empty() && (prefixIs(inc, "./") ||
|
|
|
|
prefixIs(inc, "../")))
|
|
|
|
tmp = fileSearch(path(), inc, "layout");
|
|
|
|
else
|
|
|
|
tmp = libFileSearch("layouts", inc,
|
2001-12-28 13:26:54 +00:00
|
|
|
"layout");
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2006-10-04 16:22:38 +00:00
|
|
|
if (tmp.empty()) {
|
2008-02-03 00:32:02 +00:00
|
|
|
lexrc.printError("Could not find input file: " + inc);
|
2006-10-04 16:22:38 +00:00
|
|
|
error = true;
|
2008-02-14 03:38:08 +00:00
|
|
|
} else if (!read(tmp, MERGE)) {
|
2010-04-21 01:19:09 +00:00
|
|
|
lexrc.printError("Error reading input file: " + tmp.absFileName());
|
2001-12-28 13:26:54 +00:00
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-03-02 16:39:54 +00:00
|
|
|
case TC_DEFAULTSTYLE:
|
|
|
|
if (lexrc.next()) {
|
2007-07-11 13:39:08 +00:00
|
|
|
docstring const name = from_utf8(subst(lexrc.getString(),
|
|
|
|
'_', ' '));
|
2002-03-02 16:39:54 +00:00
|
|
|
defaultlayout_ = name;
|
|
|
|
}
|
|
|
|
break;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2015-12-04 02:06:28 +00:00
|
|
|
case TC_MODIFYSTYLE:
|
|
|
|
modifystyle = true;
|
|
|
|
// fall through
|
|
|
|
case TC_PROVIDESTYLE:
|
|
|
|
// if modifystyle is true, then we got here by falling through
|
|
|
|
// so we are not in an ProvideStyle block
|
|
|
|
if (!modifystyle)
|
|
|
|
providestyle = true;
|
|
|
|
// fall through
|
2008-12-16 16:01:32 +00:00
|
|
|
case TC_STYLE: {
|
|
|
|
if (!lexrc.next()) {
|
2001-12-28 13:26:54 +00:00
|
|
|
lexrc.printError("No name given for style: `$$Token'.");
|
|
|
|
error = true;
|
2008-12-16 16:01:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
docstring const name = from_utf8(subst(lexrc.getString(),
|
|
|
|
'_', ' '));
|
|
|
|
if (name.empty()) {
|
|
|
|
string s = "Could not read name for style: `$$Token' "
|
|
|
|
+ lexrc.getString() + " is probably not valid UTF-8!";
|
2010-04-18 21:06:38 +00:00
|
|
|
lexrc.printError(s);
|
2008-12-16 16:01:32 +00:00
|
|
|
Layout lay;
|
|
|
|
// Since we couldn't read the name, we just scan the rest
|
|
|
|
// of the style and discard it.
|
|
|
|
error = !readStyle(lexrc, lay);
|
2015-12-04 02:06:28 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2015-12-04 02:06:28 +00:00
|
|
|
bool const have_layout = hasLayout(name);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2015-12-04 02:06:28 +00:00
|
|
|
// If the layout already exists, then we want to add it to
|
|
|
|
// the existing layout, as long as we are not in an ProvideStyle
|
|
|
|
// block.
|
|
|
|
if (have_layout && !providestyle) {
|
2008-12-16 16:01:32 +00:00
|
|
|
Layout & lay = operator[](name);
|
|
|
|
error = !readStyle(lexrc, lay);
|
2015-12-04 02:06:28 +00:00
|
|
|
}
|
|
|
|
// If the layout does not exist, then we want to create a new
|
|
|
|
// one, but not if we are in a ModifyStyle block.
|
|
|
|
else if (!have_layout && !modifystyle) {
|
2008-12-16 16:01:32 +00:00
|
|
|
Layout layout;
|
|
|
|
layout.setName(name);
|
|
|
|
error = !readStyle(lexrc, layout);
|
|
|
|
if (!error)
|
|
|
|
layoutlist_.push_back(layout);
|
|
|
|
|
|
|
|
if (defaultlayout_.empty()) {
|
|
|
|
// We do not have a default layout yet, so we choose
|
|
|
|
// the first layout we encounter.
|
|
|
|
defaultlayout_ = name;
|
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
2015-12-04 02:06:28 +00:00
|
|
|
// There are two ways to get here:
|
|
|
|
// (i) The layout exists but we are in an ProvideStyle block
|
|
|
|
// (ii) The layout doesn't exist, but we are in an ModifyStyle
|
|
|
|
// block.
|
|
|
|
// Either way, we just scan the rest and discard it
|
2009-08-12 14:50:01 +00:00
|
|
|
else {
|
|
|
|
Layout lay;
|
2017-03-28 08:52:59 +00:00
|
|
|
// signal to coverity that we do not care about the result
|
|
|
|
(void)readStyle(lexrc, lay);
|
2009-08-12 14:50:01 +00:00
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2008-12-16 16:01:32 +00:00
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
case TC_NOSTYLE:
|
|
|
|
if (lexrc.next()) {
|
2007-07-11 13:39:08 +00:00
|
|
|
docstring const style = from_utf8(subst(lexrc.getString(),
|
|
|
|
'_', ' '));
|
2007-11-04 09:51:26 +00:00
|
|
|
if (!deleteLayout(style))
|
2002-11-27 10:30:28 +00:00
|
|
|
lyxerr << "Cannot delete style `"
|
2007-07-11 13:39:08 +00:00
|
|
|
<< to_utf8(style) << '\'' << endl;
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-02-09 19:31:26 +00:00
|
|
|
case TC_NOINSETLAYOUT:
|
|
|
|
if (lexrc.next()) {
|
|
|
|
docstring const style = from_utf8(subst(lexrc.getString(),
|
|
|
|
'_', ' '));
|
|
|
|
if (!deleteInsetLayout(style))
|
|
|
|
LYXERR0("Style `" << style << "' cannot be removed\n"
|
|
|
|
"because it was not found!");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
case TC_COLUMNS:
|
|
|
|
if (lexrc.next())
|
|
|
|
columns_ = lexrc.getInteger();
|
|
|
|
break;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
case TC_SIDES:
|
|
|
|
if (lexrc.next()) {
|
|
|
|
switch (lexrc.getInteger()) {
|
|
|
|
case 1: sides_ = OneSide; break;
|
|
|
|
case 2: sides_ = TwoSides; break;
|
|
|
|
default:
|
|
|
|
lyxerr << "Impossible number of page"
|
|
|
|
" sides, setting to one."
|
|
|
|
<< endl;
|
|
|
|
sides_ = OneSide;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
case TC_PAGESTYLE:
|
2002-03-21 17:27:08 +00:00
|
|
|
lexrc.next();
|
2002-07-28 22:50:13 +00:00
|
|
|
pagestyle_ = rtrim(lexrc.getString());
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
case TC_DEFAULTFONT:
|
2007-11-01 09:57:38 +00:00
|
|
|
defaultfont_ = lyxRead(lexrc);
|
2001-12-28 13:26:54 +00:00
|
|
|
if (!defaultfont_.resolved()) {
|
|
|
|
lexrc.printError("Warning: defaultfont should "
|
|
|
|
"be fully instantiated!");
|
2007-10-28 18:51:54 +00:00
|
|
|
defaultfont_.realize(sane_font);
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TC_SECNUMDEPTH:
|
|
|
|
lexrc.next();
|
|
|
|
secnumdepth_ = lexrc.getInteger();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TC_TOCDEPTH:
|
|
|
|
lexrc.next();
|
|
|
|
tocdepth_ = lexrc.getInteger();
|
|
|
|
break;
|
|
|
|
|
2008-02-14 03:38:08 +00:00
|
|
|
// First step to support options
|
2002-03-21 17:27:08 +00:00
|
|
|
case TC_CLASSOPTIONS:
|
2001-12-28 13:26:54 +00:00
|
|
|
readClassOptions(lexrc);
|
2002-03-21 17:27:08 +00:00
|
|
|
break;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
case TC_PREAMBLE:
|
2016-09-25 10:37:40 +00:00
|
|
|
preamble_ = lexrc.getLongString(from_ascii("EndPreamble"));
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
|
|
|
|
2009-06-05 17:26:30 +00:00
|
|
|
case TC_HTMLPREAMBLE:
|
2016-09-25 10:37:40 +00:00
|
|
|
htmlpreamble_ = lexrc.getLongString(from_ascii("EndPreamble"));
|
2009-06-05 17:26:30 +00:00
|
|
|
break;
|
2011-12-03 22:15:11 +00:00
|
|
|
|
2011-12-06 22:38:46 +00:00
|
|
|
case TC_HTMLSTYLES:
|
2016-09-25 10:37:40 +00:00
|
|
|
htmlstyles_ = lexrc.getLongString(from_ascii("EndStyles"));
|
2011-12-06 22:38:46 +00:00
|
|
|
break;
|
|
|
|
|
2010-01-12 19:38:31 +00:00
|
|
|
case TC_HTMLTOCSECTION:
|
|
|
|
html_toc_section_ = from_utf8(trim(lexrc.getString()));
|
|
|
|
break;
|
2009-06-05 17:26:30 +00:00
|
|
|
|
2008-03-24 13:11:16 +00:00
|
|
|
case TC_ADDTOPREAMBLE:
|
2016-09-25 10:37:40 +00:00
|
|
|
preamble_ += lexrc.getLongString(from_ascii("EndPreamble"));
|
2008-03-24 13:11:16 +00:00
|
|
|
break;
|
|
|
|
|
2009-06-19 12:49:08 +00:00
|
|
|
case TC_ADDTOHTMLPREAMBLE:
|
2016-09-25 10:37:40 +00:00
|
|
|
htmlpreamble_ += lexrc.getLongString(from_ascii("EndPreamble"));
|
2009-06-19 12:49:08 +00:00
|
|
|
break;
|
|
|
|
|
2011-12-06 22:38:46 +00:00
|
|
|
case TC_ADDTOHTMLSTYLES:
|
2016-09-25 10:37:40 +00:00
|
|
|
htmlstyles_ += lexrc.getLongString(from_ascii("EndStyles"));
|
2011-12-06 22:38:46 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-06 09:02:23 +00:00
|
|
|
case TC_PROVIDES: {
|
|
|
|
lexrc.next();
|
|
|
|
string const feature = lexrc.getString();
|
|
|
|
lexrc.next();
|
|
|
|
if (lexrc.getInteger())
|
|
|
|
provides_.insert(feature);
|
|
|
|
else
|
|
|
|
provides_.erase(feature);
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2007-04-06 09:02:23 +00:00
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2008-01-07 16:59:10 +00:00
|
|
|
case TC_REQUIRES: {
|
|
|
|
lexrc.eatLine();
|
2011-12-03 22:15:11 +00:00
|
|
|
vector<string> const req
|
2008-02-01 15:12:04 +00:00
|
|
|
= getVectorFromString(lexrc.getString());
|
|
|
|
requires_.insert(req.begin(), req.end());
|
2008-01-07 16:59:10 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-05-23 13:39:16 +00:00
|
|
|
|
2013-05-23 13:25:40 +00:00
|
|
|
case TC_PKGOPTS : {
|
|
|
|
lexrc.next();
|
|
|
|
string const pkg = lexrc.getString();
|
|
|
|
lexrc.next();
|
|
|
|
string const options = lexrc.getString();
|
|
|
|
package_options_[pkg] = options;
|
|
|
|
break;
|
|
|
|
}
|
2008-01-07 16:59:10 +00:00
|
|
|
|
2008-10-23 00:27:03 +00:00
|
|
|
case TC_DEFAULTMODULE: {
|
2008-07-25 15:51:27 +00:00
|
|
|
lexrc.next();
|
|
|
|
string const module = lexrc.getString();
|
2008-10-23 00:27:03 +00:00
|
|
|
if (find(default_modules_.begin(), default_modules_.end(), module) == default_modules_.end())
|
|
|
|
default_modules_.push_back(module);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case TC_PROVIDESMODULE: {
|
|
|
|
lexrc.next();
|
|
|
|
string const module = lexrc.getString();
|
|
|
|
if (find(provided_modules_.begin(), provided_modules_.end(), module) == provided_modules_.end())
|
|
|
|
provided_modules_.push_back(module);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case TC_EXCLUDESMODULE: {
|
|
|
|
lexrc.next();
|
|
|
|
string const module = lexrc.getString();
|
|
|
|
// modules already have their own way to exclude other modules
|
|
|
|
if (rt == MODULE) {
|
|
|
|
LYXERR0("ExcludesModule tag cannot be used in a module!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (find(excluded_modules_.begin(), excluded_modules_.end(), module) == excluded_modules_.end())
|
|
|
|
excluded_modules_.push_back(module);
|
2008-07-25 15:51:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
case TC_LEFTMARGIN: // left margin type
|
2002-03-21 17:27:08 +00:00
|
|
|
if (lexrc.next())
|
2007-08-18 13:21:12 +00:00
|
|
|
leftmargin_ = lexrc.getDocString();
|
2002-03-21 17:27:08 +00:00
|
|
|
break;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
case TC_RIGHTMARGIN: // right margin type
|
|
|
|
if (lexrc.next())
|
2007-08-18 13:21:12 +00:00
|
|
|
rightmargin_ = lexrc.getDocString();
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
2008-12-16 16:11:15 +00:00
|
|
|
case TC_INSETLAYOUT: {
|
|
|
|
if (!lexrc.next()) {
|
|
|
|
lexrc.printError("No name given for InsetLayout: `$$Token'.");
|
|
|
|
error = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
docstring const name = subst(lexrc.getDocString(), '_', ' ');
|
|
|
|
if (name.empty()) {
|
|
|
|
string s = "Could not read name for InsetLayout: `$$Token' "
|
|
|
|
+ lexrc.getString() + " is probably not valid UTF-8!";
|
2010-04-18 21:06:38 +00:00
|
|
|
lexrc.printError(s);
|
2008-02-22 03:27:42 +00:00
|
|
|
InsetLayout il;
|
2008-12-16 16:11:15 +00:00
|
|
|
// Since we couldn't read the name, we just scan the rest
|
|
|
|
// of the style and discard it.
|
|
|
|
il.read(lexrc, *this);
|
2010-04-18 21:06:38 +00:00
|
|
|
// Let's try to continue rather than abort.
|
|
|
|
// error = true;
|
2008-12-16 16:11:15 +00:00
|
|
|
} else if (hasInsetLayout(name)) {
|
|
|
|
InsetLayout & il = insetlayoutlist_[name];
|
|
|
|
error = !il.read(lexrc, *this);
|
|
|
|
} else {
|
2010-01-14 23:45:53 +00:00
|
|
|
InsetLayout il;
|
|
|
|
il.setName(name);
|
2008-12-16 16:11:15 +00:00
|
|
|
error = !il.read(lexrc, *this);
|
|
|
|
if (!error)
|
|
|
|
insetlayoutlist_[name] = il;
|
2007-08-13 12:13:17 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-12-16 16:11:15 +00:00
|
|
|
}
|
2008-02-14 03:38:08 +00:00
|
|
|
|
2002-09-04 06:52:26 +00:00
|
|
|
case TC_FLOAT:
|
2010-04-18 22:21:21 +00:00
|
|
|
error = !readFloat(lexrc);
|
2002-09-04 06:52:26 +00:00
|
|
|
break;
|
2011-12-03 22:15:11 +00:00
|
|
|
|
2012-03-01 00:41:30 +00:00
|
|
|
case TC_CITEENGINE:
|
|
|
|
error = !readCiteEngine(lexrc);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TC_CITEENGINETYPE:
|
|
|
|
if (lexrc.next())
|
|
|
|
opt_enginetype_ = rtrim(lexrc.getString());
|
|
|
|
break;
|
|
|
|
|
2010-03-29 18:37:25 +00:00
|
|
|
case TC_CITEFORMAT:
|
2012-03-01 00:41:30 +00:00
|
|
|
error = !readCiteFormat(lexrc);
|
|
|
|
break;
|
|
|
|
|
2016-12-31 18:44:32 +00:00
|
|
|
case TC_CITEFRAMEWORK:
|
|
|
|
lexrc.next();
|
|
|
|
citeframework_ = rtrim(lexrc.getString());
|
|
|
|
break;
|
|
|
|
|
2017-01-07 15:44:27 +00:00
|
|
|
case TC_MAXCITENAMES:
|
|
|
|
lexrc.next();
|
|
|
|
maxcitenames_ = size_t(lexrc.getInteger());
|
|
|
|
break;
|
|
|
|
|
2012-03-01 00:41:30 +00:00
|
|
|
case TC_DEFAULTBIBLIO:
|
2016-12-31 13:57:09 +00:00
|
|
|
if (lexrc.next()) {
|
|
|
|
vector<string> const dbs =
|
|
|
|
getVectorFromString(rtrim(lexrc.getString()), "|");
|
|
|
|
vector<string>::const_iterator it = dbs.begin();
|
|
|
|
vector<string>::const_iterator end = dbs.end();
|
|
|
|
for (; it != end; ++it) {
|
2017-01-04 16:11:25 +00:00
|
|
|
if (!contains(*it, ':')) {
|
|
|
|
vector<string> const enginetypes =
|
|
|
|
getVectorFromString(opt_enginetype_, "|");
|
|
|
|
for (string const &s: enginetypes)
|
|
|
|
cite_default_biblio_style_[s] = *it;
|
|
|
|
} else {
|
2016-12-31 13:57:09 +00:00
|
|
|
string eng;
|
|
|
|
string const db = split(*it, eng, ':');
|
|
|
|
cite_default_biblio_style_[eng] = db;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-01 00:41:30 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TC_FULLAUTHORLIST:
|
|
|
|
if (lexrc.next())
|
|
|
|
cite_full_author_list_ &= lexrc.getBool();
|
2010-03-29 18:37:25 +00:00
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
2011-01-12 22:53:41 +00:00
|
|
|
case TC_NOCOUNTER:
|
|
|
|
if (lexrc.next()) {
|
|
|
|
docstring const cnt = lexrc.getDocString();
|
|
|
|
if (!counters_.remove(cnt))
|
|
|
|
LYXERR0("Unable to remove counter: " + to_utf8(cnt));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2009-08-12 14:50:01 +00:00
|
|
|
case TC_IFCOUNTER:
|
|
|
|
ifcounter = true;
|
2015-09-12 20:19:59 +00:00
|
|
|
// fall through
|
2002-09-06 14:48:01 +00:00
|
|
|
case TC_COUNTER:
|
2008-10-06 14:37:28 +00:00
|
|
|
if (lexrc.next()) {
|
|
|
|
docstring const name = lexrc.getDocString();
|
|
|
|
if (name.empty()) {
|
|
|
|
string s = "Could not read name for counter: `$$Token' "
|
|
|
|
+ lexrc.getString() + " is probably not valid UTF-8!";
|
|
|
|
lexrc.printError(s.c_str());
|
|
|
|
Counter c;
|
|
|
|
// Since we couldn't read the name, we just scan the rest
|
|
|
|
// and discard it.
|
|
|
|
c.read(lexrc);
|
|
|
|
} else
|
2009-08-12 14:50:01 +00:00
|
|
|
error = !counters_.read(lexrc, name, !ifcounter);
|
2008-10-06 14:37:28 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
lexrc.printError("No name given for style: `$$Token'.");
|
|
|
|
error = true;
|
|
|
|
}
|
2002-09-06 14:48:01 +00:00
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
2003-02-13 17:49:09 +00:00
|
|
|
case TC_TITLELATEXTYPE:
|
|
|
|
readTitleType(lexrc);
|
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
2003-02-13 17:49:09 +00:00
|
|
|
case TC_TITLELATEXNAME:
|
|
|
|
if (lexrc.next())
|
|
|
|
titlename_ = lexrc.getString();
|
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
2002-09-11 07:39:55 +00:00
|
|
|
case TC_NOFLOAT:
|
|
|
|
if (lexrc.next()) {
|
|
|
|
string const nofloat = lexrc.getString();
|
2008-03-07 03:41:12 +00:00
|
|
|
floatlist_.erase(nofloat);
|
2002-09-11 07:39:55 +00:00
|
|
|
}
|
|
|
|
break;
|
2015-11-03 16:47:25 +00:00
|
|
|
|
|
|
|
case TC_OUTLINERNAME:
|
|
|
|
error = !readOutlinerName(lexrc);
|
|
|
|
break;
|
2008-10-06 12:16:17 +00:00
|
|
|
} // end of switch
|
2005-10-21 16:11:36 +00:00
|
|
|
}
|
|
|
|
|
2010-04-18 20:42:04 +00:00
|
|
|
// at present, we abort if we encounter an error,
|
|
|
|
// so there is no point continuing.
|
|
|
|
if (error)
|
|
|
|
return ERROR;
|
2008-02-05 16:20:18 +00:00
|
|
|
|
2010-04-18 20:42:04 +00:00
|
|
|
if (rt != BASECLASS)
|
2015-09-12 16:14:28 +00:00
|
|
|
return OK;
|
2008-02-05 22:57:33 +00:00
|
|
|
|
|
|
|
if (defaultlayout_.empty()) {
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0("Error: Textclass '" << name_
|
|
|
|
<< "' is missing a defaultstyle.");
|
2010-04-18 20:37:07 +00:00
|
|
|
return ERROR;
|
2008-02-05 22:57:33 +00:00
|
|
|
}
|
2011-12-03 22:15:11 +00:00
|
|
|
|
|
|
|
// Try to erase "stdinsets" from the provides_ set.
|
2008-04-03 21:36:57 +00:00
|
|
|
// The
|
|
|
|
// Provides stdinsets 1
|
|
|
|
// declaration simply tells us that the standard insets have been
|
|
|
|
// defined. (It's found in stdinsets.inc but could also be used in
|
|
|
|
// user-defined files.) There isn't really any such package. So we
|
|
|
|
// might as well go ahead and erase it.
|
|
|
|
// If we do not succeed, then it was not there, which means that
|
|
|
|
// the textclass did not provide the definitions of the standard
|
|
|
|
// insets. So we need to try to load them.
|
2008-02-05 22:57:33 +00:00
|
|
|
int erased = provides_.erase("stdinsets");
|
|
|
|
if (!erased) {
|
|
|
|
FileName tmp = libFileSearch("layouts", "stdinsets.inc");
|
|
|
|
|
|
|
|
if (tmp.empty()) {
|
2010-04-17 22:49:38 +00:00
|
|
|
frontend::Alert::warning(_("Missing File"),
|
2008-02-06 09:46:48 +00:00
|
|
|
_("Could not find stdinsets.inc! This may lead to data loss!"));
|
2008-02-05 22:57:33 +00:00
|
|
|
error = true;
|
2008-02-14 03:38:08 +00:00
|
|
|
} else if (!read(tmp, MERGE)) {
|
2010-04-17 22:49:38 +00:00
|
|
|
frontend::Alert::warning(_("Corrupt File"),
|
2008-02-14 03:38:08 +00:00
|
|
|
_("Could not read stdinsets.inc! This may lead to data loss!"));
|
2002-03-02 16:39:54 +00:00
|
|
|
error = true;
|
|
|
|
}
|
2008-02-05 22:57:33 +00:00
|
|
|
}
|
2005-05-12 10:16:04 +00:00
|
|
|
|
2008-02-05 22:57:33 +00:00
|
|
|
min_toclevel_ = Layout::NOT_IN_TOC;
|
|
|
|
max_toclevel_ = Layout::NOT_IN_TOC;
|
2008-03-06 20:01:30 +00:00
|
|
|
const_iterator lit = begin();
|
|
|
|
const_iterator len = end();
|
2008-03-06 05:59:21 +00:00
|
|
|
for (; lit != len; ++lit) {
|
2008-03-06 20:01:30 +00:00
|
|
|
int const toclevel = lit->toclevel;
|
2008-02-05 22:57:33 +00:00
|
|
|
if (toclevel != Layout::NOT_IN_TOC) {
|
|
|
|
if (min_toclevel_ == Layout::NOT_IN_TOC)
|
|
|
|
min_toclevel_ = toclevel;
|
|
|
|
else
|
2008-02-23 16:45:38 +00:00
|
|
|
min_toclevel_ = min(min_toclevel_, toclevel);
|
|
|
|
max_toclevel_ = max(max_toclevel_, toclevel);
|
2005-05-12 10:16:04 +00:00
|
|
|
}
|
This is one of a series of patches that will merge the layout modules development in personal/branches/rgheck back into the tree.
Design goal: Allow the use of layout "modules", which are to LaTeX packages as layout files are to LaTeX document classes. Thus, one could have a module that defined certain character styles, environments, commands, or what have you, and include it in various documents, each of which uses a different document class, without having to modify the layout files themselves. For example, a theorems.module could be used with article.layout to provide support for theorem-type environments, without having to modify article.layout itself, and the same module could be used with book.layout, etc.
This patch adds the backend. The ModuleList class holds a list of the available modules, which are retrieved from lyxmodules.lst, itself generated by configure.py. There are two LFUNs available: modules-clear and module-add, which do the obvious thing; you can test by typing these into the minibuffer, along with the name of one of the available modules: URL (a CharStyle), Endnote (a Custom Inset), and---with the spaces---End To Foot (View>LaTeX and look at the user preamble), which are themselves in lib/layouts. There are some others, too, that allow theorems to be added to classes like article and book.
The GUI will come next.
Issues: (i) The configure.py script could be improved. It'd be nice, for example, if it tested for the presence of the LaTeX packages a particular module needs. But this would mean re-working the LaTeX script, and I don't know how to do that. Note that at present, the packages are ignored. This will change shortly. (ii) I've used std::string in LyXModule, following what seemed to be a precedent in TextClass. If some of these should be docstrings, please let me know, and I'll change them. (iii) There is at present no distinction between LaTeX and DocBook modules. Should there be? That is: Should there be modules that are available when the document class is a LaTeX class and others that are available only when it is DocBook? Or should there just be one set of modules? Each module can of course indicate for what it is suitable in its description.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19893 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-29 17:59:49 +00:00
|
|
|
}
|
2008-02-05 22:57:33 +00:00
|
|
|
LYXERR(Debug::TCLASS, "Minimum TocLevel is " << min_toclevel_
|
|
|
|
<< ", maximum is " << max_toclevel_);
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2008-03-24 12:31:07 +00:00
|
|
|
return (error ? ERROR : OK);
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
void TextClass::readTitleType(Lexer & lexrc)
|
2003-02-13 17:49:09 +00:00
|
|
|
{
|
2008-04-02 23:06:22 +00:00
|
|
|
LexerKeyword titleTypeTags[] = {
|
2003-02-13 17:49:09 +00:00
|
|
|
{ "commandafter", TITLE_COMMAND_AFTER },
|
2008-04-03 20:55:09 +00:00
|
|
|
{ "environment", TITLE_ENVIRONMENT }
|
2003-02-13 17:49:09 +00:00
|
|
|
};
|
|
|
|
|
2008-04-03 20:55:09 +00:00
|
|
|
PushPopHelper pph(lexrc, titleTypeTags);
|
2003-02-13 17:49:09 +00:00
|
|
|
|
|
|
|
int le = lexrc.lex();
|
|
|
|
switch (le) {
|
2007-04-26 11:30:54 +00:00
|
|
|
case Lexer::LEX_UNDEF:
|
2003-02-13 17:49:09 +00:00
|
|
|
lexrc.printError("Unknown output type `$$Token'");
|
2008-04-03 21:36:57 +00:00
|
|
|
break;
|
2003-02-13 17:49:09 +00:00
|
|
|
case TITLE_COMMAND_AFTER:
|
|
|
|
case TITLE_ENVIRONMENT:
|
2007-09-29 20:02:32 +00:00
|
|
|
titletype_ = static_cast<TitleLatexType>(le);
|
2003-02-13 17:49:09 +00:00
|
|
|
break;
|
|
|
|
default:
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0("Unhandled value " << le << " in TextClass::readTitleType.");
|
2003-02-13 17:49:09 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
void TextClass::readOutputType(Lexer & lexrc)
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2008-04-02 23:06:22 +00:00
|
|
|
LexerKeyword outputTypeTags[] = {
|
2008-04-03 20:55:09 +00:00
|
|
|
{ "docbook", DOCBOOK },
|
|
|
|
{ "latex", LATEX },
|
2001-12-28 13:26:54 +00:00
|
|
|
{ "literate", LITERATE }
|
|
|
|
};
|
|
|
|
|
2008-04-03 20:55:09 +00:00
|
|
|
PushPopHelper pph(lexrc, outputTypeTags);
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
int le = lexrc.lex();
|
|
|
|
switch (le) {
|
2007-04-26 11:30:54 +00:00
|
|
|
case Lexer::LEX_UNDEF:
|
2001-12-28 13:26:54 +00:00
|
|
|
lexrc.printError("Unknown output type `$$Token'");
|
|
|
|
return;
|
|
|
|
case LATEX:
|
|
|
|
case DOCBOOK:
|
|
|
|
case LITERATE:
|
|
|
|
outputType_ = static_cast<OutputType>(le);
|
|
|
|
break;
|
|
|
|
default:
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0("Unhandled value " << le);
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
void TextClass::readClassOptions(Lexer & lexrc)
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2008-04-03 20:55:09 +00:00
|
|
|
enum {
|
|
|
|
CO_FONTSIZE = 1,
|
|
|
|
CO_PAGESTYLE,
|
|
|
|
CO_OTHER,
|
|
|
|
CO_HEADER,
|
|
|
|
CO_END
|
|
|
|
};
|
|
|
|
|
2008-04-02 23:06:22 +00:00
|
|
|
LexerKeyword classOptionsTags[] = {
|
2008-04-03 20:55:09 +00:00
|
|
|
{"end", CO_END },
|
|
|
|
{"fontsize", CO_FONTSIZE },
|
|
|
|
{"header", CO_HEADER },
|
|
|
|
{"other", CO_OTHER },
|
2001-12-28 13:26:54 +00:00
|
|
|
{"pagestyle", CO_PAGESTYLE }
|
|
|
|
};
|
|
|
|
|
2008-04-02 23:06:22 +00:00
|
|
|
lexrc.pushTable(classOptionsTags);
|
2001-12-28 13:26:54 +00:00
|
|
|
bool getout = false;
|
|
|
|
while (!getout && lexrc.isOK()) {
|
|
|
|
int le = lexrc.lex();
|
|
|
|
switch (le) {
|
2007-04-26 11:30:54 +00:00
|
|
|
case Lexer::LEX_UNDEF:
|
2001-12-28 13:26:54 +00:00
|
|
|
lexrc.printError("Unknown ClassOption tag `$$Token'");
|
2002-03-21 17:27:08 +00:00
|
|
|
continue;
|
2010-04-18 21:06:38 +00:00
|
|
|
default:
|
|
|
|
break;
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
2008-04-03 20:55:09 +00:00
|
|
|
switch (le) {
|
2001-12-28 13:26:54 +00:00
|
|
|
case CO_FONTSIZE:
|
|
|
|
lexrc.next();
|
2002-07-28 22:50:13 +00:00
|
|
|
opt_fontsize_ = rtrim(lexrc.getString());
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
|
|
|
case CO_PAGESTYLE:
|
|
|
|
lexrc.next();
|
2002-07-28 22:50:13 +00:00
|
|
|
opt_pagestyle_ = rtrim(lexrc.getString());
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
|
|
|
case CO_OTHER:
|
|
|
|
lexrc.next();
|
2010-04-01 21:34:22 +00:00
|
|
|
if (options_.empty())
|
|
|
|
options_ = lexrc.getString();
|
|
|
|
else
|
|
|
|
options_ += ',' + lexrc.getString();
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2003-11-27 16:57:12 +00:00
|
|
|
case CO_HEADER:
|
|
|
|
lexrc.next();
|
|
|
|
class_header_ = subst(lexrc.getString(), """, "\"");
|
|
|
|
break;
|
2001-12-28 13:26:54 +00:00
|
|
|
case CO_END:
|
|
|
|
getout = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lexrc.popTable();
|
|
|
|
}
|
|
|
|
|
2003-11-12 14:38:26 +00:00
|
|
|
|
2012-03-01 00:41:30 +00:00
|
|
|
bool TextClass::readCiteEngine(Lexer & lexrc)
|
|
|
|
{
|
|
|
|
int const type = readCiteEngineType(lexrc);
|
|
|
|
if (type & ENGINE_TYPE_AUTHORYEAR)
|
|
|
|
cite_styles_[ENGINE_TYPE_AUTHORYEAR].clear();
|
|
|
|
if (type & ENGINE_TYPE_NUMERICAL)
|
|
|
|
cite_styles_[ENGINE_TYPE_NUMERICAL].clear();
|
2013-05-16 14:00:54 +00:00
|
|
|
if (type & ENGINE_TYPE_DEFAULT)
|
|
|
|
cite_styles_[ENGINE_TYPE_DEFAULT].clear();
|
2012-03-01 00:41:30 +00:00
|
|
|
string def;
|
|
|
|
bool getout = false;
|
|
|
|
while (!getout && lexrc.isOK()) {
|
|
|
|
lexrc.eatLine();
|
|
|
|
def = lexrc.getString();
|
|
|
|
def = subst(def, " ", "");
|
|
|
|
def = subst(def, "\t", "");
|
|
|
|
if (compare_ascii_no_case(def, "end") == 0) {
|
|
|
|
getout = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
CitationStyle cs;
|
|
|
|
char ichar = def[0];
|
|
|
|
if (ichar == '#')
|
|
|
|
continue;
|
2017-01-03 09:17:09 +00:00
|
|
|
if (isUpperCase(ichar)) {
|
2012-03-01 00:41:30 +00:00
|
|
|
cs.forceUpperCase = true;
|
2017-01-03 09:17:09 +00:00
|
|
|
def[0] = lowercase(ichar);
|
2012-03-01 00:41:30 +00:00
|
|
|
}
|
|
|
|
|
2017-01-03 12:11:11 +00:00
|
|
|
/** For portability reasons (between different
|
|
|
|
* cite engines such as natbib and biblatex),
|
|
|
|
* we distinguish between:
|
|
|
|
* 1. The LyX name as output in the LyX file
|
|
|
|
* 2. Possible aliases that might fall back to
|
|
|
|
* the given LyX name in the current engine
|
|
|
|
* 3. The actual LaTeX command that is output
|
|
|
|
* (2) and (3) are optional.
|
2017-01-03 16:25:41 +00:00
|
|
|
* Also, the GUI string for the starred version can
|
|
|
|
* be changed
|
2017-01-03 12:11:11 +00:00
|
|
|
* The syntax is:
|
2017-01-03 16:25:41 +00:00
|
|
|
* LyXName|alias,nextalias*<!stardesc!stardesctooltip>[][]=latexcmd
|
2017-01-03 12:11:11 +00:00
|
|
|
*/
|
|
|
|
enum ScanMode {
|
|
|
|
LyXName,
|
|
|
|
Alias,
|
2017-01-03 16:25:41 +00:00
|
|
|
LaTeXCmd,
|
|
|
|
StarDesc
|
2017-01-03 12:11:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
ScanMode mode = LyXName;
|
2017-01-03 16:25:41 +00:00
|
|
|
ScanMode oldmode = LyXName;
|
2017-01-03 12:11:11 +00:00
|
|
|
string lyx_cmd;
|
|
|
|
string alias;
|
|
|
|
string latex_cmd;
|
2017-01-03 16:25:41 +00:00
|
|
|
string stardesc;
|
2012-03-01 00:41:30 +00:00
|
|
|
size_t const n = def.size();
|
|
|
|
for (size_t i = 0; i != n; ++i) {
|
|
|
|
ichar = def[i];
|
2017-01-03 12:11:11 +00:00
|
|
|
if (ichar == '|')
|
|
|
|
mode = Alias;
|
|
|
|
else if (ichar == '=')
|
|
|
|
mode = LaTeXCmd;
|
2017-01-03 16:25:41 +00:00
|
|
|
else if (ichar == '<') {
|
|
|
|
oldmode = mode;
|
|
|
|
mode = StarDesc;
|
|
|
|
} else if (ichar == '>')
|
|
|
|
mode = oldmode;
|
2017-01-03 12:11:11 +00:00
|
|
|
else if (mode == LaTeXCmd)
|
|
|
|
latex_cmd += ichar;
|
2017-01-03 16:25:41 +00:00
|
|
|
else if (mode == StarDesc)
|
|
|
|
stardesc += ichar;
|
Support for "qualified citation lists"
These are biblatex-specific multicite commands that allow for multiple
pre- and postnotes, as in:
\cites(pre)(post)[pre1][post1]{key1}[pre2][post2]{key2}...
with an optional general pre- and postnote, which applies to the whole
list (like [][] in normal cite commands) and an optional pre- and
postnotes for each item, so that pagination can actually be specified in
multi-cite references, as in:
(cf. Miller 2015, 2; furthermore Smith 2013, 23-23; Jenkins 2012, 103,
also refer to chapter 6 in this book)
See the biblatex manual, sec. 3.8.3., for details.
File format change.
2017-01-21 13:25:17 +00:00
|
|
|
else if (ichar == '$')
|
|
|
|
cs.hasQualifiedList = true;
|
2017-01-03 12:11:11 +00:00
|
|
|
else if (ichar == '*')
|
2017-01-03 16:25:41 +00:00
|
|
|
cs.hasStarredVersion = true;
|
2012-03-01 00:41:30 +00:00
|
|
|
else if (ichar == '[' && cs.textAfter)
|
|
|
|
cs.textBefore = true;
|
|
|
|
else if (ichar == '[')
|
|
|
|
cs.textAfter = true;
|
2017-01-03 12:11:11 +00:00
|
|
|
else if (ichar != ']') {
|
|
|
|
if (mode == Alias)
|
|
|
|
alias += ichar;
|
|
|
|
else
|
|
|
|
lyx_cmd += ichar;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cs.name = lyx_cmd;
|
|
|
|
cs.cmd = latex_cmd.empty() ? lyx_cmd : latex_cmd;
|
|
|
|
if (!alias.empty()) {
|
|
|
|
vector<string> const aliases = getVectorFromString(alias);
|
|
|
|
for (string const &s: aliases)
|
|
|
|
cite_command_aliases_[s] = lyx_cmd;
|
2012-03-01 00:41:30 +00:00
|
|
|
}
|
2017-01-03 16:25:41 +00:00
|
|
|
vector<string> const stardescs = getVectorFromString(stardesc, "!");
|
|
|
|
int size = stardesc.size();
|
|
|
|
if (size > 0)
|
|
|
|
cs.stardesc = stardescs[0];
|
|
|
|
if (size > 1)
|
|
|
|
cs.startooltip = stardescs[1];
|
2012-03-01 00:41:30 +00:00
|
|
|
if (type & ENGINE_TYPE_AUTHORYEAR)
|
|
|
|
cite_styles_[ENGINE_TYPE_AUTHORYEAR].push_back(cs);
|
|
|
|
if (type & ENGINE_TYPE_NUMERICAL)
|
|
|
|
cite_styles_[ENGINE_TYPE_NUMERICAL].push_back(cs);
|
2013-05-16 14:00:54 +00:00
|
|
|
if (type & ENGINE_TYPE_DEFAULT)
|
|
|
|
cite_styles_[ENGINE_TYPE_DEFAULT].push_back(cs);
|
2012-03-01 00:41:30 +00:00
|
|
|
}
|
|
|
|
return getout;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TextClass::readCiteEngineType(Lexer & lexrc) const
|
|
|
|
{
|
2013-05-16 14:00:54 +00:00
|
|
|
LATTEST(ENGINE_TYPE_DEFAULT ==
|
|
|
|
(ENGINE_TYPE_AUTHORYEAR | ENGINE_TYPE_NUMERICAL));
|
2012-03-01 00:41:30 +00:00
|
|
|
if (!lexrc.next()) {
|
|
|
|
lexrc.printError("No cite engine type given for token: `$$Token'.");
|
|
|
|
return ENGINE_TYPE_DEFAULT;
|
|
|
|
}
|
|
|
|
string const type = rtrim(lexrc.getString());
|
|
|
|
if (compare_ascii_no_case(type, "authoryear") == 0)
|
|
|
|
return ENGINE_TYPE_AUTHORYEAR;
|
|
|
|
else if (compare_ascii_no_case(type, "numerical") == 0)
|
|
|
|
return ENGINE_TYPE_NUMERICAL;
|
|
|
|
else if (compare_ascii_no_case(type, "default") != 0) {
|
|
|
|
string const s = "Unknown cite engine type `" + type
|
|
|
|
+ "' given for token: `$$Token',";
|
|
|
|
lexrc.printError(s);
|
|
|
|
}
|
|
|
|
return ENGINE_TYPE_DEFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::readCiteFormat(Lexer & lexrc)
|
2010-03-29 18:37:25 +00:00
|
|
|
{
|
2012-03-01 00:41:30 +00:00
|
|
|
int const type = readCiteEngineType(lexrc);
|
2010-03-29 18:37:25 +00:00
|
|
|
string etype;
|
|
|
|
string definition;
|
|
|
|
while (lexrc.isOK()) {
|
|
|
|
lexrc.next();
|
|
|
|
etype = lexrc.getString();
|
2012-03-01 00:41:30 +00:00
|
|
|
if (compare_ascii_no_case(etype, "end") == 0)
|
2010-03-29 18:37:25 +00:00
|
|
|
break;
|
2012-03-01 00:41:30 +00:00
|
|
|
if (!lexrc.isOK())
|
|
|
|
return false;
|
2010-03-29 18:37:25 +00:00
|
|
|
lexrc.eatLine();
|
|
|
|
definition = lexrc.getString();
|
2010-03-29 20:01:28 +00:00
|
|
|
char initchar = etype[0];
|
|
|
|
if (initchar == '#')
|
|
|
|
continue;
|
2018-01-27 13:26:36 +00:00
|
|
|
if (initchar == '!' || initchar == '_' || prefixIs(etype, "B_")) {
|
2012-03-01 00:41:30 +00:00
|
|
|
if (type & ENGINE_TYPE_AUTHORYEAR)
|
|
|
|
cite_macros_[ENGINE_TYPE_AUTHORYEAR][etype] = definition;
|
|
|
|
if (type & ENGINE_TYPE_NUMERICAL)
|
|
|
|
cite_macros_[ENGINE_TYPE_NUMERICAL][etype] = definition;
|
2013-05-16 14:00:54 +00:00
|
|
|
if (type & ENGINE_TYPE_DEFAULT)
|
|
|
|
cite_macros_[ENGINE_TYPE_DEFAULT][etype] = definition;
|
2012-03-01 00:41:30 +00:00
|
|
|
} else {
|
|
|
|
if (type & ENGINE_TYPE_AUTHORYEAR)
|
|
|
|
cite_formats_[ENGINE_TYPE_AUTHORYEAR][etype] = definition;
|
|
|
|
if (type & ENGINE_TYPE_NUMERICAL)
|
|
|
|
cite_formats_[ENGINE_TYPE_NUMERICAL][etype] = definition;
|
2013-05-16 14:00:54 +00:00
|
|
|
if (type & ENGINE_TYPE_DEFAULT)
|
|
|
|
cite_formats_[ENGINE_TYPE_DEFAULT][etype] = definition;
|
2012-03-01 00:41:30 +00:00
|
|
|
}
|
2010-03-29 18:37:25 +00:00
|
|
|
}
|
2012-03-01 00:41:30 +00:00
|
|
|
return true;
|
2010-03-29 18:37:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-18 21:06:38 +00:00
|
|
|
bool TextClass::readFloat(Lexer & lexrc)
|
2002-09-04 06:52:26 +00:00
|
|
|
{
|
2008-04-03 20:55:09 +00:00
|
|
|
enum {
|
|
|
|
FT_TYPE = 1,
|
|
|
|
FT_NAME,
|
|
|
|
FT_PLACEMENT,
|
|
|
|
FT_EXT,
|
|
|
|
FT_WITHIN,
|
|
|
|
FT_STYLE,
|
|
|
|
FT_LISTNAME,
|
2011-02-02 22:28:47 +00:00
|
|
|
FT_USESFLOAT,
|
|
|
|
FT_PREDEFINED,
|
2009-06-19 12:49:08 +00:00
|
|
|
FT_HTMLSTYLE,
|
2010-01-07 17:32:04 +00:00
|
|
|
FT_HTMLATTR,
|
2009-11-30 17:08:56 +00:00
|
|
|
FT_HTMLTAG,
|
2010-03-05 22:58:29 +00:00
|
|
|
FT_LISTCOMMAND,
|
2010-03-17 12:23:24 +00:00
|
|
|
FT_REFPREFIX,
|
2015-05-22 08:37:14 +00:00
|
|
|
FT_ALLOWED_PLACEMENT,
|
2015-05-22 16:59:17 +00:00
|
|
|
FT_ALLOWS_SIDEWAYS,
|
|
|
|
FT_ALLOWS_WIDE,
|
2008-04-03 20:55:09 +00:00
|
|
|
FT_END
|
|
|
|
};
|
|
|
|
|
2008-04-02 23:06:22 +00:00
|
|
|
LexerKeyword floatTags[] = {
|
2015-05-22 08:37:14 +00:00
|
|
|
{ "allowedplacement", FT_ALLOWED_PLACEMENT },
|
2015-05-22 16:59:17 +00:00
|
|
|
{ "allowssideways", FT_ALLOWS_SIDEWAYS },
|
|
|
|
{ "allowswide", FT_ALLOWS_WIDE },
|
2002-09-04 06:52:26 +00:00
|
|
|
{ "end", FT_END },
|
|
|
|
{ "extension", FT_EXT },
|
|
|
|
{ "guiname", FT_NAME },
|
2010-01-07 17:32:04 +00:00
|
|
|
{ "htmlattr", FT_HTMLATTR },
|
2009-06-19 12:49:08 +00:00
|
|
|
{ "htmlstyle", FT_HTMLSTYLE },
|
2009-11-30 17:08:56 +00:00
|
|
|
{ "htmltag", FT_HTMLTAG },
|
2011-02-02 22:28:47 +00:00
|
|
|
{ "ispredefined", FT_PREDEFINED },
|
2010-03-05 22:58:29 +00:00
|
|
|
{ "listcommand", FT_LISTCOMMAND },
|
2002-09-04 06:52:26 +00:00
|
|
|
{ "listname", FT_LISTNAME },
|
|
|
|
{ "numberwithin", FT_WITHIN },
|
|
|
|
{ "placement", FT_PLACEMENT },
|
2010-03-17 12:23:24 +00:00
|
|
|
{ "refprefix", FT_REFPREFIX },
|
2002-09-04 06:52:26 +00:00
|
|
|
{ "style", FT_STYLE },
|
2011-02-02 22:28:47 +00:00
|
|
|
{ "type", FT_TYPE },
|
|
|
|
{ "usesfloatpkg", FT_USESFLOAT }
|
2002-09-04 06:52:26 +00:00
|
|
|
};
|
|
|
|
|
2008-04-02 23:06:22 +00:00
|
|
|
lexrc.pushTable(floatTags);
|
2002-09-04 06:52:26 +00:00
|
|
|
|
|
|
|
string ext;
|
2010-01-07 17:32:04 +00:00
|
|
|
string htmlattr;
|
2016-09-25 10:37:40 +00:00
|
|
|
docstring htmlstyle;
|
2009-11-30 17:08:56 +00:00
|
|
|
string htmltag;
|
2010-03-17 12:23:24 +00:00
|
|
|
string listname;
|
|
|
|
string listcommand;
|
2009-06-19 12:49:08 +00:00
|
|
|
string name;
|
|
|
|
string placement;
|
2015-05-22 08:37:14 +00:00
|
|
|
string allowed_placement = "!htbpH";
|
2010-03-17 12:23:24 +00:00
|
|
|
string refprefix;
|
2009-06-19 12:49:08 +00:00
|
|
|
string style;
|
|
|
|
string type;
|
|
|
|
string within;
|
2011-02-02 22:15:52 +00:00
|
|
|
bool usesfloat = true;
|
2011-02-02 22:28:47 +00:00
|
|
|
bool ispredefined = false;
|
2015-05-22 16:59:17 +00:00
|
|
|
bool allowswide = true;
|
|
|
|
bool allowssideways = true;
|
2002-09-04 06:52:26 +00:00
|
|
|
|
|
|
|
bool getout = false;
|
|
|
|
while (!getout && lexrc.isOK()) {
|
|
|
|
int le = lexrc.lex();
|
|
|
|
switch (le) {
|
2007-04-26 11:30:54 +00:00
|
|
|
case Lexer::LEX_UNDEF:
|
2008-01-07 16:59:10 +00:00
|
|
|
lexrc.printError("Unknown float tag `$$Token'");
|
2002-09-04 06:52:26 +00:00
|
|
|
continue;
|
2010-04-18 21:06:38 +00:00
|
|
|
default:
|
|
|
|
break;
|
2002-09-04 06:52:26 +00:00
|
|
|
}
|
2008-04-03 20:55:09 +00:00
|
|
|
switch (le) {
|
2002-09-04 06:52:26 +00:00
|
|
|
case FT_TYPE:
|
|
|
|
lexrc.next();
|
|
|
|
type = lexrc.getString();
|
2008-03-07 03:41:12 +00:00
|
|
|
if (floatlist_.typeExist(type)) {
|
|
|
|
Floating const & fl = floatlist_.getType(type);
|
2007-08-16 11:07:00 +00:00
|
|
|
placement = fl.placement();
|
|
|
|
ext = fl.ext();
|
|
|
|
within = fl.within();
|
|
|
|
style = fl.style();
|
|
|
|
name = fl.name();
|
2010-03-17 12:23:24 +00:00
|
|
|
listname = fl.listName();
|
2011-02-02 22:15:52 +00:00
|
|
|
usesfloat = fl.usesFloatPkg();
|
2011-02-02 22:34:23 +00:00
|
|
|
ispredefined = fl.isPredefined();
|
2010-03-17 12:23:24 +00:00
|
|
|
listcommand = fl.listCommand();
|
|
|
|
refprefix = fl.refPrefix();
|
2011-12-03 22:15:11 +00:00
|
|
|
}
|
2002-09-04 06:52:26 +00:00
|
|
|
break;
|
|
|
|
case FT_NAME:
|
|
|
|
lexrc.next();
|
|
|
|
name = lexrc.getString();
|
|
|
|
break;
|
|
|
|
case FT_PLACEMENT:
|
|
|
|
lexrc.next();
|
|
|
|
placement = lexrc.getString();
|
|
|
|
break;
|
2015-05-22 08:37:14 +00:00
|
|
|
case FT_ALLOWED_PLACEMENT:
|
|
|
|
lexrc.next();
|
|
|
|
allowed_placement = lexrc.getString();
|
|
|
|
break;
|
2002-09-04 06:52:26 +00:00
|
|
|
case FT_EXT:
|
|
|
|
lexrc.next();
|
|
|
|
ext = lexrc.getString();
|
|
|
|
break;
|
|
|
|
case FT_WITHIN:
|
|
|
|
lexrc.next();
|
|
|
|
within = lexrc.getString();
|
|
|
|
if (within == "none")
|
|
|
|
within.erase();
|
|
|
|
break;
|
|
|
|
case FT_STYLE:
|
|
|
|
lexrc.next();
|
|
|
|
style = lexrc.getString();
|
|
|
|
break;
|
2010-03-05 22:58:29 +00:00
|
|
|
case FT_LISTCOMMAND:
|
|
|
|
lexrc.next();
|
2010-03-17 12:23:24 +00:00
|
|
|
listcommand = lexrc.getString();
|
|
|
|
break;
|
|
|
|
case FT_REFPREFIX:
|
|
|
|
lexrc.next();
|
|
|
|
refprefix = lexrc.getString();
|
2010-03-05 22:58:29 +00:00
|
|
|
break;
|
2002-09-04 06:52:26 +00:00
|
|
|
case FT_LISTNAME:
|
|
|
|
lexrc.next();
|
2010-03-17 12:23:24 +00:00
|
|
|
listname = lexrc.getString();
|
2002-09-04 06:52:26 +00:00
|
|
|
break;
|
2011-02-02 22:28:47 +00:00
|
|
|
case FT_USESFLOAT:
|
2002-09-04 06:52:26 +00:00
|
|
|
lexrc.next();
|
2011-02-02 22:15:52 +00:00
|
|
|
usesfloat = lexrc.getBool();
|
2002-09-04 06:52:26 +00:00
|
|
|
break;
|
2011-02-02 22:28:47 +00:00
|
|
|
case FT_PREDEFINED:
|
|
|
|
lexrc.next();
|
|
|
|
ispredefined = lexrc.getBool();
|
|
|
|
break;
|
2015-05-22 16:59:17 +00:00
|
|
|
case FT_ALLOWS_SIDEWAYS:
|
|
|
|
lexrc.next();
|
|
|
|
allowssideways = lexrc.getBool();
|
|
|
|
break;
|
|
|
|
case FT_ALLOWS_WIDE:
|
|
|
|
lexrc.next();
|
|
|
|
allowswide = lexrc.getBool();
|
|
|
|
break;
|
2010-01-07 17:32:04 +00:00
|
|
|
case FT_HTMLATTR:
|
2009-06-19 12:49:08 +00:00
|
|
|
lexrc.next();
|
2010-01-07 17:32:04 +00:00
|
|
|
htmlattr = lexrc.getString();
|
2009-06-19 12:49:08 +00:00
|
|
|
break;
|
|
|
|
case FT_HTMLSTYLE:
|
|
|
|
lexrc.next();
|
2016-09-25 10:37:40 +00:00
|
|
|
htmlstyle = lexrc.getLongString(from_ascii("EndHTMLStyle"));
|
2009-06-19 12:49:08 +00:00
|
|
|
break;
|
2009-11-30 17:08:56 +00:00
|
|
|
case FT_HTMLTAG:
|
2009-06-19 12:49:08 +00:00
|
|
|
lexrc.next();
|
2009-11-30 17:08:56 +00:00
|
|
|
htmltag = lexrc.getString();
|
2009-06-19 12:49:08 +00:00
|
|
|
break;
|
2002-09-04 06:52:26 +00:00
|
|
|
case FT_END:
|
|
|
|
getout = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-18 21:06:38 +00:00
|
|
|
lexrc.popTable();
|
|
|
|
|
2010-03-05 22:58:29 +00:00
|
|
|
// Here we have a full float if getout == true
|
2002-09-04 06:52:26 +00:00
|
|
|
if (getout) {
|
2011-02-02 22:15:52 +00:00
|
|
|
if (!usesfloat && listcommand.empty()) {
|
2011-02-02 17:32:59 +00:00
|
|
|
// if this float uses the same auxfile as an existing one,
|
|
|
|
// there is no need for it to provide a list command.
|
|
|
|
FloatList::const_iterator it = floatlist_.begin();
|
|
|
|
FloatList::const_iterator en = floatlist_.end();
|
|
|
|
bool found_ext = false;
|
|
|
|
for (; it != en; ++it) {
|
|
|
|
if (it->second.ext() == ext) {
|
|
|
|
found_ext = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found_ext)
|
|
|
|
LYXERR0("The layout does not provide a list command " <<
|
2011-02-02 22:15:52 +00:00
|
|
|
"for the float `" << type << "'. LyX will " <<
|
2011-02-02 17:32:59 +00:00
|
|
|
"not be able to produce a float list.");
|
|
|
|
}
|
2011-12-03 22:15:11 +00:00
|
|
|
Floating fl(type, placement, ext, within, style, name,
|
2015-05-22 16:59:17 +00:00
|
|
|
listname, listcommand, refprefix, allowed_placement,
|
|
|
|
htmltag, htmlattr, htmlstyle, usesfloat, ispredefined,
|
|
|
|
allowswide, allowssideways);
|
2008-03-07 03:41:12 +00:00
|
|
|
floatlist_.newFloat(fl);
|
2007-08-16 11:07:00 +00:00
|
|
|
// each float has its own counter
|
2008-03-07 03:41:12 +00:00
|
|
|
counters_.newCounter(from_ascii(type), from_ascii(within),
|
2007-08-16 15:26:00 +00:00
|
|
|
docstring(), docstring());
|
2008-03-02 11:30:50 +00:00
|
|
|
// also define sub-float counters
|
|
|
|
docstring const subtype = "sub-" + from_ascii(type);
|
2008-03-07 03:41:12 +00:00
|
|
|
counters_.newCounter(subtype, from_ascii(type),
|
2008-03-02 11:30:50 +00:00
|
|
|
"\\alph{" + subtype + "}", docstring());
|
2002-09-04 06:52:26 +00:00
|
|
|
}
|
2010-04-18 21:06:38 +00:00
|
|
|
return getout;
|
2002-09-04 06:52:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-03 16:47:25 +00:00
|
|
|
bool TextClass::readOutlinerName(Lexer & lexrc)
|
|
|
|
{
|
|
|
|
std::string type;
|
|
|
|
docstring name;
|
|
|
|
if (lexrc.next())
|
|
|
|
type = lexrc.getString();
|
|
|
|
else {
|
|
|
|
lexrc.printError("No type given for OutlinerName: `$$Token'.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (lexrc.next())
|
|
|
|
name = lexrc.getDocString();
|
|
|
|
else {
|
|
|
|
lexrc.printError("No name given for OutlinerName: `$$Token'.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
outliner_names_[type] = name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-09 05:17:36 +00:00
|
|
|
string const & TextClass::prerequisites(string const & sep) const
|
2011-12-03 22:15:11 +00:00
|
|
|
{
|
2010-03-25 00:44:15 +00:00
|
|
|
if (contains(prerequisites_, ',')) {
|
|
|
|
vector<string> const pres = getVectorFromString(prerequisites_);
|
2012-10-09 05:17:36 +00:00
|
|
|
prerequisites_ = getStringFromVector(pres, sep);
|
2010-03-25 00:44:15 +00:00
|
|
|
}
|
2011-12-03 22:15:11 +00:00
|
|
|
return prerequisites_;
|
2010-03-25 00:44:15 +00:00
|
|
|
}
|
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
|
2007-07-11 13:39:08 +00:00
|
|
|
bool TextClass::hasLayout(docstring const & n) const
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2007-07-11 13:39:08 +00:00
|
|
|
docstring const name = n.empty() ? defaultLayoutName() : n;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2002-08-27 15:51:19 +00:00
|
|
|
return find_if(layoutlist_.begin(), layoutlist_.end(),
|
2004-01-31 15:30:24 +00:00
|
|
|
LayoutNamesEqual(name))
|
2002-08-27 15:51:19 +00:00
|
|
|
!= layoutlist_.end();
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-16 16:11:15 +00:00
|
|
|
bool TextClass::hasInsetLayout(docstring const & n) const
|
|
|
|
{
|
2011-12-03 22:15:11 +00:00
|
|
|
if (n.empty())
|
2008-12-16 16:11:15 +00:00
|
|
|
return false;
|
2013-02-09 19:37:42 +00:00
|
|
|
InsetLayouts::const_iterator it = insetlayoutlist_.find(n);
|
|
|
|
return it != insetlayoutlist_.end();
|
2008-12-16 16:11:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
Layout const & TextClass::operator[](docstring const & name) const
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(!name.empty());
|
2002-03-12 18:11:49 +00:00
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
const_iterator it =
|
2008-03-06 20:01:30 +00:00
|
|
|
find_if(begin(), end(), LayoutNamesEqual(name));
|
2002-03-02 16:39:54 +00:00
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
if (it == end()) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LYXERR0("We failed to find the layout '" << name
|
|
|
|
<< "' in the layout list. You MUST investigate!");
|
2008-03-06 20:01:30 +00:00
|
|
|
for (const_iterator cit = begin(); cit != end(); ++cit)
|
|
|
|
lyxerr << " " << to_utf8(cit->name()) << endl;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2013-04-25 21:27:10 +00:00
|
|
|
// We require the name to exist
|
|
|
|
static const Layout dummy;
|
|
|
|
LASSERT(false, return dummy);
|
2002-03-02 16:39:54 +00:00
|
|
|
}
|
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Layout & TextClass::operator[](docstring const & name)
|
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(!name.empty());
|
|
|
|
// Safe to continue, given what we do below.
|
2008-03-06 20:01:30 +00:00
|
|
|
|
|
|
|
iterator it = find_if(begin(), end(), LayoutNamesEqual(name));
|
|
|
|
|
|
|
|
if (it == end()) {
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0("We failed to find the layout '" << to_utf8(name)
|
|
|
|
<< "' in the layout list. You MUST investigate!");
|
2008-03-06 20:01:30 +00:00
|
|
|
for (const_iterator cit = begin(); cit != end(); ++cit)
|
2008-04-03 21:36:57 +00:00
|
|
|
LYXERR0(" " << to_utf8(cit->name()));
|
2008-03-06 20:01:30 +00:00
|
|
|
|
|
|
|
// we require the name to exist
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(false);
|
|
|
|
// we are here only in release mode
|
|
|
|
layoutlist_.push_back(createBasicLayout(name, true));
|
|
|
|
it = find_if(begin(), end(), LayoutNamesEqual(name));
|
2008-03-06 20:01:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return *it;
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-04 09:51:26 +00:00
|
|
|
bool TextClass::deleteLayout(docstring const & name)
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2008-08-01 20:57:27 +00:00
|
|
|
if (name == defaultLayoutName() || name == plainLayoutName())
|
2002-03-02 16:39:54 +00:00
|
|
|
return false;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
LayoutList::iterator it =
|
2002-08-27 15:51:19 +00:00
|
|
|
remove_if(layoutlist_.begin(), layoutlist_.end(),
|
2004-01-31 15:30:24 +00:00
|
|
|
LayoutNamesEqual(name));
|
2002-06-24 20:28:12 +00:00
|
|
|
|
2002-08-27 15:51:19 +00:00
|
|
|
LayoutList::iterator end = layoutlist_.end();
|
2001-12-28 13:26:54 +00:00
|
|
|
bool const ret = (it != end);
|
2002-08-27 15:51:19 +00:00
|
|
|
layoutlist_.erase(it, end);
|
2001-12-28 13:26:54 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-09 19:31:26 +00:00
|
|
|
bool TextClass::deleteInsetLayout(docstring const & name)
|
|
|
|
{
|
|
|
|
return insetlayoutlist_.erase(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
// Load textclass info if not loaded yet
|
2007-04-29 19:53:54 +00:00
|
|
|
bool TextClass::load(string const & path) const
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
2004-03-30 16:19:50 +00:00
|
|
|
if (loaded_)
|
2002-03-02 16:39:54 +00:00
|
|
|
return true;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2006-05-04 02:38:11 +00:00
|
|
|
// Read style-file, provided path is searched before the system ones
|
2008-07-11 02:43:02 +00:00
|
|
|
// If path is a file, it is loaded directly.
|
|
|
|
FileName layout_file(path);
|
|
|
|
if (!path.empty() && !layout_file.isReadableFile())
|
2006-11-26 21:30:39 +00:00
|
|
|
layout_file = FileName(addName(path, name_ + ".layout"));
|
2007-10-18 19:29:32 +00:00
|
|
|
if (layout_file.empty() || !layout_file.exists())
|
2006-05-04 02:38:11 +00:00
|
|
|
layout_file = libFileSearch("layouts", name_, "layout");
|
2008-02-14 03:38:08 +00:00
|
|
|
loaded_ = const_cast<TextClass*>(this)->read(layout_file);
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2004-03-31 09:44:40 +00:00
|
|
|
if (!loaded_) {
|
2001-12-28 13:26:54 +00:00
|
|
|
lyxerr << "Error reading `"
|
2010-04-21 01:19:09 +00:00
|
|
|
<< to_utf8(makeDisplayPath(layout_file.absFileName()))
|
2001-12-28 13:26:54 +00:00
|
|
|
<< "'\n(Check `" << name_
|
|
|
|
<< "')\nCheck your installation and "
|
2011-12-03 22:15:11 +00:00
|
|
|
"try Options/Reconfigure..."
|
2010-04-07 13:25:44 +00:00
|
|
|
<< endl;
|
2001-12-28 13:26:54 +00:00
|
|
|
}
|
2004-03-31 09:44:40 +00:00
|
|
|
|
2004-03-30 16:19:50 +00:00
|
|
|
return loaded_;
|
2002-03-02 16:39:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-08 00:12:57 +00:00
|
|
|
bool DocumentClass::addLayoutIfNeeded(docstring const & n) const
|
2008-07-15 17:51:57 +00:00
|
|
|
{
|
2011-06-08 00:12:57 +00:00
|
|
|
if (hasLayout(n))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
layoutlist_.push_back(createBasicLayout(n, true));
|
|
|
|
return true;
|
2008-07-15 17:51:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-15 05:19:49 +00:00
|
|
|
string DocumentClass::forcedLayouts() const
|
|
|
|
{
|
|
|
|
ostringstream os;
|
|
|
|
bool first = true;
|
|
|
|
const_iterator const e = end();
|
|
|
|
for (const_iterator i = begin(); i != e; ++i) {
|
|
|
|
if (i->forcelocal > 0) {
|
|
|
|
if (first) {
|
|
|
|
os << "Format " << LAYOUT_FORMAT << '\n';
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
i->write(os);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return os.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
InsetLayout const & DocumentClass::insetLayout(docstring const & name) const
|
2007-08-13 12:13:17 +00:00
|
|
|
{
|
2008-07-15 18:09:44 +00:00
|
|
|
// FIXME The fix for the InsetLayout part of 4812 would be here:
|
|
|
|
// Add the InsetLayout to the document class if it is not found.
|
2007-08-17 15:38:58 +00:00
|
|
|
docstring n = name;
|
2008-03-07 03:41:12 +00:00
|
|
|
InsetLayouts::const_iterator cen = insetlayoutlist_.end();
|
2007-08-17 15:38:58 +00:00
|
|
|
while (!n.empty()) {
|
2008-03-07 03:41:12 +00:00
|
|
|
InsetLayouts::const_iterator cit = insetlayoutlist_.lower_bound(n);
|
2014-12-08 08:06:41 +00:00
|
|
|
if (cit != cen && cit->first == n) {
|
|
|
|
if (cit->second.obsoleted_by().empty())
|
|
|
|
return cit->second;
|
|
|
|
n = cit->second.obsoleted_by();
|
|
|
|
return insetLayout(n);
|
|
|
|
}
|
|
|
|
// If we have a generic prefix (e.g., "Note:"),
|
|
|
|
// try if this one alone is found.
|
2008-02-23 16:45:38 +00:00
|
|
|
size_t i = n.find(':');
|
2007-08-17 15:38:58 +00:00
|
|
|
if (i == string::npos)
|
|
|
|
break;
|
2008-09-08 01:18:33 +00:00
|
|
|
n = n.substr(0, i);
|
2007-08-17 15:38:58 +00:00
|
|
|
}
|
2014-12-08 08:06:41 +00:00
|
|
|
// Layout "name" not found.
|
2016-03-27 20:54:46 +00:00
|
|
|
return plainInsetLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
InsetLayout const & DocumentClass::plainInsetLayout() {
|
2016-03-28 16:39:55 +00:00
|
|
|
static const InsetLayout plain_insetlayout_;
|
2008-08-01 21:13:03 +00:00
|
|
|
return plain_insetlayout_;
|
2007-08-13 12:13:17 +00:00
|
|
|
}
|
|
|
|
|
2002-09-06 14:48:01 +00:00
|
|
|
|
2007-07-11 13:39:08 +00:00
|
|
|
docstring const & TextClass::defaultLayoutName() const
|
2002-03-02 16:39:54 +00:00
|
|
|
{
|
|
|
|
return defaultlayout_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
Layout const & TextClass::defaultLayout() const
|
2002-03-02 16:39:54 +00:00
|
|
|
{
|
|
|
|
return operator[](defaultLayoutName());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
bool TextClass::isDefaultLayout(Layout const & layout) const
|
2008-03-06 20:01:30 +00:00
|
|
|
{
|
2008-04-16 21:23:45 +00:00
|
|
|
return layout.name() == defaultLayoutName();
|
2008-03-06 20:01:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-03 22:15:11 +00:00
|
|
|
bool TextClass::isPlainLayout(Layout const & layout) const
|
2008-03-06 20:01:30 +00:00
|
|
|
{
|
2008-08-01 20:57:27 +00:00
|
|
|
return layout.name() == plainLayoutName();
|
2008-03-06 20:01:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-01 21:13:03 +00:00
|
|
|
Layout TextClass::createBasicLayout(docstring const & name, bool unknown) const
|
2008-07-11 02:43:02 +00:00
|
|
|
{
|
|
|
|
static Layout * defaultLayout = NULL;
|
|
|
|
|
|
|
|
if (defaultLayout) {
|
|
|
|
defaultLayout->setUnknown(unknown);
|
|
|
|
defaultLayout->setName(name);
|
|
|
|
return *defaultLayout;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char const * s = "Margin Static\n"
|
|
|
|
"LatexType Paragraph\n"
|
|
|
|
"LatexName dummy\n"
|
|
|
|
"Align Block\n"
|
|
|
|
"AlignPossible Left, Right, Center\n"
|
|
|
|
"LabelType No_Label\n"
|
|
|
|
"End";
|
|
|
|
istringstream ss(s);
|
|
|
|
Lexer lex(textClassTags);
|
|
|
|
lex.setStream(ss);
|
|
|
|
defaultLayout = new Layout;
|
|
|
|
defaultLayout->setUnknown(unknown);
|
|
|
|
defaultLayout->setName(name);
|
|
|
|
if (!readStyle(lex, *defaultLayout)) {
|
|
|
|
// The only way this happens is because the hardcoded layout above
|
|
|
|
// is wrong.
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(false);
|
2008-07-11 02:43:02 +00:00
|
|
|
};
|
|
|
|
return *defaultLayout;
|
|
|
|
}
|
|
|
|
|
2010-01-12 19:38:31 +00:00
|
|
|
|
2012-03-13 16:13:31 +00:00
|
|
|
DocumentClassPtr getDocumentClass(
|
2014-02-09 10:15:57 +00:00
|
|
|
LayoutFile const & baseClass, LayoutModuleList const & modlist,
|
2016-12-30 15:22:08 +00:00
|
|
|
LayoutModuleList const & celist,
|
2014-02-09 10:15:57 +00:00
|
|
|
bool const clone)
|
2009-02-11 23:22:10 +00:00
|
|
|
{
|
2012-03-13 16:13:31 +00:00
|
|
|
DocumentClassPtr doc_class =
|
|
|
|
DocumentClassPtr(new DocumentClass(baseClass));
|
2009-02-11 23:22:10 +00:00
|
|
|
LayoutModuleList::const_iterator it = modlist.begin();
|
|
|
|
LayoutModuleList::const_iterator en = modlist.end();
|
2012-05-28 20:41:32 +00:00
|
|
|
for (; it != en; ++it) {
|
2009-02-11 23:22:10 +00:00
|
|
|
string const modName = *it;
|
2009-08-14 15:37:34 +00:00
|
|
|
LyXModule * lm = theModuleList[modName];
|
2009-02-11 23:22:10 +00:00
|
|
|
if (!lm) {
|
|
|
|
docstring const msg =
|
|
|
|
bformat(_("The module %1$s has been requested by\n"
|
|
|
|
"this document but has not been found in the list of\n"
|
|
|
|
"available modules. If you recently installed it, you\n"
|
|
|
|
"probably need to reconfigure LyX.\n"), from_utf8(modName));
|
2014-02-09 10:15:57 +00:00
|
|
|
if (!clone)
|
|
|
|
frontend::Alert::warning(_("Module not available"), msg);
|
2009-02-11 23:22:10 +00:00
|
|
|
continue;
|
|
|
|
}
|
2014-02-09 10:15:57 +00:00
|
|
|
if (!lm->isAvailable() && !clone) {
|
2011-01-13 21:19:14 +00:00
|
|
|
docstring const prereqs = from_utf8(getStringFromVector(lm->prerequisites(), "\n\t"));
|
2009-02-11 23:22:10 +00:00
|
|
|
docstring const msg =
|
2011-01-13 21:19:14 +00:00
|
|
|
bformat(_("The module %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"
|
2011-01-21 13:08:21 +00:00
|
|
|
"See section 3.1.2.3 (Modules) of the User's Guide for more information."),
|
2011-01-13 21:19:14 +00:00
|
|
|
from_utf8(modName), prereqs);
|
2011-01-13 21:31:14 +00:00
|
|
|
frontend::Alert::warning(_("Package not available"), msg, true);
|
2009-02-11 23:22:10 +00:00
|
|
|
}
|
|
|
|
FileName layout_file = libFileSearch("layouts", lm->getFilename());
|
2012-03-13 16:13:31 +00:00
|
|
|
if (!doc_class->read(layout_file, TextClass::MODULE)) {
|
2009-02-11 23:22:10 +00:00
|
|
|
docstring const msg =
|
|
|
|
bformat(_("Error reading module %1$s\n"), from_utf8(modName));
|
2010-04-17 22:36:31 +00:00
|
|
|
frontend::Alert::warning(_("Read Error"), msg);
|
2009-02-11 23:22:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-30 15:22:08 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-11 23:22:10 +00:00
|
|
|
return doc_class;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-16 21:23:45 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// DocumentClass
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required.
At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do.
There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-29 02:45:33 +00:00
|
|
|
DocumentClass::DocumentClass(LayoutFile const & tc)
|
2008-02-28 01:42:02 +00:00
|
|
|
: TextClass(tc)
|
|
|
|
{}
|
2008-02-25 19:31:31 +00:00
|
|
|
|
|
|
|
|
2008-02-28 21:25:57 +00:00
|
|
|
bool DocumentClass::hasLaTeXLayout(std::string const & lay) const
|
|
|
|
{
|
|
|
|
LayoutList::const_iterator it = layoutlist_.begin();
|
|
|
|
LayoutList::const_iterator end = layoutlist_.end();
|
|
|
|
for (; it != end; ++it)
|
2008-03-06 20:01:30 +00:00
|
|
|
if (it->latexname() == lay)
|
2008-02-28 21:25:57 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required.
At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do.
There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-29 02:45:33 +00:00
|
|
|
bool DocumentClass::provides(string const & p) const
|
|
|
|
{
|
|
|
|
return provides_.find(p) != provides_.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DocumentClass::hasTocLevels() const
|
|
|
|
{
|
|
|
|
return min_toclevel_ != Layout::NOT_IN_TOC;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-21 18:14:12 +00:00
|
|
|
Layout const & DocumentClass::getTOCLayout() const
|
|
|
|
{
|
|
|
|
// we're going to look for the layout with the minimum toclevel
|
|
|
|
TextClass::LayoutList::const_iterator lit = begin();
|
|
|
|
TextClass::LayoutList::const_iterator const len = end();
|
|
|
|
int minlevel = 1000;
|
|
|
|
Layout const * lay = NULL;
|
|
|
|
for (; lit != len; ++lit) {
|
|
|
|
int const level = lit->toclevel;
|
2013-05-03 21:48:48 +00:00
|
|
|
// we don't want Part or unnumbered sections
|
2017-07-03 17:53:14 +00:00
|
|
|
if (level == Layout::NOT_IN_TOC || level < 0
|
2013-05-03 21:48:48 +00:00
|
|
|
|| level >= minlevel || lit->counter.empty())
|
2012-07-21 18:14:12 +00:00
|
|
|
continue;
|
|
|
|
lay = &*lit;
|
|
|
|
minlevel = level;
|
|
|
|
}
|
|
|
|
if (lay)
|
|
|
|
return *lay;
|
|
|
|
// hmm. that is very odd, so we'll do our best.
|
|
|
|
return operator[](defaultLayoutName());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-12 19:38:31 +00:00
|
|
|
Layout const & DocumentClass::htmlTOCLayout() const
|
|
|
|
{
|
2012-10-27 13:45:27 +00:00
|
|
|
if (html_toc_section_.empty())
|
2012-07-21 18:14:12 +00:00
|
|
|
html_toc_section_ = getTOCLayout().name();
|
2010-01-12 19:38:31 +00:00
|
|
|
return operator[](html_toc_section_);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-07 16:55:38 +00:00
|
|
|
string const DocumentClass::getCiteFormat(CiteEngineType const & type,
|
|
|
|
string const & entry, bool const punct, string const & fallback) const
|
2010-03-29 18:37:25 +00:00
|
|
|
{
|
2017-01-09 16:54:56 +00:00
|
|
|
string default_format = "{%fullnames:author%[[%fullnames:author%, ]][[{%fullnames:editor%[[%fullnames:editor%, ed., ]]}]]}\"%title%\"{%journal%[[, {!<i>!}%journal%{!</i>!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}";
|
2017-01-07 16:55:38 +00:00
|
|
|
if (punct)
|
|
|
|
default_format += ".";
|
2011-12-03 22:15:11 +00:00
|
|
|
|
2012-03-01 00:41:30 +00:00
|
|
|
map<CiteEngineType, map<string, string> >::const_iterator itype = cite_formats_.find(type);
|
|
|
|
if (itype == cite_formats_.end())
|
|
|
|
return default_format;
|
|
|
|
map<string, string>::const_iterator it = itype->second.find(entry);
|
|
|
|
if (it == itype->second.end() && !fallback.empty())
|
|
|
|
it = itype->second.find(fallback);
|
|
|
|
if (it == itype->second.end())
|
|
|
|
return default_format;
|
2017-01-07 16:55:38 +00:00
|
|
|
if (punct)
|
|
|
|
return it->second + ".";
|
2012-03-01 00:41:30 +00:00
|
|
|
return it->second;
|
2010-03-29 18:37:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-01 00:41:30 +00:00
|
|
|
string const & DocumentClass::getCiteMacro(CiteEngineType const & type,
|
|
|
|
string const & macro) const
|
2010-03-29 20:01:28 +00:00
|
|
|
{
|
|
|
|
static string empty;
|
2012-03-01 00:41:30 +00:00
|
|
|
map<CiteEngineType, map<string, string> >::const_iterator itype = cite_macros_.find(type);
|
|
|
|
if (itype == cite_macros_.end())
|
|
|
|
return empty;
|
|
|
|
map<string, string>::const_iterator it = itype->second.find(macro);
|
|
|
|
if (it == itype->second.end())
|
|
|
|
return empty;
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<string> const DocumentClass::citeCommands(
|
|
|
|
CiteEngineType const & type) const
|
|
|
|
{
|
|
|
|
vector<CitationStyle> const styles = citeStyles(type);
|
|
|
|
vector<CitationStyle>::const_iterator it = styles.begin();
|
|
|
|
vector<CitationStyle>::const_iterator end = styles.end();
|
|
|
|
vector<string> cmds;
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
CitationStyle const cite = *it;
|
2017-01-03 12:11:11 +00:00
|
|
|
cmds.push_back(cite.name);
|
2012-03-01 00:41:30 +00:00
|
|
|
}
|
|
|
|
return cmds;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<CitationStyle> const & DocumentClass::citeStyles(
|
|
|
|
CiteEngineType const & type) const
|
|
|
|
{
|
|
|
|
static vector<CitationStyle> empty;
|
|
|
|
map<CiteEngineType, vector<CitationStyle> >::const_iterator it = cite_styles_.find(type);
|
|
|
|
if (it == cite_styles_.end())
|
|
|
|
return empty;
|
|
|
|
return it->second;
|
2010-03-29 20:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-16 21:23:45 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// PageSides
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2007-11-07 23:25:08 +00:00
|
|
|
ostream & operator<<(ostream & os, PageSides p)
|
2001-12-28 13:26:54 +00:00
|
|
|
{
|
|
|
|
switch (p) {
|
2007-11-07 23:25:08 +00:00
|
|
|
case OneSide:
|
2002-11-27 10:30:28 +00:00
|
|
|
os << '1';
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
2007-11-07 23:25:08 +00:00
|
|
|
case TwoSides:
|
2002-11-27 10:30:28 +00:00
|
|
|
os << '2';
|
2001-12-28 13:26:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return os;
|
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
} // namespace lyx
|