Example #1
0
bool Font::fromString(string const & data, bool & toggle)
{
	istringstream is(data);
	Lexer lex;
	lex.setStream(is);

	int nset = 0;
	while (lex.isOK()) {
		string token;
		if (lex.next())
			token = lex.getString();

		if (token.empty() || !lex.next())
			break;

		if (token == "family") {
			int const next = lex.getInteger();
			bits_.setFamily(FontFamily(next));

		} else if (token == "series") {
			int const next = lex.getInteger();
			bits_.setSeries(FontSeries(next));

		} else if (token == "shape") {
			int const next = lex.getInteger();
			bits_.setShape(FontShape(next));

		} else if (token == "size") {
			int const next = lex.getInteger();
			bits_.setSize(FontSize(next));

		} else if (token == "emph" || token == "underbar" ||
			   token == "noun" || token == "number" ||
			   token == "uuline" || token == "uwave" ||
			   token == "strikeout") {

			int const next = lex.getInteger();
			FontState const misc = FontState(next);

			if (token == "emph")
				bits_.setEmph(misc);
			else if (token == "underbar")
				bits_.setUnderbar(misc);
			else if (token == "strikeout")
				bits_.setStrikeout(misc);
			else if (token == "uuline")
				bits_.setUuline(misc);
			else if (token == "uwave")
				bits_.setUwave(misc);
			else if (token == "noun")
				bits_.setNoun(misc);
			else if (token == "number")
				bits_.setNumber(misc);

		} else if (token == "color") {
			int const next = lex.getInteger();
			bits_.setColor(ColorCode(next));

		/**
		} else if (token == "background") {
			int const next = lex.getInteger();
			bits_.setBackground(ColorCode(next));
		*/

		} else if (token == "language") {
			string const next = lex.getString();
			setLanguage(languages.getLanguage(next));

		} else if (token == "toggleall") {
			toggle = lex.getBool();

		} else {
			// Unrecognised token
			break;
		}

		++nset;
	}
	return (nset > 0);
}
Example #2
0
// Reads a textclass structure from file.
TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt) 
{
	if (!lexrc.isOK())
		return ERROR;

	// Format of files before the 'Format' tag was introduced
	int format = 1;
	bool error = false;

	// parsing
	while (lexrc.isOK() && !error) {
		int le = lexrc.lex();

		switch (le) {
		case Lexer::LEX_FEOF:
			continue;

		case Lexer::LEX_UNDEF:
			lexrc.printError("Unknown TextClass tag `$$Token'");
			error = true;
			continue;

		default:
			break;
		}

		// used below to track whether we are in an IfStyle or IfCounter tag.
		bool ifstyle    = false;
		bool ifcounter  = false;

		switch (static_cast<TextClassTags>(le)) {

		case TC_FORMAT:
			if (lexrc.next())
				format = lexrc.getInteger();
			break;

		case TC_OUTPUTFORMAT:
			if (lexrc.next())
				outputFormat_ = lexrc.getString();
			break;

		case TC_OUTPUTTYPE:
			readOutputType(lexrc);
			switch(outputType_) {
			case LATEX:
				outputFormat_ = "latex";
				break;
			case DOCBOOK:
				outputFormat_ = "docbook";
				break;
			case LITERATE:
				outputFormat_ = "literate";
				break;
			}
			break;

		case TC_INPUT: // Include file
			if (lexrc.next()) {
				string const inc = lexrc.getString();
				FileName tmp = libFileSearch("layouts", inc,
							    "layout");

				if (tmp.empty()) {
					lexrc.printError("Could not find input file: " + inc);
					error = true;
				} else if (!read(tmp, MERGE)) {
					lexrc.printError("Error reading input file: " + tmp.absFileName());
					error = true;
				}
			}
			break;

		case TC_DEFAULTSTYLE:
			if (lexrc.next()) {
				docstring const name = from_utf8(subst(lexrc.getString(),
							  '_', ' '));
				defaultlayout_ = name;
			}
			break;

		case TC_IFSTYLE:
			ifstyle = true;
			// fall through
		case TC_STYLE: {
			if (!lexrc.next()) {
				lexrc.printError("No name given for style: `$$Token'.");
				error = true;
				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!";
				lexrc.printError(s);
				Layout lay;
				// 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);
				error = !readStyle(lexrc, lay);
			} else if (!ifstyle) {
				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;
				}
			}
			else {
				// this was an ifstyle where we didn't have the style
				// scan the rest and discard it
				Layout lay;
				readStyle(lexrc, lay);
			}

			// reset flag
			ifstyle = false;
			break;
		}

		case TC_NOSTYLE:
			if (lexrc.next()) {
				docstring const style = from_utf8(subst(lexrc.getString(),
						     '_', ' '));
				if (!deleteLayout(style))
					lyxerr << "Cannot delete style `"
					       << to_utf8(style) << '\'' << endl;
			}
			break;

		case TC_COLUMNS:
			if (lexrc.next())
				columns_ = lexrc.getInteger();
			break;

		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;

		case TC_PAGESTYLE:
			lexrc.next();
			pagestyle_ = rtrim(lexrc.getString());
			break;

		case TC_DEFAULTFONT:
			defaultfont_ = lyxRead(lexrc);
			if (!defaultfont_.resolved()) {
				lexrc.printError("Warning: defaultfont should "
						 "be fully instantiated!");
				defaultfont_.realize(sane_font);
			}
			break;

		case TC_SECNUMDEPTH:
			lexrc.next();
			secnumdepth_ = lexrc.getInteger();
			break;

		case TC_TOCDEPTH:
			lexrc.next();
			tocdepth_ = lexrc.getInteger();
			break;

		// First step to support options
		case TC_CLASSOPTIONS:
			readClassOptions(lexrc);
			break;

		case TC_PREAMBLE:
			preamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
			break;

		case TC_HTMLPREAMBLE:
			htmlpreamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
			break;
		
		case TC_HTMLTOCSECTION:
			html_toc_section_ = from_utf8(trim(lexrc.getString()));
			break;

		case TC_ADDTOPREAMBLE:
			preamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
			break;

		case TC_ADDTOHTMLPREAMBLE:
			htmlpreamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
			break;

		case TC_PROVIDES: {
			lexrc.next();
			string const feature = lexrc.getString();
			lexrc.next();
			if (lexrc.getInteger())
				provides_.insert(feature);
			else
				provides_.erase(feature);
			break;
		}

		case TC_REQUIRES: {
			lexrc.eatLine();
			vector<string> const req 
				= getVectorFromString(lexrc.getString());
			requires_.insert(req.begin(), req.end());
			break;
		}

		case TC_DEFAULTMODULE: {
			lexrc.next();
			string const module = lexrc.getString();
			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);
			break;
		}

		case TC_LEFTMARGIN:	// left margin type
			if (lexrc.next())
				leftmargin_ = lexrc.getDocString();
			break;

		case TC_RIGHTMARGIN:	// right margin type
			if (lexrc.next())
				rightmargin_ = lexrc.getDocString();
			break;

		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!";
				lexrc.printError(s);
				InsetLayout il;
				// Since we couldn't read the name, we just scan the rest
				// of the style and discard it.
				il.read(lexrc, *this);
				// Let's try to continue rather than abort.
				// error = true;
			} else if (hasInsetLayout(name)) {
				InsetLayout & il = insetlayoutlist_[name];
				error = !il.read(lexrc, *this);
			} else {
				InsetLayout il;
				il.setName(name);
				error = !il.read(lexrc, *this);
				if (!error)
					insetlayoutlist_[name] = il;
			}
			break;
		}

		case TC_FLOAT:
			error = !readFloat(lexrc);
			break;
		
		case TC_CITEFORMAT:
			readCiteFormat(lexrc);
			break;

		case TC_IFCOUNTER:
			ifcounter = true;
		case TC_COUNTER:
			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
					error = !counters_.read(lexrc, name, !ifcounter);
			}
			else {
				lexrc.printError("No name given for style: `$$Token'.");
				error = true;
			}
			// reset flag
			ifcounter = false;
			break;

		case TC_TITLELATEXTYPE:
			readTitleType(lexrc);
			break;

		case TC_TITLELATEXNAME:
			if (lexrc.next())
				titlename_ = lexrc.getString();
			break;

		case TC_NOFLOAT:
			if (lexrc.next()) {
				string const nofloat = lexrc.getString();
				floatlist_.erase(nofloat);
			}
			break;
		} // end of switch

		// Note that this is triggered the first time through the loop unless
		// we hit a format tag.
		if (format != LAYOUT_FORMAT)
			return FORMAT_MISMATCH;
	}

	// at present, we abort if we encounter an error,
	// so there is no point continuing.
	if (error)
		return ERROR;

	if (rt != BASECLASS)
		return (error ? ERROR : OK);

	if (defaultlayout_.empty()) {
		LYXERR0("Error: Textclass '" << name_
						<< "' is missing a defaultstyle.");
		return ERROR;
	}
		
	// 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()) {
			frontend::Alert::warning(_("Missing File"),
				_("Could not find stdinsets.inc! This may lead to data loss!"));
			error = true;
		} else if (!read(tmp, MERGE)) {
			frontend::Alert::warning(_("Corrupt File"),
				_("Could not read stdinsets.inc! This may lead to data loss!"));
			error = true;
		}
	}

	min_toclevel_ = Layout::NOT_IN_TOC;
	max_toclevel_ = Layout::NOT_IN_TOC;
	const_iterator lit = begin();
	const_iterator len = end();
	for (; lit != len; ++lit) {
		int const toclevel = lit->toclevel;
		if (toclevel != Layout::NOT_IN_TOC) {
			if (min_toclevel_ == Layout::NOT_IN_TOC)
				min_toclevel_ = toclevel;
			else
				min_toclevel_ = min(min_toclevel_, toclevel);
			max_toclevel_ = max(max_toclevel_, toclevel);
		}
	}
	LYXERR(Debug::TCLASS, "Minimum TocLevel is " << min_toclevel_
		<< ", maximum is " << max_toclevel_);

	return (error ? ERROR : OK);
}