X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetListings.cpp;h=bec33b12cb44ee86ce28d927a1757a21a34cb99d;hb=239b9919ffe28338d789e6dc9122228f77ab77a7;hp=566636d68e753e76bc631bcfa18c72f4eb0997b6;hpb=9b7ccbfc8016398705583d6973395dfb46dceb8f;p=lyx.git diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp index 566636d68e..bec33b12cb 100644 --- a/src/insets/InsetListings.cpp +++ b/src/insets/InsetListings.cpp @@ -30,6 +30,8 @@ #include "output_xhtml.h" #include "OutputParams.h" #include "TextClass.h" +#include "TexRow.h" +#include "texstream.h" #include "support/debug.h" #include "support/docstream.h" @@ -122,13 +124,16 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const bool encoding_switched = false; Encoding const * const save_enc = runparams.encoding; - - if (!runparams.isFullUnicode() - && !runparams.encoding->hasFixedWidth()) { - // We need to switch to a singlebyte encoding, since the - // listings package cannot deal with multi-byte-encoded - // glyphs (not needed with full-unicode aware backends - // such as XeTeX). + // The listings package cannot deal with multi-byte-encoded + // glyphs, except if full-unicode aware backends + // such as XeTeX or LuaTeX are used, and with pLaTeX. + bool const multibyte_possible = runparams.isFullUnicode() + || (buffer().params().encoding().package() == Encoding::japanese + && runparams.encoding->package() == Encoding::japanese); + + if (!multibyte_possible && !runparams.encoding->hasFixedWidth()) { + // We need to switch to a singlebyte encoding, due to + // the restrictions of the listings package (see above). // This needs to be consistent with // LaTeXFeatures::getTClassI18nPreamble(). Language const * const outer_language = @@ -153,8 +158,20 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const if (i == 0 && par->isInset(i) && i + 1 == siz) captionline = true; // ignore all struck out text and (caption) insets - if (par->isDeleted(i) || par->isInset(i)) + if (par->isDeleted(i) + || (par->isInset(i) && par->getInset(i)->lyxCode() == CAPTION_CODE)) + continue; + if (par->isInset(i)) { + // Currently, this can only be a quote inset + // that is output as plain quote here, but + // we use more generic code anyway. + otexstringstream ots; + OutputParams rp = runparams; + rp.pass_thru = true; + par->getInset(i)->latex(ots, rp); + code += ots.str(); continue; + } char_type c = par->getChar(i); // we can only output characters covered by the current // encoding! @@ -218,13 +235,16 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const } else { OutputParams rp = runparams; rp.moving_arg = true; - docstring const caption = getCaption(rp); - if (param_string.empty() && caption.empty()) - os << breakln << "\\begin{lstlisting}\n"; + TexString caption = getCaption(rp); + os << breakln << "\\begin{lstlisting}"; + if (param_string.empty() && caption.str.empty()) + os << "\n"; else { - os << breakln << "\\begin{lstlisting}["; - if (!caption.empty()) { - os << "caption={" << caption << '}'; + if (!runparams.nice) + os << safebreakln; + os << "["; + if (!caption.str.empty()) { + os << "caption={" << move(caption) << '}'; if (!param_string.empty()) os << ','; } @@ -242,10 +262,20 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const if (!uncodable.empty() && !runparams.silent) { // issue a warning about omitted characters // FIXME: should be passed to the error dialog - frontend::Alert::warning(_("Uncodable characters in listings inset"), - bformat(_("The following characters in one of the program listings are\n" - "not representable in the current encoding and have been omitted:\n%1$s."), - uncodable)); + if (!multibyte_possible && !runparams.encoding->hasFixedWidth()) + frontend::Alert::warning(_("Uncodable characters in listings inset"), + bformat(_("The following characters in one of the program listings are\n" + "not representable in the current encoding and have been omitted:\n%1$s.\n" + "This is due to a restriction of the listings package, which does\n" + "not support your encoding '%2$s'.\n" + "Toggling 'Use non-TeX fonts' in Document > Settings...\n" + "might help."), + uncodable, _(runparams.encoding->guiName()))); + else + frontend::Alert::warning(_("Uncodable characters in listings inset"), + bformat(_("The following characters in one of the program listings are\n" + "not representable in the current encoding and have been omitted:\n%1$s."), + uncodable)); } } @@ -259,10 +289,10 @@ docstring InsetListings::xhtml(XHTMLStream & os, OutputParams const & rp) const if (isInline) out << html::CompTag("br"); else { - out << html::StartTag("div", "class='float float-listings'"); + out << html::StartTag("div", "class='float-listings'"); docstring caption = getCaptionHTML(rp); if (!caption.empty()) - out << html::StartTag("div", "class='float-caption'") + out << html::StartTag("div", "class='listings-caption'") << XHTMLStream::ESCAPE_NONE << caption << html::EndTag("div"); } @@ -358,6 +388,7 @@ docstring const InsetListings::buttonLabel(BufferView const & bv) const void InsetListings::validate(LaTeXFeatures & features) const { features.require("listings"); + features.useInsetLayout(getLayout()); string param_string = params().params(); if (param_string.find("\\color") != string::npos) features.require("color"); @@ -373,24 +404,23 @@ bool InsetListings::showInsetDialog(BufferView * bv) const } -docstring InsetListings::getCaption(OutputParams const & runparams) const +TexString InsetListings::getCaption(OutputParams const & runparams) const { - if (paragraphs().empty()) - return docstring(); - InsetCaption const * ins = getCaptionInset(); if (ins == 0) - return docstring(); + return TexString(); - TexRow texrow; - odocstringstream ods; - otexstream os(ods, texrow); + otexstringstream os; ins->getArgs(os, runparams); ins->getArgument(os, runparams); + + // TODO: The code below should be moved to support, and then the test + // in ../tests should be moved there as well. + // the caption may contain \label{} but the listings // package prefer caption={}, label={} - docstring cap = ods.str(); - if (!contains(to_utf8(cap), "\\label{")) + TexString cap = os.release(); + if (!contains(cap.str, from_ascii("\\label{"))) return cap; // convert from // blah1\label{blah2} blah3 @@ -401,8 +431,12 @@ docstring InsetListings::getCaption(OutputParams const & runparams) const // // NOTE that } is not allowed in blah2. regex const reg("(.*)\\\\label\\{(.*?)\\}(.*)"); - string const new_cap("\\1\\3},label={\\2"); - return from_utf8(regex_replace(to_utf8(cap), reg, new_cap)); + string const new_cap("$1$3},label={$2"); + // TexString validity: the substitution preserves the number of newlines. + // Moreover we assume that $2 does not contain newlines, so that the texrow + // information remains accurate. + cap.str = from_utf8(regex_replace(to_utf8(cap.str), reg, new_cap)); + return cap; }