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); }
// 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); }