X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Foutput_latex.cpp;h=2f919f4fec998973bbf7375dd1d94d1aae2d6b5c;hb=1797f5218b8819874f9dbe97b44445b3b5d598a0;hp=c1d3000077a4d2fc6d5b609b0d6ee1e08a4c378e;hpb=f401ce5d29cd83ace9d1925cc8c24ceb7a6a41e6;p=lyx.git diff --git a/src/output_latex.cpp b/src/output_latex.cpp index c1d3000077..2f919f4fec 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -30,6 +30,7 @@ #include "insets/InsetBibitem.h" #include "insets/InsetOptArg.h" +#include "support/lassert.h" #include "support/debug.h" #include "support/lstrings.h" @@ -38,16 +39,16 @@ using namespace std; using namespace lyx::support; + namespace lyx { namespace { - enum OpenEncoding { none, inputenc, CJK - }; +}; static int open_encoding_ = none; static bool cjk_inherited_ = false; @@ -83,7 +84,7 @@ TeXDeeper(Buffer const & buf, while (par != paragraphs.end() && par->params().depth() == pit->params().depth()) { - if (par->layout()->isEnvironment()) { + if (par->layout().isEnvironment()) { par = TeXEnvironment(buf, text, par, os, texrow, runparams); } else { @@ -108,8 +109,8 @@ TeXEnvironment(Buffer const & buf, BufferParams const & bparams = buf.params(); - LayoutPtr const & style = pit->forceEmptyLayout() ? - &bparams.documentClass().emptyLayout() : pit->layout(); + Layout const & style = pit->forceEmptyLayout() ? + bparams.documentClass().emptyLayout() : pit->layout(); ParagraphList const & paragraphs = text.paragraphs(); @@ -155,25 +156,25 @@ TeXEnvironment(Buffer const & buf, leftindent_open = true; } - if (style->isEnvironment()) { - os << "\\begin{" << from_ascii(style->latexname()) << '}'; - if (style->optionalargs > 0) { + if (style.isEnvironment()) { + os << "\\begin{" << from_ascii(style.latexname()) << '}'; + if (style.optionalargs > 0) { int ret = latexOptArgInsets(*pit, os, runparams, - style->optionalargs); + style.optionalargs); while (ret > 0) { texrow.newline(); --ret; } } - if (style->latextype == LATEX_LIST_ENVIRONMENT) { + if (style.latextype == LATEX_LIST_ENVIRONMENT) { os << '{' << pit->params().labelWidthString() << "}\n"; - } else if (style->labeltype == LABEL_BIBLIO) { + } else if (style.labeltype == LABEL_BIBLIO) { // ale970405 os << '{' << bibitemWidest(buf) << "}\n"; } else - os << from_ascii(style->latexparam()) << '\n'; + os << from_ascii(style.latexparam()) << '\n'; texrow.newline(); } @@ -199,11 +200,10 @@ TeXEnvironment(Buffer const & buf, os << '\n'; texrow.newline(); } else if (par->params().depth() > pit->params().depth()) { - if (par->layout()->isParagraph()) { + if (par->layout().isParagraph()) { // Thinko! // How to handle this? (Lgb) //&& !suffixIs(os, "\n\n") - //) { // There should be at least one '\n' already // but we need there to be two for Standard @@ -234,8 +234,8 @@ TeXEnvironment(Buffer const & buf, open_encoding_ = none; } - if (style->isEnvironment()) { - os << "\\end{" << from_ascii(style->latexname()) << "}\n"; + if (style.isEnvironment()) { + os << "\\end{" << from_ascii(style.latexname()) << "}\n"; texrow.newline(); } @@ -250,7 +250,7 @@ TeXEnvironment(Buffer const & buf, return par; } -} +} // namespace anon int latexOptArgInsets(Paragraph const & par, odocstream & os, @@ -277,7 +277,7 @@ namespace { ParagraphList::const_iterator TeXOnePar(Buffer const & buf, Text const & text, - ParagraphList::const_iterator pit, + ParagraphList::const_iterator const pit, odocstream & os, TexRow & texrow, OutputParams const & runparams_in, string const & everypar) @@ -287,6 +287,13 @@ TeXOnePar(Buffer const & buf, BufferParams const & bparams = buf.params(); ParagraphList const & paragraphs = text.paragraphs(); + ParagraphList::const_iterator priorpit = pit; + if (priorpit != paragraphs.begin()) + --priorpit; + ParagraphList::const_iterator nextpit = pit; + if (nextpit != paragraphs.end()) + ++nextpit; + if (runparams_in.verbatim) { int const dist = distance(paragraphs.begin(), pit); Font const outerfont = outerFont(dist, paragraphs); @@ -299,20 +306,14 @@ TeXOnePar(Buffer const & buf, /*bool need_par = */ pit->latex(bparams, outerfont, os, texrow, runparams_in); - - return ++pit; + return nextpit; } - // FIXME This comment doesn't make sense. What's the - // length got to do with forceEmptyLayout()? I.e., what - // was forceDefaultParagraphs()? - // In an inset with unlimited length (all in one row), - // force layout to default - LayoutPtr const style = pit->forceEmptyLayout() ? - &bparams.documentClass().emptyLayout() : pit->layout(); + Layout const style = pit->forceEmptyLayout() ? + bparams.documentClass().emptyLayout() : pit->layout(); OutputParams runparams = runparams_in; - runparams.moving_arg |= style->needprotect; + runparams.moving_arg |= style.needprotect; bool const maintext = text.isMainText(buf); // we are at the beginning of an inset and CJK is already open. @@ -335,15 +336,15 @@ TeXOnePar(Buffer const & buf, // if there is no previous paragraph Language const * const prev_language = (pit != paragraphs.begin()) ? - boost::prior(pit)->getParLanguage(bparams) : outer_language; + priorpit->getParLanguage(bparams) : outer_language; if (par_language->babel() != prev_language->babel() // check if we already put language command in TeXEnvironment() - && !(style->isEnvironment() + && !(style.isEnvironment() && (pit == paragraphs.begin() || - (boost::prior(pit)->layout() != pit->layout() && - boost::prior(pit)->getDepth() <= pit->getDepth()) - || boost::prior(pit)->getDepth() < pit->getDepth()))) + (priorpit->layout() != pit->layout() && + priorpit->getDepth() <= pit->getDepth()) + || priorpit->getDepth() < pit->getDepth()))) { if (!lyxrc.language_command_end.empty() && prev_language->babel() != outer_language->babel() && @@ -486,34 +487,34 @@ TeXOnePar(Buffer const & buf, if (!pit->params().spacing().isDefault() && (pit == paragraphs.begin() - || !boost::prior(pit)->hasSameLayout(*pit))) + || !priorpit->hasSameLayout(*pit))) { os << from_ascii(pit->params().spacing().writeEnvirBegin(useSetSpace)) << '\n'; texrow.newline(); } - if (style->isCommand()) { + if (style.isCommand()) { os << '\n'; texrow.newline(); } } - switch (style->latextype) { + switch (style.latextype) { case LATEX_COMMAND: - os << '\\' << from_ascii(style->latexname()); + os << '\\' << from_ascii(style.latexname()); // Separate handling of optional argument inset. - if (style->optionalargs > 0) { + if (style.optionalargs > 0) { int ret = latexOptArgInsets(*pit, os, runparams, - style->optionalargs); + style.optionalargs); while (ret > 0) { texrow.newline(); --ret; } } else - os << from_ascii(style->latexparam()); + os << from_ascii(style.latexparam()); break; case LATEX_ITEM_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: @@ -548,10 +549,10 @@ TeXOnePar(Buffer const & buf, ? pit->getLayoutFont(bparams, outerfont) : pit->getFont(bparams, pit->size() - 1, outerfont); - bool is_command = style->isCommand(); + bool is_command = style.isCommand(); - if (style->resfont.size() != font.fontInfo().size() - && boost::next(pit) != paragraphs.end() + if (style.resfont.size() != font.fontInfo().size() + && nextpit != paragraphs.end() && !is_command) { if (!need_par) os << '{'; @@ -562,20 +563,19 @@ TeXOnePar(Buffer const & buf, os << '}'; bool pending_newline = false; - switch (style->latextype) { + switch (style.latextype) { case LATEX_ITEM_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: - if (boost::next(pit) != paragraphs.end() - && (pit->params().depth() < boost::next(pit)->params().depth())) + if (nextpit != paragraphs.end() + && (pit->params().depth() < nextpit->params().depth())) pending_newline = true; break; case LATEX_ENVIRONMENT: { // if its the last paragraph of the current environment // skip it otherwise fall through - ParagraphList::const_iterator next = boost::next(pit); + ParagraphList::const_iterator next = nextpit; - if (next != paragraphs.end() - && (next->layout() != pit->layout() + if (next != paragraphs.end() && (next->layout() != pit->layout() || next->params().depth() != pit->params().depth())) break; } @@ -583,14 +583,13 @@ TeXOnePar(Buffer const & buf, // fall through possible default: // we don't need it for the last paragraph!!! - if (boost::next(pit) != paragraphs.end()) + if (nextpit != paragraphs.end()) pending_newline = true; } if (pit->allowParagraphCustomization()) { if (!pit->params().spacing().isDefault() - && (boost::next(pit) == paragraphs.end() - || !boost::next(pit)->hasSameLayout(*pit))) + && (nextpit == paragraphs.end() || !nextpit->hasSameLayout(*pit))) { if (pending_newline) { os << '\n'; @@ -612,13 +611,13 @@ TeXOnePar(Buffer const & buf, runparams.local_font != 0 && runparams.local_font->isRightToLeft() != par_language->rightToLeft() && // are we about to close the language? - ((boost::next(pit) != paragraphs.end() && + ((nextpit != paragraphs.end() && par_language->babel() != - (boost::next(pit)->getParLanguage(bparams))->babel()) || - (boost::next(pit) == paragraphs.end() && + (nextpit->getParLanguage(bparams))->babel()) || + (nextpit == paragraphs.end() && par_language->babel() != outer_language->babel())); - if (closing_rtl_ltr_environment || (boost::next(pit) == paragraphs.end() + if (closing_rtl_ltr_environment || (nextpit == paragraphs.end() && par_language->babel() != outer_language->babel())) { // Since \selectlanguage write the language to the aux file, // we need to reset the language at the end of footnote or @@ -657,18 +656,18 @@ TeXOnePar(Buffer const & buf, // if this is a CJK-paragraph and the next isn't, close CJK // also if the next paragraph is a multilingual environment (because of nesting) - if (boost::next(pit) != paragraphs.end() && open_encoding_ == CJK && - (boost::next(pit)->getParLanguage(bparams)->encoding()->package() != Encoding::CJK || - boost::next(pit)->layout()->isEnvironment() && boost::next(pit)->isMultiLingual(bparams)) + if (nextpit != paragraphs.end() && open_encoding_ == CJK && + (nextpit->getParLanguage(bparams)->encoding()->package() != Encoding::CJK || + nextpit->layout().isEnvironment() && nextpit->isMultiLingual(bparams)) // in environments, CJK has to be closed later (nesting!) - && !style->isEnvironment()) { + && !style.isEnvironment()) { os << "\\end{CJK}\n"; open_encoding_ = none; } // If this is the last paragraph, close the CJK environment // if necessary. If it's an environment, we'll have to \end that first. - if (boost::next(pit) == paragraphs.end() && !style->isEnvironment()) { + if (nextpit == paragraphs.end() && !style.isEnvironment()) { switch (open_encoding_) { case CJK: { // end of main text @@ -696,16 +695,12 @@ TeXOnePar(Buffer const & buf, } // If this is the last paragraph, and a local_font was set upon entering - // the inset, the encoding should be set back to that local_font's - // encoding. We don't use switchEncoding(), because no explicit encoding - // switch command is needed, since latex will automatically revert to it - // when this inset closes. - // This switch is only necessary if we're using "auto" or "default" - // encoding. - if (boost::next(pit) == paragraphs.end() && runparams_in.local_font != 0) { + // the inset, and we're using "auto" or "default" encoding, the encoding + // should be set back to that local_font's encoding. + if (nextpit == paragraphs.end() && runparams_in.local_font != 0 + && (bparams.inputenc == "auto" || bparams.inputenc == "default")) { runparams_in.encoding = runparams_in.local_font->language()->encoding(); - if (bparams.inputenc == "auto" || bparams.inputenc == "default") - os << setEncoding(runparams_in.encoding->iconvName()); + os << setEncoding(runparams_in.encoding->iconvName()); } // Otherwise, the current encoding should be set for the next paragraph. @@ -716,15 +711,15 @@ TeXOnePar(Buffer const & buf, // we don't need it for the last paragraph!!! // Note from JMarc: we will re-add a \n explicitely in // TeXEnvironment, because it is needed in this case - if (boost::next(pit) != paragraphs.end()) { + if (nextpit != paragraphs.end()) { os << '\n'; texrow.newline(); } - if (boost::next(pit) != paragraphs.end()) - LYXERR(Debug::LATEX, "TeXOnePar...done " << &*boost::next(pit)); + if (nextpit != paragraphs.end()) + LYXERR(Debug::LATEX, "TeXOnePar...done " << &*nextpit); - return ++pit; + return nextpit; } } // anon namespace @@ -746,7 +741,7 @@ void latexParagraphs(Buffer const & buf, ParagraphList::const_iterator par = paragraphs.begin(); ParagraphList::const_iterator endpar = paragraphs.end(); - BOOST_ASSERT(runparams.par_begin <= runparams.par_end); + LASSERT(runparams.par_begin <= runparams.par_end, /**/); // if only part of the paragraphs will be outputed if (runparams.par_begin != runparams.par_end) { par = boost::next(paragraphs.begin(), runparams.par_begin); @@ -783,55 +778,45 @@ void latexParagraphs(Buffer const & buf, // if only_body while (par != endpar) { lastpar = par; - // well we have to check if we are in an inset with unlimited - // length (all in one row) if that is true then we don't allow - // any special options in the paragraph and also we don't allow - // any environment other than the default layout of the - // text class to be valid! - if (par->allowParagraphCustomization()) { - LayoutPtr const & layout = par->forceEmptyLayout() ? - &tclass.emptyLayout() : - par->layout(); - - if (layout->intitle) { - if (already_title) { - lyxerr << "Error in latexParagraphs: You" - " should not mix title layouts" - " with normal ones." << endl; - } else if (!was_title) { - was_title = true; - if (tclass.titletype() == TITLE_ENVIRONMENT) { - os << "\\begin{" - << from_ascii(tclass.titlename()) - << "}\n"; - texrow.newline(); - } - } - } else if (was_title && !already_title) { + Layout const & layout = par->forceEmptyLayout() ? + tclass.emptyLayout() : + par->layout(); + + if (layout.intitle) { + if (already_title) { + lyxerr << "Error in latexParagraphs: You" + " should not mix title layouts" + " with normal ones." << endl; + } else if (!was_title) { + was_title = true; if (tclass.titletype() == TITLE_ENVIRONMENT) { - os << "\\end{" << from_ascii(tclass.titlename()) - << "}\n"; - } - else { - os << "\\" << from_ascii(tclass.titlename()) - << "\n"; + os << "\\begin{" + << from_ascii(tclass.titlename()) + << "}\n"; + texrow.newline(); } - texrow.newline(); - already_title = true; - was_title = false; } - - if (layout->is_environment) { - par = TeXOnePar(buf, text, par, os, texrow, - runparams, everypar); - } else if (layout->isEnvironment() || - !par->params().leftIndent().zero()) { - par = TeXEnvironment(buf, text, par, os, - texrow, runparams); - } else { - par = TeXOnePar(buf, text, par, os, texrow, - runparams, everypar); + } else if (was_title && !already_title) { + if (tclass.titletype() == TITLE_ENVIRONMENT) { + os << "\\end{" << from_ascii(tclass.titlename()) + << "}\n"; + } + else { + os << "\\" << from_ascii(tclass.titlename()) + << "\n"; } + texrow.newline(); + already_title = true; + was_title = false; + } + + if (layout.is_environment) { + par = TeXOnePar(buf, text, par, os, texrow, + runparams, everypar); + } else if (layout.isEnvironment() || + !par->params().leftIndent().zero()) { + par = TeXEnvironment(buf, text, par, os, + texrow, runparams); } else { par = TeXOnePar(buf, text, par, os, texrow, runparams, everypar); @@ -839,6 +824,7 @@ void latexParagraphs(Buffer const & buf, if (distance(lastpar, par) >= distance(lastpar, endpar)) break; } + // It might be that we only have a title in this document if (was_title && !already_title) { if (tclass.titletype() == TITLE_ENVIRONMENT) { @@ -851,6 +837,7 @@ void latexParagraphs(Buffer const & buf, } texrow.newline(); } + // if "auto end" is switched off, explicitely close the language at the end // but only if the last par is in a babel language if (maintext && !lyxrc.language_auto_end && !bparams.language->babel().empty() && @@ -861,6 +848,7 @@ void latexParagraphs(Buffer const & buf, << '\n'; texrow.newline(); } + // If the last paragraph is an environment, we'll have to close // CJK at the very end to do proper nesting. if (maintext && open_encoding_ == CJK) { @@ -868,6 +856,7 @@ void latexParagraphs(Buffer const & buf, texrow.newline(); open_encoding_ = none; } + // reset inherited encoding if (cjk_inherited_) { open_encoding_ = CJK;