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
|
|
|
|
*
|
2003-08-22 09:44:59 +00:00
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
* \author Jean-Marc Lasgouttes
|
2003-08-23 00:17:00 +00:00
|
|
|
|
* \author Angus Leeming
|
|
|
|
|
* \author John Levon
|
2003-08-22 09:44:59 +00:00
|
|
|
|
* \author Andr<EFBFBD> P<EFBFBD>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"
|
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"
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
2007-07-11 13:39:08 +00:00
|
|
|
|
#include "frontends/alert.h"
|
|
|
|
|
|
2008-02-18 07:14:42 +00:00
|
|
|
|
#include "support/debug.h"
|
2008-02-06 09:46:48 +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"
|
|
|
|
|
|
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>
|
|
|
|
|
|
2008-03-07 03:41:12 +00:00
|
|
|
|
#include "boost/assert.hpp"
|
|
|
|
|
|
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 {
|
|
|
|
|
|
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
|
|
|
|
|
2008-03-24 13:11:16 +00:00
|
|
|
|
int const FORMAT = 7;
|
2005-10-21 16:11:36 +00:00
|
|
|
|
|
|
|
|
|
|
2006-11-26 21:30:39 +00:00
|
|
|
|
bool layout2layout(FileName const & filename, FileName const & tempfile)
|
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()) {
|
|
|
|
|
lyxerr << "Could not find layout conversion "
|
2006-04-05 23:56:29 +00:00
|
|
|
|
"script layout2layout.py." << endl;
|
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())
|
2006-11-26 21:30:39 +00:00
|
|
|
|
<< ' ' << 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
|
|
|
|
|
2007-12-12 19:57:42 +00:00
|
|
|
|
cmd_ret const ret =
|
|
|
|
|
runCommand(command_str);
|
2005-10-21 16:11:36 +00:00
|
|
|
|
if (ret.first != 0) {
|
|
|
|
|
lyxerr << "Could not run layout conversion "
|
2006-04-05 23:56:29 +00:00
|
|
|
|
"script layout2layout.py." << endl;
|
2005-10-21 16:11:36 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-05 16:20:18 +00:00
|
|
|
|
|
|
|
|
|
std::string translateRT(TextClass::ReadType rt)
|
|
|
|
|
{
|
|
|
|
|
switch (rt) {
|
|
|
|
|
case TextClass::BASECLASS:
|
|
|
|
|
return "textclass";
|
|
|
|
|
case TextClass::MERGE:
|
|
|
|
|
return "input file";
|
|
|
|
|
case TextClass::MODULE:
|
|
|
|
|
return "module file";
|
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
|
|
|
|
}
|
|
|
|
|
|
2004-01-31 15:30:24 +00:00
|
|
|
|
} // namespace anon
|
2002-06-24 20:28:12 +00:00
|
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
2008-03-24 21:08:51 +00:00
|
|
|
|
docstring const TextClass::emptylayout_ = 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InsetLayout DocumentClass::empty_insetlayout_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TextClass::TextClass()
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{
|
|
|
|
|
outputType_ = LATEX;
|
|
|
|
|
columns_ = 1;
|
|
|
|
|
sides_ = OneSide;
|
|
|
|
|
secnumdepth_ = 3;
|
|
|
|
|
tocdepth_ = 3;
|
|
|
|
|
pagestyle_ = "default";
|
2007-10-28 18:51:54 +00:00
|
|
|
|
defaultfont_ = sane_font;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
opt_fontsize_ = "10|11|12";
|
|
|
|
|
opt_pagestyle_ = "empty|plain|headings|fancy";
|
2003-02-13 17:49:09 +00:00
|
|
|
|
titletype_ = TITLE_COMMAND_AFTER;
|
|
|
|
|
titlename_ = "maketitle";
|
2004-03-30 16:19:50 +00:00
|
|
|
|
loaded_ = false;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-04 09:51:26 +00:00
|
|
|
|
bool TextClass::readStyle(Lexer & lexrc, Layout & lay)
|
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-02-13 14:39:16 +00:00
|
|
|
|
lyxerr << "Error parsing style `" << to_utf8(lay.name()) << '\'' << endl;
|
|
|
|
|
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,
|
|
|
|
|
TC_INPUT,
|
|
|
|
|
TC_STYLE,
|
2002-03-02 16:39:54 +00:00
|
|
|
|
TC_DEFAULTSTYLE,
|
2007-08-13 12:13:17 +00:00
|
|
|
|
TC_INSETLAYOUT,
|
2003-03-21 12:48:20 +00:00
|
|
|
|
TC_ENVIRONMENT,
|
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,
|
2007-04-06 09:02:23 +00:00
|
|
|
|
TC_PROVIDES,
|
2008-01-07 16:59:10 +00:00
|
|
|
|
TC_REQUIRES,
|
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,
|
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,
|
|
|
|
|
TC_ADDTOPREAMBLE
|
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
|
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
|
keyword_item textClassTags[] = {
|
2008-03-24 13:11:16 +00:00
|
|
|
|
{ "addtopreamble", TC_ADDTOPREAMBLE },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "classoptions", TC_CLASSOPTIONS },
|
|
|
|
|
{ "columns", TC_COLUMNS },
|
2002-09-06 14:48:01 +00:00
|
|
|
|
{ "counter", TC_COUNTER },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "defaultfont", TC_DEFAULTFONT },
|
2002-03-02 16:39:54 +00:00
|
|
|
|
{ "defaultstyle", TC_DEFAULTSTYLE },
|
2003-03-21 12:48:20 +00:00
|
|
|
|
{ "environment", TC_ENVIRONMENT },
|
2002-09-04 06:52:26 +00:00
|
|
|
|
{ "float", TC_FLOAT },
|
2005-10-21 16:11:36 +00:00
|
|
|
|
{ "format", TC_FORMAT },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "input", TC_INPUT },
|
2007-08-13 12:13:17 +00:00
|
|
|
|
{ "insetlayout", TC_INSETLAYOUT },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "leftmargin", TC_LEFTMARGIN },
|
2002-09-11 07:39:55 +00:00
|
|
|
|
{ "nofloat", TC_NOFLOAT },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "nostyle", TC_NOSTYLE },
|
|
|
|
|
{ "outputtype", TC_OUTPUTTYPE },
|
|
|
|
|
{ "pagestyle", TC_PAGESTYLE },
|
|
|
|
|
{ "preamble", TC_PREAMBLE },
|
2007-04-06 09:02:23 +00:00
|
|
|
|
{ "provides", TC_PROVIDES },
|
2008-01-07 16:59:10 +00:00
|
|
|
|
{ "requires", TC_REQUIRES },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "rightmargin", TC_RIGHTMARGIN },
|
|
|
|
|
{ "secnumdepth", TC_SECNUMDEPTH },
|
|
|
|
|
{ "sides", TC_SIDES },
|
|
|
|
|
{ "style", TC_STYLE },
|
2003-02-13 17:49:09 +00:00
|
|
|
|
{ "titlelatexname", TC_TITLELATEXNAME },
|
|
|
|
|
{ "titlelatextype", TC_TITLELATEXTYPE },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{ "tocdepth", TC_TOCDEPTH }
|
|
|
|
|
};
|
2008-03-24 12:31:07 +00:00
|
|
|
|
|
|
|
|
|
} //namespace anon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::convertLayoutFormat(support::FileName const & filename, ReadType rt)
|
|
|
|
|
{
|
|
|
|
|
LYXERR(Debug::TCLASS, "Converting layout file to " << FORMAT);
|
|
|
|
|
FileName const tempfile = FileName::tempName();
|
|
|
|
|
bool success = layout2layout(filename, tempfile);
|
|
|
|
|
if (success)
|
|
|
|
|
success = read(tempfile, rt);
|
|
|
|
|
tempfile.removeFile();
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TextClass::read(FileName const & filename, ReadType rt)
|
|
|
|
|
{
|
|
|
|
|
if (!filename.isReadableFile()) {
|
|
|
|
|
lyxerr << "Cannot read layout file `" << filename << "'."
|
|
|
|
|
<< endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
2008-02-05 16:20:18 +00:00
|
|
|
|
LYXERR(Debug::TCLASS, "Reading " + translateRT(rt) + ": " +
|
|
|
|
|
to_utf8(makeDisplayPath(filename.absFilename())));
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
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
|
|
|
|
// Define the `empty' layout used in table cells, ert, etc. Note that
|
|
|
|
|
// we do this before loading any layout file, so that classes can
|
|
|
|
|
// override features of this layout if they should choose to do so.
|
2008-03-24 12:31:07 +00:00
|
|
|
|
if (rt == BASECLASS && !hasLayout(emptylayout_)) {
|
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
|
|
|
|
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";
|
2008-02-18 10:03:30 +00:00
|
|
|
|
istringstream ss(s);
|
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
|
|
|
|
Lexer lex(textClassTags, sizeof(textClassTags) / sizeof(textClassTags[0]));
|
|
|
|
|
lex.setStream(ss);
|
|
|
|
|
Layout lay;
|
|
|
|
|
lay.setName(emptylayout_);
|
2008-02-13 12:37:11 +00:00
|
|
|
|
if (!readStyle(lex, lay)) {
|
2008-02-14 03:38:08 +00:00
|
|
|
|
// The only way this happens is because the hardcoded layout above
|
|
|
|
|
// is wrong.
|
2008-02-13 12:37:11 +00:00
|
|
|
|
BOOST_ASSERT(false);
|
2008-03-06 20:01:30 +00:00
|
|
|
|
};
|
|
|
|
|
layoutlist_.push_back(lay);
|
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
|
|
|
|
}
|
2007-04-26 11:30:54 +00:00
|
|
|
|
Lexer lexrc(textClassTags,
|
2003-03-21 12:48:20 +00:00
|
|
|
|
sizeof(textClassTags) / sizeof(textClassTags[0]));
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
2002-03-21 17:27:08 +00:00
|
|
|
|
lexrc.setFile(filename);
|
2008-03-24 12:31:07 +00:00
|
|
|
|
ReturnValues retval = read(lexrc, rt);
|
|
|
|
|
|
|
|
|
|
LYXERR(Debug::TCLASS, "Finished reading " + translateRT(rt) + ": " +
|
|
|
|
|
to_utf8(makeDisplayPath(filename.absFilename())));
|
|
|
|
|
|
|
|
|
|
if (retval != FORMAT_MISMATCH)
|
|
|
|
|
return retval == OK;
|
|
|
|
|
|
|
|
|
|
bool const worx = convertLayoutFormat(filename, rt);
|
|
|
|
|
if (!worx) {
|
|
|
|
|
lyxerr << "Unable to convert " << filename <<
|
|
|
|
|
" to format " << FORMAT << std::endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::validate(std::string const & str)
|
|
|
|
|
{
|
|
|
|
|
TextClass tc;
|
|
|
|
|
return tc.read(str, VALIDATION);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::read(std::string const & str, ReadType rt)
|
|
|
|
|
{
|
|
|
|
|
Lexer lexrc(textClassTags,
|
|
|
|
|
sizeof(textClassTags) / sizeof(textClassTags[0]));
|
|
|
|
|
istringstream is(str);
|
|
|
|
|
lexrc.setStream(is);
|
|
|
|
|
ReturnValues retval = read(lexrc, rt);
|
|
|
|
|
|
|
|
|
|
if (retval != FORMAT_MISMATCH)
|
|
|
|
|
return retval == OK;
|
|
|
|
|
|
|
|
|
|
// write the layout string to a temporary file
|
|
|
|
|
FileName const tempfile = FileName::tempName();
|
|
|
|
|
ofstream os(tempfile.toFilesystemEncoding().c_str());
|
|
|
|
|
if (!os) {
|
|
|
|
|
lyxerr << "Unable to create tempoary file in TextClass::read!!"
|
|
|
|
|
<< std::endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
os << str;
|
|
|
|
|
os.close();
|
|
|
|
|
|
|
|
|
|
// now try to convert it
|
|
|
|
|
bool const worx = convertLayoutFormat(tempfile, rt);
|
|
|
|
|
if (!worx) {
|
|
|
|
|
lyxerr << "Unable to convert internal layout information to format "
|
|
|
|
|
<< FORMAT << std::endl;
|
|
|
|
|
}
|
|
|
|
|
tempfile.removeFile();
|
|
|
|
|
return worx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reads a textclass structure from file.
|
|
|
|
|
TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
|
|
|
|
|
{
|
2005-10-21 16:11:36 +00:00
|
|
|
|
bool error = !lexrc.isOK();
|
|
|
|
|
|
|
|
|
|
// Format of files before the 'Format' tag was introduced
|
|
|
|
|
int format = 1;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
|
|
// parsing
|
|
|
|
|
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
|
|
|
|
|
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:
|
|
|
|
|
if (lexrc.next())
|
|
|
|
|
format = lexrc.getInteger();
|
|
|
|
|
break;
|
|
|
|
|
|
2001-12-28 13:26:54 +00:00
|
|
|
|
case TC_OUTPUTTYPE: // output type definition
|
|
|
|
|
readOutputType(lexrc);
|
|
|
|
|
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()) {
|
2006-10-04 16:22:38 +00:00
|
|
|
|
string const inc = lexrc.getString();
|
2006-11-26 21:30:39 +00:00
|
|
|
|
FileName 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)) {
|
2001-12-28 13:26:54 +00:00
|
|
|
|
lexrc.printError("Error reading input"
|
2006-11-26 21:30:39 +00:00
|
|
|
|
"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
|
|
|
|
|
2003-05-19 07:12:09 +00:00
|
|
|
|
case TC_ENVIRONMENT:
|
2001-12-28 13:26:54 +00:00
|
|
|
|
case TC_STYLE:
|
|
|
|
|
if (lexrc.next()) {
|
2007-07-11 13:39:08 +00:00
|
|
|
|
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!";
|
|
|
|
|
lexrc.printError(s.c_str());
|
|
|
|
|
Layout lay;
|
2008-03-24 12:31:07 +00:00
|
|
|
|
// Since we couldn't read the name, we just scan the rest
|
|
|
|
|
// of the style and discard it.
|
2008-02-13 14:39:16 +00:00
|
|
|
|
error = !readStyle(lexrc, lay);
|
2007-07-11 13:39:08 +00:00
|
|
|
|
} else if (hasLayout(name)) {
|
2008-03-06 20:01:30 +00:00
|
|
|
|
Layout & lay = operator[](name);
|
|
|
|
|
error = !readStyle(lexrc, lay);
|
2001-12-28 13:26:54 +00:00
|
|
|
|
} else {
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout lay;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
lay.setName(name);
|
2003-05-19 07:12:09 +00:00
|
|
|
|
if (le == TC_ENVIRONMENT)
|
|
|
|
|
lay.is_environment = true;
|
2008-02-13 14:39:16 +00:00
|
|
|
|
error = !readStyle(lexrc, lay);
|
2005-11-02 20:11:36 +00:00
|
|
|
|
if (!error)
|
2008-03-06 20:01:30 +00:00
|
|
|
|
layoutlist_.push_back(lay);
|
2003-11-03 17:47:28 +00:00
|
|
|
|
|
2002-03-03 20:25:07 +00:00
|
|
|
|
if (defaultlayout_.empty()) {
|
2008-02-14 03:38:08 +00:00
|
|
|
|
// We do not have a default layout yet, so we choose
|
|
|
|
|
// the first layout we encounter.
|
2002-03-03 20:25:07 +00:00
|
|
|
|
defaultlayout_ = name;
|
|
|
|
|
}
|
2001-12-28 13:26:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2008-02-14 03:38:08 +00:00
|
|
|
|
//FIXME Should we also eat the style here? viz:
|
|
|
|
|
//Layout lay;
|
|
|
|
|
//readStyle(lexrc, lay);
|
|
|
|
|
//as above...
|
2001-12-28 13:26:54 +00:00
|
|
|
|
lexrc.printError("No name given for style: `$$Token'.");
|
|
|
|
|
error = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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:
|
2006-11-08 17:22:44 +00:00
|
|
|
|
preamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
|
2001-12-28 13:26:54 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2008-03-24 13:11:16 +00:00
|
|
|
|
case TC_ADDTOPREAMBLE:
|
|
|
|
|
preamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
|
|
|
|
|
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();
|
2008-02-01 15:12:04 +00:00
|
|
|
|
vector<string> const req
|
|
|
|
|
= getVectorFromString(lexrc.getString());
|
|
|
|
|
requires_.insert(req.begin(), req.end());
|
2008-01-07 16:59:10 +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
|
|
|
|
|
2007-08-13 12:13:17 +00:00
|
|
|
|
case TC_INSETLAYOUT:
|
|
|
|
|
if (lexrc.next()) {
|
2008-02-22 03:27:42 +00:00
|
|
|
|
InsetLayout il;
|
|
|
|
|
if (il.read(lexrc)) {
|
|
|
|
|
insetlayoutlist_[il.name()] = il;
|
|
|
|
|
}
|
|
|
|
|
// else there was an error, so forget it
|
2007-08-13 12:13:17 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
|
2002-09-04 06:52:26 +00:00
|
|
|
|
case TC_FLOAT:
|
|
|
|
|
readFloat(lexrc);
|
|
|
|
|
break;
|
2008-02-14 03:38:08 +00:00
|
|
|
|
|
2002-09-06 14:48:01 +00:00
|
|
|
|
case TC_COUNTER:
|
|
|
|
|
readCounter(lexrc);
|
|
|
|
|
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;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
}
|
2008-02-14 03:38:08 +00:00
|
|
|
|
|
|
|
|
|
//Note that this is triggered the first time through the loop unless
|
|
|
|
|
//we hit a format tag.
|
2005-10-21 16:11:36 +00:00
|
|
|
|
if (format != FORMAT)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-24 12:31:07 +00:00
|
|
|
|
if (format != FORMAT)
|
|
|
|
|
return FORMAT_MISMATCH;
|
2008-02-05 16:20:18 +00:00
|
|
|
|
|
2008-02-05 22:57:33 +00:00
|
|
|
|
if (rt != BASECLASS)
|
2008-03-24 12:31:07 +00:00
|
|
|
|
return (error ? ERROR : OK);
|
2008-02-05 22:57:33 +00:00
|
|
|
|
|
|
|
|
|
if (defaultlayout_.empty()) {
|
|
|
|
|
lyxerr << "Error: Textclass '" << name_
|
|
|
|
|
<< "' is missing a defaultstyle." << endl;
|
|
|
|
|
error = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Try to erase "stdinsets" from the provides_ set.
|
|
|
|
|
//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.
|
|
|
|
|
int erased = provides_.erase("stdinsets");
|
|
|
|
|
if (!erased) {
|
|
|
|
|
FileName tmp = libFileSearch("layouts", "stdinsets.inc");
|
|
|
|
|
|
|
|
|
|
if (tmp.empty()) {
|
2008-02-06 09:46:48 +00:00
|
|
|
|
throw ExceptionMessage(WarningException, _("Missing File"),
|
|
|
|
|
_("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)) {
|
2008-02-06 09:46:48 +00:00
|
|
|
|
throw ExceptionMessage(WarningException, _("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
|
|
|
|
{
|
|
|
|
|
keyword_item titleTypeTags[] = {
|
|
|
|
|
{ "commandafter", TITLE_COMMAND_AFTER },
|
|
|
|
|
{ "environment", TITLE_ENVIRONMENT }
|
|
|
|
|
};
|
|
|
|
|
|
2007-04-26 11:30:54 +00:00
|
|
|
|
PushPopHelper pph(lexrc, titleTypeTags, TITLE_ENVIRONMENT);
|
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'");
|
|
|
|
|
return;
|
|
|
|
|
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:
|
|
|
|
|
lyxerr << "Unhandled value " << le
|
2007-04-29 19:53:54 +00:00
|
|
|
|
<< " in TextClass::readTitleType." << endl;
|
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
|
|
|
|
{
|
|
|
|
|
keyword_item outputTypeTags[] = {
|
|
|
|
|
{ "docbook", DOCBOOK },
|
|
|
|
|
{ "latex", LATEX },
|
|
|
|
|
{ "literate", LITERATE }
|
|
|
|
|
};
|
|
|
|
|
|
2007-04-26 11:30:54 +00:00
|
|
|
|
PushPopHelper pph(lexrc, outputTypeTags, LITERATE);
|
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:
|
|
|
|
|
lyxerr << "Unhandled value " << le
|
2007-04-29 19:53:54 +00:00
|
|
|
|
<< " in TextClass::readOutputType." << endl;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum ClassOptionsTags {
|
|
|
|
|
CO_FONTSIZE = 1,
|
|
|
|
|
CO_PAGESTYLE,
|
|
|
|
|
CO_OTHER,
|
2003-11-27 16:57:12 +00:00
|
|
|
|
CO_HEADER,
|
2001-12-28 13:26:54 +00:00
|
|
|
|
CO_END
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
|
void TextClass::readClassOptions(Lexer & lexrc)
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{
|
|
|
|
|
keyword_item classOptionsTags[] = {
|
|
|
|
|
{"end", CO_END },
|
|
|
|
|
{"fontsize", CO_FONTSIZE },
|
2003-11-27 16:57:12 +00:00
|
|
|
|
{"header", CO_HEADER },
|
2001-12-28 13:26:54 +00:00
|
|
|
|
{"other", CO_OTHER },
|
|
|
|
|
{"pagestyle", CO_PAGESTYLE }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
lexrc.pushTable(classOptionsTags, CO_END);
|
|
|
|
|
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;
|
2001-12-28 13:26:54 +00:00
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
switch (static_cast<ClassOptionsTags>(le)) {
|
|
|
|
|
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();
|
|
|
|
|
options_ = lexrc.getString();
|
|
|
|
|
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
|
|
|
|
|
2002-09-04 06:52:26 +00:00
|
|
|
|
enum FloatTags {
|
|
|
|
|
FT_TYPE = 1,
|
|
|
|
|
FT_NAME,
|
|
|
|
|
FT_PLACEMENT,
|
|
|
|
|
FT_EXT,
|
|
|
|
|
FT_WITHIN,
|
|
|
|
|
FT_STYLE,
|
|
|
|
|
FT_LISTNAME,
|
|
|
|
|
FT_BUILTIN,
|
|
|
|
|
FT_END
|
|
|
|
|
};
|
|
|
|
|
|
2003-11-12 14:38:26 +00:00
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
|
void TextClass::readFloat(Lexer & lexrc)
|
2002-09-04 06:52:26 +00:00
|
|
|
|
{
|
|
|
|
|
keyword_item floatTags[] = {
|
|
|
|
|
{ "end", FT_END },
|
|
|
|
|
{ "extension", FT_EXT },
|
|
|
|
|
{ "guiname", FT_NAME },
|
|
|
|
|
{ "latexbuiltin", FT_BUILTIN },
|
|
|
|
|
{ "listname", FT_LISTNAME },
|
|
|
|
|
{ "numberwithin", FT_WITHIN },
|
|
|
|
|
{ "placement", FT_PLACEMENT },
|
|
|
|
|
{ "style", FT_STYLE },
|
|
|
|
|
{ "type", FT_TYPE }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
lexrc.pushTable(floatTags, FT_END);
|
|
|
|
|
|
|
|
|
|
string type;
|
|
|
|
|
string placement;
|
|
|
|
|
string ext;
|
|
|
|
|
string within;
|
|
|
|
|
string style;
|
|
|
|
|
string name;
|
2007-08-16 11:07:00 +00:00
|
|
|
|
string listName;
|
2002-09-04 06:52:26 +00:00
|
|
|
|
bool builtin = false;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
switch (static_cast<FloatTags>(le)) {
|
|
|
|
|
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();
|
|
|
|
|
listName = fl.listName();
|
|
|
|
|
builtin = fl.builtin();
|
|
|
|
|
}
|
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;
|
|
|
|
|
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;
|
|
|
|
|
case FT_LISTNAME:
|
|
|
|
|
lexrc.next();
|
2007-08-16 11:07:00 +00:00
|
|
|
|
listName = lexrc.getString();
|
2002-09-04 06:52:26 +00:00
|
|
|
|
break;
|
|
|
|
|
case FT_BUILTIN:
|
|
|
|
|
lexrc.next();
|
|
|
|
|
builtin = lexrc.getBool();
|
|
|
|
|
break;
|
|
|
|
|
case FT_END:
|
|
|
|
|
getout = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Here if have a full float if getout == true
|
|
|
|
|
if (getout) {
|
2007-08-16 11:07:00 +00:00
|
|
|
|
Floating fl(type, placement, ext, within,
|
|
|
|
|
style, name, listName, builtin);
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lexrc.popTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-09-06 14:48:01 +00:00
|
|
|
|
enum CounterTags {
|
|
|
|
|
CT_NAME = 1,
|
|
|
|
|
CT_WITHIN,
|
2007-08-16 11:07:00 +00:00
|
|
|
|
CT_LABELSTRING,
|
|
|
|
|
CT_LABELSTRING_APPENDIX,
|
2002-09-06 14:48:01 +00:00
|
|
|
|
CT_END
|
|
|
|
|
};
|
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
|
void TextClass::readCounter(Lexer & lexrc)
|
2002-09-06 14:48:01 +00:00
|
|
|
|
{
|
|
|
|
|
keyword_item counterTags[] = {
|
|
|
|
|
{ "end", CT_END },
|
2007-08-16 11:07:00 +00:00
|
|
|
|
{ "labelstring", CT_LABELSTRING },
|
|
|
|
|
{ "labelstringappendix", CT_LABELSTRING_APPENDIX },
|
2002-09-06 14:48:01 +00:00
|
|
|
|
{ "name", CT_NAME },
|
|
|
|
|
{ "within", CT_WITHIN }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
lexrc.pushTable(counterTags, CT_END);
|
|
|
|
|
|
2006-10-20 22:17:16 +00:00
|
|
|
|
docstring name;
|
|
|
|
|
docstring within;
|
2007-08-16 11:07:00 +00:00
|
|
|
|
docstring labelstring;
|
|
|
|
|
docstring labelstring_appendix;
|
2002-09-06 14:48:01 +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 counter tag `$$Token'");
|
2002-09-06 14:48:01 +00:00
|
|
|
|
continue;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
switch (static_cast<CounterTags>(le)) {
|
|
|
|
|
case CT_NAME:
|
|
|
|
|
lexrc.next();
|
2007-08-16 11:07:00 +00:00
|
|
|
|
name = lexrc.getDocString();
|
2008-03-07 03:41:12 +00:00
|
|
|
|
if (counters_.hasCounter(name))
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::TCLASS, "Reading existing counter " << to_utf8(name));
|
2007-08-16 11:07:00 +00:00
|
|
|
|
else
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::TCLASS, "Reading new counter " << to_utf8(name));
|
2002-09-06 14:48:01 +00:00
|
|
|
|
break;
|
|
|
|
|
case CT_WITHIN:
|
|
|
|
|
lexrc.next();
|
2007-08-16 11:07:00 +00:00
|
|
|
|
within = lexrc.getDocString();
|
2006-12-21 19:02:17 +00:00
|
|
|
|
if (within == "none")
|
2002-09-06 14:48:01 +00:00
|
|
|
|
within.erase();
|
|
|
|
|
break;
|
2007-08-16 11:07:00 +00:00
|
|
|
|
case CT_LABELSTRING:
|
|
|
|
|
lexrc.next();
|
|
|
|
|
labelstring = lexrc.getDocString();
|
|
|
|
|
labelstring_appendix = labelstring;
|
|
|
|
|
break;
|
|
|
|
|
case CT_LABELSTRING_APPENDIX:
|
|
|
|
|
lexrc.next();
|
|
|
|
|
labelstring_appendix = lexrc.getDocString();
|
|
|
|
|
break;
|
2002-09-06 14:48:01 +00:00
|
|
|
|
case CT_END:
|
|
|
|
|
getout = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-12 17:13:22 +00:00
|
|
|
|
// Here if have a full counter if getout == true
|
2007-08-16 11:07:00 +00:00
|
|
|
|
if (getout)
|
2008-03-07 03:41:12 +00:00
|
|
|
|
counters_.newCounter(name, within,
|
2007-08-16 15:26:00 +00:00
|
|
|
|
labelstring, labelstring_appendix);
|
2002-09-06 14:48:01 +00:00
|
|
|
|
|
|
|
|
|
lexrc.popTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-05-19 07:12:09 +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
|
|
|
|
{
|
2003-09-09 17:25:35 +00:00
|
|
|
|
BOOST_ASSERT(!name.empty());
|
2002-03-12 18:11:49 +00:00
|
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
|
const_iterator it =
|
|
|
|
|
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()) {
|
2007-07-11 13:39:08 +00:00
|
|
|
|
lyxerr << "We failed to find the layout '" << to_utf8(name)
|
2002-03-02 16:39:54 +00:00
|
|
|
|
<< "' in the layout list. You MUST investigate!"
|
|
|
|
|
<< endl;
|
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
|
|
|
|
|
2002-03-02 16:39:54 +00:00
|
|
|
|
// we require the name to exist
|
2003-09-09 17:25:35 +00:00
|
|
|
|
BOOST_ASSERT(false);
|
2002-03-02 16:39:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
|
return *it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Layout & TextClass::operator[](docstring const & name)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(!name.empty());
|
|
|
|
|
|
|
|
|
|
iterator it = find_if(begin(), end(), LayoutNamesEqual(name));
|
|
|
|
|
|
|
|
|
|
if (it == end()) {
|
|
|
|
|
lyxerr << "We failed to find the layout '" << to_utf8(name)
|
|
|
|
|
<< "' in the layout list. You MUST investigate!"
|
|
|
|
|
<< endl;
|
|
|
|
|
for (const_iterator cit = begin(); cit != end(); ++cit)
|
|
|
|
|
lyxerr << " " << to_utf8(cit->name()) << endl;
|
|
|
|
|
|
|
|
|
|
// we require the name to exist
|
|
|
|
|
BOOST_ASSERT(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
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
|
|
|
|
if (name == defaultLayoutName() || name == emptyLayoutName())
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
2006-11-26 21:30:39 +00:00
|
|
|
|
FileName layout_file;
|
2006-05-04 02:38:11 +00:00
|
|
|
|
if (!path.empty())
|
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 `"
|
2006-11-26 21:30:39 +00:00
|
|
|
|
<< to_utf8(makeDisplayPath(layout_file.absFilename()))
|
2001-12-28 13:26:54 +00:00
|
|
|
|
<< "'\n(Check `" << name_
|
|
|
|
|
<< "')\nCheck your installation and "
|
|
|
|
|
"try Options/Reconfigure..." << endl;
|
|
|
|
|
}
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
InsetLayout const & DocumentClass::insetLayout(docstring const & name) const
|
2007-08-13 12:13:17 +00:00
|
|
|
|
{
|
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);
|
|
|
|
|
if (cit != cen && cit->first == n)
|
|
|
|
|
return cit->second;
|
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;
|
|
|
|
|
n = n.substr(0,i);
|
|
|
|
|
}
|
2008-02-21 16:31:59 +00:00
|
|
|
|
return empty_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
|
|
|
|
{
|
|
|
|
|
// This really should come from the actual layout... (Lgb)
|
|
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-03-06 20:01:30 +00:00
|
|
|
|
bool TextClass::isDefaultLayout(Layout const & lay) const
|
|
|
|
|
{
|
|
|
|
|
return lay.name() == defaultLayoutName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TextClass::isEmptyLayout(Layout const & lay) const
|
|
|
|
|
{
|
|
|
|
|
return lay.name() == emptyLayoutName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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 & DocumentClassBundle::newClass(LayoutFile const & baseClass)
|
2008-02-25 19:31:31 +00:00
|
|
|
|
{
|
2008-03-06 23:31:40 +00:00
|
|
|
|
DocumentClass * dc = new DocumentClass(baseClass);
|
2008-02-28 01:42:02 +00:00
|
|
|
|
tc_list_.push_back(dc);
|
2008-03-06 23:31:40 +00:00
|
|
|
|
return *tc_list_.back();
|
2008-02-25 19:31:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-02-28 01:42:02 +00:00
|
|
|
|
DocumentClassBundle & DocumentClassBundle::get()
|
2008-02-25 19:31:31 +00:00
|
|
|
|
{
|
2008-02-28 01:42:02 +00:00
|
|
|
|
static DocumentClassBundle singleton;
|
2008-02-25 19:31:31 +00:00
|
|
|
|
return singleton;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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
|