X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetQuotes.cpp;h=1295f27f0753e0949fa11144ea9f9ddc4f193345;hb=9c4929ca406091267dafa40f5e083a27db046bf6;hp=fa2558150fff1829debd9b6e6d5191e1698a5b0a;hpb=4c82dd1fc8d8b90c89a77bfcb3503d1dcae49d94;p=lyx.git diff --git a/src/insets/InsetQuotes.cpp b/src/insets/InsetQuotes.cpp index fa2558150f..1295f27f07 100644 --- a/src/insets/InsetQuotes.cpp +++ b/src/insets/InsetQuotes.cpp @@ -14,34 +14,35 @@ #include "Buffer.h" #include "BufferParams.h" -#include "debug.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" +#include "support/debug.h" +#include "support/docstring.h" +#include "support/docstream.h" #include "support/lstrings.h" +using namespace std; +using namespace lyx::support; namespace lyx { -using support::prefixIs; - -using std::endl; -using std::string; -using std::ostream; - - namespace { /* codes used to read/write quotes to LyX files * e ``english'' - * s ''spanish'' + * s ''swedish'' * g ,,german`` * p ,,polish'' * f <> @@ -55,72 +56,88 @@ 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 }, // "'',,<>" - { 1, 1, 2, 1, 4, 3 } }; // "`'`'><" + { 1, 1, 2, 1, 4, 3 } // "`'`'><" +}; // Corresponding LaTeX code, for double and single quotes. -char const * const latex_quote_t1[2][5] = -{ { "\\quotesinglbase ", "'", "`", +char const * const latex_quote_t1[2][5] = { + { "\\quotesinglbase ", "'", "`", "\\guilsinglleft{}", "\\guilsinglright{}" }, - { ",,", "''", "``", "<<", ">>" } }; + { ",,", "''", "``", "<<", ">>" } +}; -char const * const latex_quote_ot1[2][5] = -{ { "\\quotesinglbase ", "'", "`", +char const * const latex_quote_ot1[2][5] = { + { "\\quotesinglbase ", "'", "`", "\\guilsinglleft{}", "\\guilsinglright{}" }, { "\\quotedblbase ", "''", "``", - "\\guillemotleft{}", "\\guillemotright{}" } }; + "\\guillemotleft{}", "\\guillemotright{}" } +}; -char const * const latex_quote_babel[2][5] = -{ { "\\glq ", "'", "`", "\\flq{}", "\\frq{}" }, - { "\\glqq ", "''", "``", "\\flqq{}", "\\frqq{}" } }; +char const * const latex_quote_babel[2][5] = { + { "\\glq ", "'", "`", "\\flq{}", "\\frq{}" }, + { "\\glqq ", "''", "``", "\\flqq{}", "\\frqq{}" } +}; } // 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) +InsetQuotes::InsetQuotes(Buffer * buf, char_type c, QuoteTimes t) + : Inset(buf), times_(t) { - getPosition(c); + if (buf) + language_ = buf->params().quotes_language; + setSide(c); } -InsetQuotes::InsetQuotes(char_type c, quote_language l, quote_times t) - : language_(l), times_(t) +docstring InsetQuotes::layoutName() const { - getPosition(c); + 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 + case ' ': + case '(': + case '[': + side_ = LeftQuote; // left quote break; default: - side_ = RightQ; // right quote + side_ = RightQuote; // right quote } } void InsetQuotes::parseString(string const & s) { - string str(s); + string str = s; if (str.length() != 3) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad string length." << endl; @@ -131,99 +148,73 @@ 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 const InsetQuotes::dispString(Language const * loclang) const +docstring InsetQuotes::displayString() const { - 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 = lyx::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(docstring::size_type(0), 1, ' '); + retdisp.insert(size_t(0), 1, ' '); } return retdisp; } -bool InsetQuotes::metrics(MetricsInfo & mi, Dimension & dim) const +void InsetQuotes::metrics(MetricsInfo & mi, Dimension & dim) const { - Font & font = mi.base.font; + FontInfo & font = mi.base.font; frontend::FontMetrics const & fm = theFontMetrics(font); dim.asc = fm.maxAscent(); dim.des = fm.maxDescent(); dim.wid = 0; - docstring const text = dispString(font.language()); + // FIXME: should we add a language or a font parameter member? + docstring const text = displayString(); for (string::size_type i = 0; i < text.length(); ++i) { if (text[i] == ' ') dim.wid += fm.width('i'); @@ -232,41 +223,27 @@ bool InsetQuotes::metrics(MetricsInfo & mi, Dimension & dim) const else dim.wid += fm.width(','); } - bool const changed = dim_ != dim; - dim_ = dim; - return changed; -} - - -#if 0 -Font const InsetQuotes::convertFont(Font const & f) const -{ -#if 1 - return f; -#else - Font font(f); - return font; -#endif } -#endif void InsetQuotes::draw(PainterInfo & pi, int x, int y) const { - docstring const text = dispString(pi.base.font.language()); - + // FIXME: should we add a language or a font parameter member? + 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); } } -void InsetQuotes::write(Buffer const &, ostream & os) const +void InsetQuotes::write(ostream & os) const { string text; text += language_char[language_]; @@ -276,69 +253,68 @@ void InsetQuotes::write(Buffer const &, ostream & os) const } -void InsetQuotes::read(Buffer const &, Lexer & lex) +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(Buffer const &, 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(Buffer const & buf, odocstream & os, - OutputParams const &) const +int InsetQuotes::plaintext(odocstream & os, OutputParams const &) const { - docstring const str = dispString(buf.params().language); + docstring const str = displayString(); os << str; return str.size(); } -int InsetQuotes::docbook(Buffer const &, 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 << "’"; @@ -347,9 +323,22 @@ int InsetQuotes::docbook(Buffer const &, odocstream & os, } -void InsetQuotes::textString(Buffer const & buf, 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(buf.params().language); + os += displayString(); } @@ -364,9 +353,9 @@ 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("quotesinglbase"); break; case '<': features.require("guilsinglleft"); break; case '>': features.require("guilsinglright"); break; default: break; @@ -381,17 +370,4 @@ void InsetQuotes::validate(LaTeXFeatures & features) const } } - -Inset * InsetQuotes::clone() const -{ - return new InsetQuotes(language_, side_, times_); -} - - -Inset::Code InsetQuotes::lyxCode() const -{ - return Inset::QUOTE_CODE; -} - - } // namespace lyx