+string Font::toString(bool const toggle) const
+{
+ string const lang = (language() == reset_language)
+ ? "reset" : language()->lang();
+
+ ostringstream os;
+ os << "family " << bits_.family() << '\n'
+ << "series " << bits_.series() << '\n'
+ << "shape " << bits_.shape() << '\n'
+ << "size " << bits_.size() << '\n'
+ << "emph " << bits_.emph() << '\n'
+ << "underbar " << bits_.underbar() << '\n'
+ << "strikeout " << bits_.strikeout() << '\n'
+ << "uuline " << bits_.uuline() << '\n'
+ << "uwave " << bits_.uwave() << '\n'
+ << "noun " << bits_.noun() << '\n'
+ << "number " << bits_.number() << '\n'
+ << "color " << bits_.color() << '\n'
+ << "language " << lang << '\n'
+ << "toggleall " << convert<string>(toggle);
+ return os.str();
+}
+
+
+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);
+}
+
+
+void Font::validate(LaTeXFeatures & features) const