X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetQuotes.cpp;h=1295f27f0753e0949fa11144ea9f9ddc4f193345;hb=9c4929ca406091267dafa40f5e083a27db046bf6;hp=35c1358e506b672824cb9ac6fdedbc3ae5ca3f25;hpb=36ec5a880fbc12a5eebcac31b72e2714645e6605;p=lyx.git diff --git a/src/insets/InsetQuotes.cpp b/src/insets/InsetQuotes.cpp index 35c1358e50..1295f27f07 100644 --- a/src/insets/InsetQuotes.cpp +++ b/src/insets/InsetQuotes.cpp @@ -16,12 +16,14 @@ #include "BufferParams.h" #include "BufferView.h" #include "Dimension.h" +#include "Font.h" #include "Language.h" #include "LaTeXFeatures.h" #include "Lexer.h" #include "LyXRC.h" #include "MetricsInfo.h" #include "OutputParams.h" +#include "output_xhtml.h" #include "frontends/FontMetrics.h" #include "frontends/Painter.h" @@ -40,7 +42,7 @@ namespace { /* codes used to read/write quotes to LyX files * e ``english'' - * s ''spanish'' + * s ''swedish'' * g ,,german`` * p ,,polish'' * f <> @@ -54,6 +56,12 @@ char const * const times_char = "sd"; // List of known quote chars char const * const quote_char = ",'`<>"; +// Unicode characters needed by each quote type +char_type const display_quote_char[2][5] = { + { 0x201a, 0x2019, 0x2018, 0x2039, 0x203a}, + { 0x201e, 0x201d, 0x201c, 0x00ab, 0x00bb} +}; + // Index of chars used for the quote. Index is [side, language] int quote_index[2][6] = { { 2, 1, 0, 0, 3, 4 }, // "'',,<>" @@ -82,49 +90,47 @@ char const * const latex_quote_babel[2][5] = { } // namespace anon -InsetQuotes::InsetQuotes(string const & str) +InsetQuotes::InsetQuotes(Buffer * buf, string const & str) : Inset(buf) { parseString(str); } - -InsetQuotes::InsetQuotes(quote_language l, quote_side s, quote_times t) - : language_(l), side_(s), times_(t) +InsetQuotes::InsetQuotes(Buffer * buf, char_type c) : Inset(buf) { + if (buf) { + language_ = buf->params().quotes_language; + times_ = buf->params().quotes_times; + } + setSide(c); } -InsetQuotes::InsetQuotes(char_type c, BufferParams const & params) - : language_(params.quotes_language), times_(params.quotes_times) -{ - getPosition(c); -} - - -InsetQuotes::InsetQuotes(char_type c, quote_language l, quote_times t) - : language_(l), times_(t) +InsetQuotes::InsetQuotes(Buffer * buf, char_type c, QuoteTimes t) + : Inset(buf), times_(t) { - getPosition(c); + if (buf) + language_ = buf->params().quotes_language; + setSide(c); } -docstring InsetQuotes::name() const +docstring InsetQuotes::layoutName() const { return from_ascii("Quotes"); } -void InsetQuotes::getPosition(char_type c) +void InsetQuotes::setSide(char_type c) { // Decide whether left or right switch (c) { case ' ': case '(': case '[': - side_ = LeftQ; // left quote + side_ = LeftQuote; // left quote break; default: - side_ = RightQ; // right quote + side_ = RightQuote; // right quote } } @@ -142,81 +148,53 @@ void InsetQuotes::parseString(string const & s) for (i = 0; i < 6; ++i) { if (str[0] == language_char[i]) { - language_ = quote_language(i); + language_ = QuoteLanguage(i); break; } } if (i >= 6) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad language specification." << endl; - language_ = EnglishQ; + language_ = EnglishQuotes; } for (i = 0; i < 2; ++i) { if (str[1] == side_char[i]) { - side_ = quote_side(i); + side_ = QuoteSide(i); break; } } if (i >= 2) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad side specification." << endl; - side_ = LeftQ; + side_ = LeftQuote; } for (i = 0; i < 2; ++i) { if (str[2] == times_char[i]) { - times_ = quote_times(i); + times_ = QuoteTimes(i); break; } } if (i >= 2) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad times specification." << endl; - times_ = DoubleQ; + times_ = DoubleQuotes; } } -docstring InsetQuotes::dispString() const +docstring InsetQuotes::displayString() const { - Language const * loclang = buffer().params().language; - string disp; - disp += quote_char[quote_index[side_][language_]]; - if (times_ == DoubleQ) - disp += disp; - - - docstring retdisp; - if (disp == "<<") - retdisp = docstring(1, 0x00ab); //'«'; - else if (disp == ">>") - retdisp = docstring(1, 0x00bb); //'»'; -#if 0 - // The below are supposed to work, but something fails. - else if (disp == ",,") - retdisp = docstring(1, 0x201e); - else if (disp == "''") - retdisp == docstring(1, 0x201d); - else if (disp == "``") - retdisp == docstring(1, 0x201c); - else if (disp == "<") - retdisp = docstring(1, 0x2039); - else if (disp == ">") - retdisp = docstring(1, 0x203a); - else if (disp == ",") - retdisp = docstring(1, 0x201a); - else if (disp == "'") - retdisp = docstring(1, 0x2019); - else if (disp == "`") - retdisp = docstring(1, 0x2018); -#endif - else - retdisp = from_ascii(disp); + Language const * loclang = + isBufferValid() ? buffer().params().language : 0; + int const index = quote_index[side_][language_]; + docstring retdisp = docstring(1, display_quote_char[times_][index]); // in french, spaces are added inside double quotes - if (times_ == DoubleQ && prefixIs(loclang->code(), "fr")) { - if (side_ == LeftQ) + // FIXME: this should be done by a separate quote type. + if (times_ == DoubleQuotes && loclang && prefixIs(loclang->code(), "fr")) { + if (side_ == LeftQuote) retdisp += ' '; else retdisp.insert(size_t(0), 1, ' '); @@ -236,7 +214,7 @@ void InsetQuotes::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = 0; // FIXME: should we add a language or a font parameter member? - docstring const text = dispString(); + docstring const text = displayString(); for (string::size_type i = 0; i < text.length(); ++i) { if (text[i] == ' ') dim.wid += fm.width('i'); @@ -251,15 +229,16 @@ void InsetQuotes::metrics(MetricsInfo & mi, Dimension & dim) const void InsetQuotes::draw(PainterInfo & pi, int x, int y) const { // FIXME: should we add a language or a font parameter member? - docstring const text = dispString(); - + docstring const text = displayString(); + FontInfo font = pi.base.font; + font.setPaintColor(pi.textColor(font.realColor())); if (text.length() == 2 && text[0] == text[1]) { - pi.pain.text(x, y, text[0], pi.base.font); - int const t = theFontMetrics(pi.base.font) + pi.pain.text(x, y, text[0], font); + int const t = theFontMetrics(font) .width(','); - pi.pain.text(x + t, y, text[0], pi.base.font); + pi.pain.text(x + t, y, text[0], font); } else { - pi.pain.text(x, y, text, pi.base.font); + pi.pain.text(x, y, text, font); } } @@ -276,50 +255,52 @@ void InsetQuotes::write(ostream & os) const void InsetQuotes::read(Lexer & lex) { + lex.setContext("InsetQuotes::read"); lex.next(); parseString(lex.getString()); - lex.next(); - if (lex.getString() != "\\end_inset") { - lex.printError("Missing \\end_inset at this point"); - } + lex >> "\\end_inset"; } -int InsetQuotes::latex(odocstream & os, OutputParams const & runparams) const +void InsetQuotes::latex(otexstream & os, OutputParams const & runparams) const { const int quoteind = quote_index[side_][language_]; string qstr; - if (language_ == FrenchQ && times_ == DoubleQ - && prefixIs(runparams.local_font->language()->code(), "fr")) { - if (side_ == LeftQ) + if (language_ == FrenchQuotes && times_ == DoubleQuotes + && prefixIs(runparams.local_font->language()->code(), "fr") + && !runparams.use_polyglossia) { + if (side_ == LeftQuote) qstr = "\\og "; //the spaces are important here else qstr = " \\fg{}"; //and here - } else if (lyxrc.fontenc == "T1") { + } else if (lyxrc.fontenc == "T1" && !runparams.use_polyglossia) { qstr = latex_quote_t1[times_][quoteind]; #ifdef DO_USE_DEFAULT_LANGUAGE } else if (doclang == "default") { #else } else if (!runparams.use_babel) { #endif + // these are also used by polyglossia qstr = latex_quote_ot1[times_][quoteind]; } else { qstr = latex_quote_babel[times_][quoteind]; } // Always guard against unfortunate ligatures (!` ?`) - if (prefixIs(qstr, "`")) - qstr.insert(0, "{}"); + if (prefixIs(qstr, "`")) { + char_type const lastchar = os.lastChar(); + if (lastchar == '!' || lastchar == '?') + qstr.insert(0, "{}"); + } os << from_ascii(qstr); - return 0; } int InsetQuotes::plaintext(odocstream & os, OutputParams const &) const { - docstring const str = dispString(); + docstring const str = displayString(); os << str; return str.size(); } @@ -327,13 +308,13 @@ int InsetQuotes::plaintext(odocstream & os, OutputParams const &) const int InsetQuotes::docbook(odocstream & os, OutputParams const &) const { - if (times_ == DoubleQ) { - if (side_ == LeftQ) + if (times_ == DoubleQuotes) { + if (side_ == LeftQuote) os << "“"; else os << "”"; } else { - if (side_ == LeftQ) + if (side_ == LeftQuote) os << "‘"; else os << "’"; @@ -342,9 +323,22 @@ int InsetQuotes::docbook(odocstream & os, OutputParams const &) const } -void InsetQuotes::textString(odocstream & os) const +docstring InsetQuotes::xhtml(XHTMLStream & xs, OutputParams const & op) const +{ + docbook(xs.os(), op); + return docstring(); +} + + +void InsetQuotes::toString(odocstream & os) const +{ + os << displayString(); +} + + +void InsetQuotes::forToc(docstring & os, size_t) const { - os << dispString(); + os += displayString(); } @@ -359,7 +353,7 @@ void InsetQuotes::validate(LaTeXFeatures & features) const if (!use_babel #endif && lyxrc.fontenc != "T1") { - if (times_ == SingleQ) + if (times_ == SingleQuotes) switch (type) { case ',': features.require("quotesinglbase"); break; case '<': features.require("guilsinglleft"); break;