#include "TextClass.h"
-#include "BaseClassList.h"
+#include "LayoutFile.h"
#include "Color.h"
#include "Counters.h"
#include "Floating.h"
#include "support/lstrings.h"
#include "support/os.h"
+#include <algorithm>
+#include <fstream>
#include <sstream>
#include "boost/assert.hpp"
};
-int const FORMAT = 6;
+int const FORMAT = 7;
bool layout2layout(FileName const & filename, FileName const & tempfile)
return "input file";
case TextClass::MODULE:
return "module file";
+ case TextClass::VALIDATION:
+ return "validation";
}
// shutup warning
return string();
} // namespace anon
-docstring const TextClass::emptylayout_ = from_ascii("PlainLayout");
+docstring const TextClass::emptylayout_ = from_ascii(N_("Plain Layout"));
InsetLayout DocumentClass::empty_insetlayout_;
titletype_ = TITLE_COMMAND_AFTER;
titlename_ = "maketitle";
loaded_ = false;
- // a hack to make this available for translation
- // i'm sure there must be a better way (rgh)
- _("PlainLayout");
}
TC_NOFLOAT,
TC_TITLELATEXNAME,
TC_TITLELATEXTYPE,
- TC_FORMAT
+ TC_FORMAT,
+ TC_ADDTOPREAMBLE
};
-// Reads a textclass structure from file.
-bool TextClass::read(FileName const & filename, ReadType rt)
-{
- if (!filename.isReadableFile()) {
- lyxerr << "Cannot read layout file `" << filename << "'."
- << endl;
- return false;
- }
+namespace {
keyword_item textClassTags[] = {
+ { "addtopreamble", TC_ADDTOPREAMBLE },
{ "classoptions", TC_CLASSOPTIONS },
{ "columns", TC_COLUMNS },
{ "counter", TC_COUNTER },
{ "titlelatextype", TC_TITLELATEXTYPE },
{ "tocdepth", TC_TOCDEPTH }
};
+
+} //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;
+ }
LYXERR(Debug::TCLASS, "Reading " + translateRT(rt) + ": " +
to_utf8(makeDisplayPath(filename.absFilename())));
// 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.
- if (rt == BASECLASS) {
+ if (rt == BASECLASS && !hasLayout(emptylayout_)) {
static char const * s = "Margin Static\n"
"LatexType Paragraph\n"
"LatexName dummy\n"
};
layoutlist_.push_back(lay);
}
-
Lexer lexrc(textClassTags,
sizeof(textClassTags) / sizeof(textClassTags[0]));
lexrc.setFile(filename);
+ 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)
+{
bool error = !lexrc.isOK();
// Format of files before the 'Format' tag was introduced
+ lexrc.getString() + " is probably not valid UTF-8!";
lexrc.printError(s.c_str());
Layout lay;
- //FIXME If we're just dropping this layout, do we really
- //care whether there's an error?? Or should we just set
- //error to true, since we couldn't even read the name?
+ // Since we couldn't read the name, we just scan the rest
+ // of the style and discard it.
error = !readStyle(lexrc, lay);
} else if (hasLayout(name)) {
Layout & lay = operator[](name);
preamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
break;
+ case TC_ADDTOPREAMBLE:
+ preamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
+ break;
+
case TC_PROVIDES: {
lexrc.next();
string const feature = lexrc.getString();
break;
}
- if (format != FORMAT) {
- LYXERR(Debug::TCLASS, "Converting layout file from format "
- << format << " to " << FORMAT);
- FileName const tempfile = FileName::tempName();
- bool success = layout2layout(filename, tempfile);
- if (success)
- read(tempfile, rt);
- tempfile.removeFile();
- return success;
- }
-
- LYXERR(Debug::TCLASS, "Finished reading " + translateRT(rt) + ": " +
- to_utf8(makeDisplayPath(filename.absFilename())));
+ if (format != FORMAT)
+ return FORMAT_MISMATCH;
if (rt != BASECLASS)
- return !error;
+ return (error ? ERROR : OK);
if (defaultlayout_.empty()) {
lyxerr << "Error: Textclass '" << name_
LYXERR(Debug::TCLASS, "Minimum TocLevel is " << min_toclevel_
<< ", maximum is " << max_toclevel_);
- return !error;
+ return (error ? ERROR : OK);
}