X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetquotes.C;h=eb7c87e454086a3daf03fd07dfb4d88d9e4f1ca6;hb=e28331ed63062dea10d0a21b9ec12034b4b17b9a;hp=2f917efe2012edc62d703ef1c0ba6e4c7496639f;hpb=7521b5d20f42102cf444e3fd8718a088a60d0098;p=lyx.git diff --git a/src/insets/insetquotes.C b/src/insets/insetquotes.C index 2f917efe20..eb7c87e454 100644 --- a/src/insets/insetquotes.C +++ b/src/insets/insetquotes.C @@ -1,41 +1,56 @@ -/* This file is part of - * ====================================================== - * - * LyX, The Document Processor - * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. +/** + * \file insetquotes.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * ====================================================== */ + * \author Jean-Marc Lasgouttes + * + * Full author contact details are available in file CREDITS. + */ #include -#ifdef __GNUG__ -#pragma implementation -#endif - #include "insetquotes.h" -#include "support/lyxlib.h" -#include "debug.h" -#include "lyxfont.h" -#include "lyxrc.h" + #include "buffer.h" +#include "bufferparams.h" +#include "debug.h" +#include "language.h" #include "LaTeXFeatures.h" +#include "lyxlex.h" +#include "lyxrc.h" +#include "metricsinfo.h" +#include "outputparams.h" +#include "paragraph.h" +#include "paragraph_funcs.h" + +#include "frontends/FontMetrics.h" +#include "frontends/Painter.h" + #include "support/lstrings.h" -#include "Painter.h" -#include "font.h" -#include "language.h" -#include "BufferView.h" -using std::ostream; + +namespace lyx { + +using support::prefixIs; + using std::endl; +using std::string; +using std::auto_ptr; +using std::ostream; -// Quotes. Used for the various quotes. German, English, French, -// Danish, Polish, all either double or single. namespace { -// codes used to read/write quotes to LyX files +/* codes used to read/write quotes to LyX files + * e ``english'' + * s ''spanish'' + * g ,,german`` + * p ,,polish'' + * f <> + * a >>danish<< + */ + char const * const language_char = "esgpfa"; char const * const side_char = "lr" ; char const * const times_char = "sd"; @@ -45,24 +60,24 @@ char const * const quote_char = ",'`<>"; // Index of chars used for the quote. Index is [side, language] int quote_index[2][6] = { - { 2, 1, 0, 0, 3, 4 }, // "'',,<>" + { 2, 1, 0, 0, 3, 4 }, // "'',,<>" { 1, 1, 2, 1, 4, 3 } }; // "`'`'><" // Corresponding LaTeX code, for double and single quotes. -char const * const latex_quote_t1[2][5] = -{ { "\\quotesinglbase{}", "'", "`", - "\\guilsinglleft{}", "\\guilsinglright{}" }, +char const * const latex_quote_t1[2][5] = +{ { "\\quotesinglbase ", "'", "`", + "\\guilsinglleft{}", "\\guilsinglright{}" }, { ",,", "''", "``", "<<", ">>" } }; -char const * const latex_quote_ot1[2][5] = -{ { "\\quotesinglbase{}", "'", "`", - "\\guilsinglleft{}", "\\guilsinglright{}" }, - { "\\quotedblbase{}", "''", "``", +char const * const latex_quote_ot1[2][5] = +{ { "\\quotesinglbase ", "'", "`", + "\\guilsinglleft{}", "\\guilsinglright{}" }, + { "\\quotedblbase ", "''", "``", "\\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 @@ -70,28 +85,42 @@ char const * const latex_quote_babel[2][5] = InsetQuotes::InsetQuotes(string const & str) { parseString(str); + setInsetName(from_utf8("InsetQuotes")); } -InsetQuotes::InsetQuotes(InsetQuotes::quote_language l, - InsetQuotes::quote_side s, - InsetQuotes::quote_times t) - : language(l), side(s), times(t) -{} +InsetQuotes::InsetQuotes(quote_language l, quote_side s, quote_times t) + : language_(l), side_(s), times_(t) +{ + setInsetName(from_utf8("InsetQuotes")); +} + + +InsetQuotes::InsetQuotes(char_type c, BufferParams const & params) + : language_(params.quotes_language), times_(params.quotes_times) +{ + getPosition(c); + setInsetName(from_utf8("InsetQuotes")); +} + + +InsetQuotes::InsetQuotes(char_type c, quote_language l, quote_times t) + : language_(l), times_(t) +{ + getPosition(c); + setInsetName(from_utf8("InsetQuotes")); +} -InsetQuotes::InsetQuotes(char c, BufferParams const & params) - : language(params.quotes_language), times(params.quotes_times) +void InsetQuotes::getPosition(char_type c) { - // Decide whether left or right + // Decide whether left or right switch (c) { - case ' ': case '(': case '{': case '[': case '-': case ':': - case Paragraph::META_HFILL: - case Paragraph::META_NEWLINE: - side = InsetQuotes::LeftQ; // left quote + case ' ': case '(': case '[': + side_ = LeftQ; // left quote break; default: - side = InsetQuotes::RightQ; // right quote + side_ = RightQ; // right quote } } @@ -106,194 +135,217 @@ void InsetQuotes::parseString(string const & s) } int i; - + for (i = 0; i < 6; ++i) { if (str[0] == language_char[i]) { - language = InsetQuotes::quote_language(i); + language_ = quote_language(i); break; } } if (i >= 6) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad language specification." << endl; - language = InsetQuotes::EnglishQ; + language_ = EnglishQ; } for (i = 0; i < 2; ++i) { if (str[1] == side_char[i]) { - side = InsetQuotes::quote_side(i); + side_ = quote_side(i); break; } } if (i >= 2) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad side specification." << endl; - side = InsetQuotes::LeftQ; + side_ = LeftQ; } for (i = 0; i < 2; ++i) { if (str[2] == times_char[i]) { - times = InsetQuotes::quote_times(i); + times_ = quote_times(i); break; } } if (i >= 2) { lyxerr << "ERROR (InsetQuotes::InsetQuotes):" " bad times specification." << endl; - times = InsetQuotes::DoubleQ; + times_ = DoubleQ; } } -string const InsetQuotes::dispString() const +docstring const InsetQuotes::dispString(Language const * loclang) const { - string disp; - disp += quote_char[quote_index[side][language]]; - if (times == InsetQuotes::DoubleQ) + string disp; + disp += quote_char[quote_index[side_][language_]]; + if (times_ == DoubleQ) disp += disp; - if (lyxrc.font_norm_type == LyXRC::ISO_8859_1) - if (disp == "<<") - disp = '«'; - else if (disp == ">>") - disp = '»'; - - return disp; -} - - -int InsetQuotes::ascent(BufferView *, LyXFont const & font) const -{ - return lyxfont::maxAscent(font); -} + 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); + + // in french, spaces are added inside double quotes + if (times_ == DoubleQ && prefixIs(loclang->code(), "fr")) { + if (side_ == LeftQ) + retdisp += ' '; + else + retdisp.insert(docstring::size_type(0), 1, ' '); + } -int InsetQuotes::descent(BufferView *, LyXFont const & font) const -{ - return lyxfont::maxDescent(font); + return retdisp; } -int InsetQuotes::width(BufferView *, LyXFont const & font) const +bool InsetQuotes::metrics(MetricsInfo & mi, Dimension & dim) const { - string text = dispString(); - int w = 0; - + LyXFont & 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()); for (string::size_type i = 0; i < text.length(); ++i) { if (text[i] == ' ') - w += lyxfont::width('i', font); - else if (i == 0 || text[i] != text[i-1]) - w += lyxfont::width(text[i], font); + dim.wid += fm.width('i'); + else if (i == 0 || text[i] != text[i - 1]) + dim.wid += fm.width(text[i]); else - w += lyxfont::width(',', font); + dim.wid += fm.width(','); } - - return w; + bool const changed = dim_ != dim; + dim_ = dim; + return changed; } +#if 0 LyXFont const InsetQuotes::convertFont(LyXFont const & f) const { +#if 1 + return f; +#else LyXFont font(f); -#ifndef NO_LATEX - // quotes-insets cannot be latex of any kind - font.setLatex(LyXFont::OFF); -#endif return font; +#endif } +#endif -void InsetQuotes::draw(BufferView * bv, LyXFont const & font, - int baseline, float & x, bool) const +void InsetQuotes::draw(PainterInfo & pi, int x, int y) const { - string text = dispString(); + docstring const text = dispString(pi.base.font.language()); - bv->painter().text(int(x), baseline, text, font); - x += width(bv, font); + 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) + .width(','); + pi.pain.text(x + t, y, text[0], pi.base.font); + } else { + pi.pain.text(x, y, text, pi.base.font); + } + setPosCache(pi, x, y); } -void InsetQuotes::write(Buffer const *, ostream & os) const +void InsetQuotes::write(Buffer const &, ostream & os) const { string text; - text += language_char[language]; - text += side_char[side]; - text += times_char[times]; + text += language_char[language_]; + text += side_char[side_]; + text += times_char[times_]; os << "Quotes " << text; } -void InsetQuotes::read(Buffer const *, LyXLex & lex) +void InsetQuotes::read(Buffer const &, LyXLex & lex) { - lex.nextToken(); - parseString(lex.GetString()); lex.next(); - string tmp(lex.GetString()); - if (tmp != "\\end_inset") - lyxerr << "LyX Warning: Missing \\end_inset " - "in InsetQuotes::Read." << endl; + parseString(lex.getString()); + lex.next(); + if (lex.getString() != "\\end_inset") { + lex.printError("Missing \\end_inset at this point"); + } } -extern bool use_babel; - -int InsetQuotes::latex(Buffer const * buf, ostream & os, - bool /*fragile*/, bool) const +int InsetQuotes::latex(Buffer const &, odocstream & os, + OutputParams const & runparams) const { - string const doclang = buf->getLanguage()->lang(); - int quoteind = quote_index[side][language]; + const int quoteind = quote_index[side_][language_]; string qstr; - - if (lyxrc.fontenc == "T1") { - qstr = latex_quote_t1[times][quoteind]; + + if (language_ == FrenchQ && times_ == DoubleQ + && prefixIs(runparams.local_font->language()->code(), "fr")) { + if (side_ == LeftQ) + qstr = "\\og "; //the spaces are important here + else + qstr = " \\fg{}"; //and here + } else if (lyxrc.fontenc == "T1") { + qstr = latex_quote_t1[times_][quoteind]; #ifdef DO_USE_DEFAULT_LANGUAGE } else if (doclang == "default") { #else - } else if (!use_babel) { + } else if (!runparams.use_babel) { #endif - qstr = latex_quote_ot1[times][quoteind]; - } else if (language == InsetQuotes::FrenchQ - && times == InsetQuotes::DoubleQ - && doclang == "frenchb") { - if (side == InsetQuotes::LeftQ) - qstr = "\\og{}"; - else - qstr = " \\fg{}"; - } else - qstr = latex_quote_babel[times][quoteind]; + qstr = latex_quote_ot1[times_][quoteind]; + } else { + qstr = latex_quote_babel[times_][quoteind]; + } // Always guard against unfortunate ligatures (!` ?`) if (prefixIs(qstr, "`")) qstr.insert(0, "{}"); - os << qstr; + os << from_ascii(qstr); return 0; } -int InsetQuotes::ascii(Buffer const *, ostream & os, int) const +int InsetQuotes::plaintext(Buffer const & buf, odocstream & os, + OutputParams const &) const { - os << "\""; + os << dispString(buf.params().language); return 0; } -int InsetQuotes::linuxdoc(Buffer const *, ostream & os) const +int InsetQuotes::docbook(Buffer const &, odocstream & os, + OutputParams const &) const { - os << "\""; - return 0; -} - - -int InsetQuotes::docBook(Buffer const *, ostream & os) const -{ - if (times == InsetQuotes::DoubleQ) { - if (side == InsetQuotes::LeftQ) + if (times_ == DoubleQ) { + if (side_ == LeftQ) os << "“"; else os << "”"; } else { - if (side == InsetQuotes::LeftQ) + if (side_ == LeftQ) os << "‘"; else os << "’"; @@ -302,37 +354,51 @@ int InsetQuotes::docBook(Buffer const *, ostream & os) const } -void InsetQuotes::validate(LaTeXFeatures & features) const +void InsetQuotes::textString(Buffer const & buf, odocstream & os) const +{ + os << dispString(buf.params().language); +} + + +void InsetQuotes::validate(LaTeXFeatures & features) const { - char type = quote_char[quote_index[side][language]]; + bool const use_babel = features.useBabel(); + char type = quote_char[quote_index[side_][language_]]; - if (features.bufferParams().language->lang() == "default" +#ifdef DO_USE_DEFAULT_LANGUAGE + if (features.bufferParams().language->lang() == "default" +#else + if (!use_babel +#endif && lyxrc.fontenc != "T1") { - if (times == InsetQuotes::SingleQ) + if (times_ == SingleQ) switch (type) { - case ',': features.quotesinglbase = true; break; - case '<': features.guilsinglleft = true; break; - case '>': features.guilsinglright = true; break; + case ',': features.require("quotesinglbase"); break; + case '<': features.require("guilsinglleft"); break; + case '>': features.require("guilsinglright"); break; default: break; } - else + else switch (type) { - case ',': features.quotedblbase = true; break; - case '<': features.guillemotleft = true; break; - case '>': features.guillemotright = true; break; + case ',': features.require("quotedblbase"); break; + case '<': features.require("guillemotleft"); break; + case '>': features.require("guillemotright"); break; default: break; } } } -Inset * InsetQuotes::clone(Buffer const &, bool) const +auto_ptr InsetQuotes::doClone() const { - return new InsetQuotes(language, side, times); + return auto_ptr(new InsetQuotes(language_, side_, times_)); } -Inset::Code InsetQuotes::lyxCode() const +InsetBase::Code InsetQuotes::lyxCode() const { - return Inset::QUOTE_CODE; + return InsetBase::QUOTE_CODE; } + + +} // namespace lyx