#include "output_latex.h"
+#include "BiblioInfo.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "Encoding.h"
// in multilingual environments, the CJK tags have to be nested properly
data.cjk_nested = false;
- if (data.par_language->encoding()->package() == Encoding::CJK &&
- state->open_encoding_ != CJK && pit->isMultiLingual(bparams)) {
+ if (!bparams.useNonTeXFonts
+ && (bparams.inputenc == "auto-legacy"
+ || bparams.inputenc == "auto-legacy-plain")
+ && data.par_language->encoding()->package() == Encoding::CJK
+ && state->open_encoding_ != CJK && pit->isMultiLingual(bparams)) {
if (prev_par_language->encoding()->package() == Encoding::CJK) {
- docstring const cjkenc = (bparams.encoding().name() == "utf8-cjk"
- && LaTeXFeatures::isAvailable("CJKutf8")) ?
- from_ascii("UTF8")
- : from_ascii(data.par_language->encoding()->latexName());
- os << "\\begin{CJK}{" << cjkenc
+ os << "\\begin{CJK}{"
+ << from_ascii(data.par_language->encoding()->latexName())
<< "}{" << from_ascii(bparams.fonts_cjk) << "}%\n";
}
state->open_encoding_ = CJK;
}
}
}
+ if (runparams.for_search) {
+ // Mark end of arguments for findadv() only
+ os << "\\endarguments{}";
+ }
}
os << " ";
}
break;
+ case LATEX_ENVIRONMENT:
+ if (runparams.for_search) {
+ os << "\\latexenvironment{" << style.latexname() << "}{";
+ }
+ break;
case LATEX_BIB_ENVIRONMENT:
// ignore this, the inset will write itself
break;
if (style.pass_thru) {
Font const outerfont = text.outerFont(pit);
parStartCommand(par, os, runparams, style);
+ if (style.isCommand() && style.needprotect)
+ // Due to the moving argument, some fragile
+ // commands (labels, index entries)
+ // are output after this command (#2154)
+ runparams.postpone_fragile_stuff = true;
if (intitle_command)
os << '{';
// (see #10849); thus open the command here.
if (intitle_command) {
parStartCommand(par, os, runparams, style);
+ if (style.isCommand() && style.needprotect)
+ // Due to the moving argument, some fragile
+ // commands (labels, index entries)
+ // are output after this command (#2154)
+ runparams.postpone_fragile_stuff = true;
os << '{';
}
lang_end_command = "}";
lang_command_termination.clear();
}
-
+
bool const localswitch_needed = localswitch && par_lang != outer_lang;
// localswitches need to be closed and reopened at each par
if (!localswitch
&& (!using_begin_end || langOpenedAtThisLevel(state))
&& !lang_end_command.empty()
- && prev_lang != outer_lang
+ && prev_lang != outer_lang
&& !prev_lang.empty()
&& (!using_begin_end || !style.isEnvironment())) {
os << from_ascii(subst(lang_end_command,
}
}
- // Switch file encoding if necessary; no need to do this for "default"
+ // Switch file encoding if necessary; no need to do this for "auto-legacy-plain"
// encoding, since this only affects the position of the outputted
// \inputencoding command; the encoding switch will occur when necessary
- if (bparams.inputenc == "auto"
+ if (bparams.inputenc == "auto-legacy"
&& !runparams.isFullUnicode() // Xe/LuaTeX use one document-wide encoding (see also switchEncoding())
+ && runparams.encoding->package() != Encoding::japanese
&& runparams.encoding->package() != Encoding::none) {
// Look ahead for future encoding changes.
// We try to output them at the beginning of the paragraph,
// context (nesting issue).
if (par_language->encoding()->package() == Encoding::CJK
&& state->open_encoding_ != CJK && state->cjk_inherited_ == 0) {
- docstring const cjkenc = (bparams.encoding().name() == "utf8-cjk"
- && LaTeXFeatures::isAvailable("CJKutf8")) ?
- from_ascii("UTF8")
- : from_ascii(par_language->encoding()->latexName());
- os << "\\begin{CJK}{" << cjkenc
+ os << "\\begin{CJK}{"
+ << from_ascii(par_language->encoding()->latexName())
<< "}{" << from_ascii(bparams.fonts_cjk) << "}%\n";
state->open_encoding_ = CJK;
}
}
runparams.moving_arg |= style.needprotect;
+ if (style.needmboxprotect)
+ ++runparams.inulemcmd;
Encoding const * const prev_encoding = runparams.encoding;
bool const useSetSpace = bparams.documentClass().provides("SetSpace");
// For InTitle commands, we already started the command before
// the language switch
- if (!intitle_command)
+ if (!intitle_command) {
parStartCommand(par, os, runparams, style);
+ if (style.isCommand() && style.needprotect)
+ // Due to the moving argument, some fragile
+ // commands (labels, index entries)
+ // are output after this command (#2154)
+ runparams.postpone_fragile_stuff = true;
+ }
Font const outerfont = text.outerFont(pit);
os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
+ if (!runparams.post_macro.empty()) {
+ // Output the stored fragile commands (labels, indices etc.)
+ // that need to be output after the command with moving argument.
+ os << runparams.post_macro;
+ runparams.post_macro.clear();
+ }
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName());
pending_newline = true;
break;
case LATEX_ENVIRONMENT: {
- // if its the last paragraph of the current environment
+ // if it's the last paragraph of the current environment
// skip it otherwise fall through
if (nextpar
&& ((nextpar->layout() != par.layout()
if (localswitch_needed
|| (intitle_command && using_begin_end)
|| closing_rtl_ltr_environment
- || ((runparams.isLastPar || close_lang_switch)
+ || (((runparams.isLastPar && !runparams.inbranch) || close_lang_switch)
&& (par_lang != outer_lang || (using_begin_end
&& style.isEnvironment()
&& par_lang != nextpar_lang)))) {
os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
+ if (!runparams.post_macro.empty()) {
+ // Output the stored fragile commands (labels, indices etc.)
+ // that need to be output after the command with moving argument.
+ os << runparams.post_macro;
+ runparams.post_macro.clear();
+ }
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName());
// 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 (nextpar
- && (state->open_encoding_ == CJK && bparams.encoding().iconvName() != "UTF-8")
+ && (state->open_encoding_ == CJK && bparams.encoding().iconvName() != "UTF-8"
+ && bparams.encoding().package() != Encoding::CJK )
&& (nextpar_language->encoding()->package() != Encoding::CJK
|| (nextpar->layout().isEnvironment() && nextpar->isMultiLingual(bparams)))
// inbetween environments, CJK has to be closed later (nesting!)
}
// 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 (runparams.isLastPar && !style.isEnvironment()) {
+ // if necessary. If it's an environment or nested in an environment,
+ // we'll have to \end that first.
+ if (runparams.isLastPar && !style.isEnvironment()
+ && par.params().depth() < 1) {
switch (state->open_encoding_) {
case CJK: {
// do nothing at the end of child documents
if (maintext && buf.masterBuffer() != &buf)
break;
- // end of main text
+ // end of main text: also insert a \clearpage (see #5386)
if (maintext) {
- os << "\n\\end{CJK}\n";
+ os << "\n\\clearpage\n\\end{CJK}\n";
// end of an inset
} else
os << "\\end{CJK}";
}
}
- // If this is the last paragraph, and a local_font was set upon entering
- // the inset, and we're using "auto" or "default" encoding, and not
- // compiling with XeTeX or LuaTeX, the encoding
- // should be set back to that local_font's encoding.
+ // Information about local language is stored as a font feature.
+ // If this is the last paragraph of the inset and a local_font was set upon entering
+ // and we are mixing encodings ("auto-legacy" or "auto-legacy-plain" and no XeTeX or LuaTeX),
+ // ensure the encoding is set back to the default encoding of the local language.
if (runparams.isLastPar && runparams_in.local_font != 0
&& runparams_in.encoding != runparams_in.local_font->language()->encoding()
- && (bparams.inputenc == "auto" || bparams.inputenc == "default")
+ && (bparams.inputenc == "auto-legacy" || bparams.inputenc == "auto-legacy-plain")
&& !runparams.isFullUnicode()
) {
runparams_in.encoding = runparams_in.local_font->language()->encoding();
else
runparams_in.encoding = runparams.encoding;
+ // Also pass the post_macros upstream
+ runparams_in.post_macro = runparams.post_macro;
+
// we don't need a newline for the last paragraph!!!
// Note from JMarc: we will re-add a \n explicitly in
&& nextpar->getAlign() == par.getAlign())
|| (!next_layout.isEnvironment()
&& nextpar->getDepth() > par.getDepth()
- && nextpar->getAlign() == par.getAlign())
+ && nextpar->getAlign() == next_layout.align)
|| (!style.isEnvironment()
&& next_layout.latextype == LATEX_ENVIRONMENT
&& nextpar->getDepth() < par.getDepth())
if (multibib_child && mparams.useBiblatex())
os << "\\newrefsection";
- else if (multibib_child && mparams.useBibtopic()) {
+ else if (multibib_child && mparams.useBibtopic()
+ && !buf.masterBibInfo().empty()) {
os << "\\begin{btUnit}\n";
runparams.openbtUnit = true;
}
// Open a CJK environment at the beginning of the main buffer
- // (but not in child documents or documents using system fonts)
- // if the document's language is a CJK language (with some exceptions)
- // or the document encoding is utf8-cjk:
+ // if the document's main encoding requires the CJK package
+ // or the document encoding is utf8 and the CJK package is required
+ // (but not in child documents or documents using system fonts):
OutputState * state = getOutputState();
if (maintext && !is_child && !bparams.useNonTeXFonts
- && ((bparams.language->encoding()->package() == Encoding::CJK
- && (bparams.encoding().iconvName() != "UTF-8"
- || bparams.encoding().name() == "utf8-cjk"
- || bparams.encoding().name() == "utf8" ))
- || (bparams.encoding().name() == "utf8-cjk"
- && LaTeXFeatures::isAvailable("CJKutf8")))) {
+ && (bparams.encoding().package() == Encoding::CJK
+ || (bparams.encoding().name() == "utf8"
+ && runparams.use_CJK))
+ ) {
docstring const cjkenc = bparams.encoding().iconvName() == "UTF-8"
? from_ascii("UTF8") : from_ascii(bparams.encoding().latexName());
os << "\\begin{CJK}{" << cjkenc
&& layout.latexname() == bparams.multibib) {
if (runparams.openbtUnit)
os << "\\end{btUnit}\n";
- if (!bparams.useBiblatex()) {
+ if (!bparams.useBiblatex()
+ && !buf.masterBibInfo().empty()) {
os << '\n' << "\\begin{btUnit}\n";
runparams.openbtUnit = true;
}
// If the last paragraph is an environment, we'll have to close
// CJK at the very end to do proper nesting.
if (maintext && !is_child && state->open_encoding_ == CJK) {
- os << "\\end{CJK}\n";
+ os << "\\clearpage\n\\end{CJK}\n";
state->open_encoding_ = none;
}
// Likewise for polyglossia or when using begin/end commands
+ // or after an active branch inset with a language switch
+ Language const * const outer_language = (runparams.local_font != 0)
+ ? runparams.local_font->language() : bparams.language;
+ string const & prev_lang = runparams.use_polyglossia
+ ? getPolyglossiaEnvName(outer_language)
+ : outer_language->babel();
string const & cur_lang = openLanguageName(state);
- if (maintext && !is_child && !cur_lang.empty()) {
+ if (((runparams.inbranch && langOpenedAtThisLevel(state) && prev_lang != cur_lang)
+ || (maintext && !is_child)) && !cur_lang.empty()) {
os << from_utf8(subst(lang_end_command,
"$$lang",
cur_lang))
<< '\n';
if (using_begin_end)
popLanguageName();
+ } else if (runparams.inbranch && !using_begin_end && prev_lang != cur_lang) {
+ os << subst(lang_begin_command, "$$lang", prev_lang) << '\n';
}
// reset inherited encoding
}
}
-
+// Switch the input encoding for some part(s) of the document.
pair<bool, int> switchEncoding(odocstream & os, BufferParams const & bparams,
OutputParams const & runparams, Encoding const & newEnc,
bool force, bool noswitchmacro)
{
- // XeTeX/LuaTeX use only one encoding per document:
- // * with useNonTeXFonts: "utf8plain",
- // * with XeTeX and TeX fonts: "ascii" (inputenc fails),
- // * with LuaTeX and TeX fonts: only one encoding accepted by luainputenc.
- if (runparams.isFullUnicode() || newEnc.name() == "inherit")
+ // Never switch encoding with non-TeX fonts (always "utf8plain"),
+ // with LuaTeX and TeX fonts (only one encoding accepted by luainputenc),
+ // or if we're in a moving argument or inherit the outer encoding.
+ if (bparams.useNonTeXFonts
+ || runparams.flavor == OutputParams::LUATEX
+ || runparams.flavor == OutputParams::DVILUATEX
+ || newEnc.name() == "inherit")
+ return make_pair(false, 0);
+
+ // Only switch for auto-selected legacy encodings (inputenc setting
+ // "auto-legacy" or "auto-legacy-plain").
+ // The "listings" environment can force a switch also with other
+ // encoding settings (it does not support variable width encodings
+ // (utf8, jis, ...) under 8-bit latex engines).
+ if (!force && ((bparams.inputenc != "auto-legacy" && bparams.inputenc != "auto-legacy-plain")
+ || runparams.moving_arg))
return make_pair(false, 0);
Encoding const & oldEnc = *runparams.encoding;
- bool moving_arg = runparams.moving_arg;
- // If we switch from/to CJK, we need to switch anyway, despite custom inputenc,
- // except if we use CJKutf8
- bool const from_to_cjk =
- ((oldEnc.package() == Encoding::CJK && newEnc.package() != Encoding::CJK)
- || (oldEnc.package() != Encoding::CJK && newEnc.package() == Encoding::CJK))
- && (bparams.encoding().name() != "utf8-cjk" || !LaTeXFeatures::isAvailable("CJKutf8"));
- if (!force && !from_to_cjk
- && ((bparams.inputenc != "auto" && bparams.inputenc != "default") || moving_arg))
+ // Do not switch, if the encoding is unchanged or switching is not supported.
+ if (oldEnc.name() == newEnc.name()
+ || oldEnc.package() == Encoding::japanese
+ || oldEnc.package() == Encoding::none
+ || newEnc.package() == Encoding::none
+ || runparams.for_search)
return make_pair(false, 0);
-
- // Do nothing if the encoding is unchanged.
- if (oldEnc.name() == newEnc.name())
- return make_pair(false, 0);
-
// FIXME We ignore encoding switches from/to encodings that do
// neither support the inputenc package nor the CJK package here.
- // This does of course only work in special cases (e.g. switch from
- // tis620-0 to latin1, but the text in latin1 contains ASCII only),
- // but it is the best we can do
- //
- // 2019-01-08 Possibly no longer required since tis620-0 is supported
- // by inputenc (but check special encodings "utf8-plain" and "default").
- if (oldEnc.package() == Encoding::none || newEnc.package() == Encoding::none)
- return make_pair(false, 0);
+ // This may fail for characters not supported by "unicodesymbols"
+ // or for non-ASCII characters in "listings"
+ // but it is the best we can do.
+ // change encoding
LYXERR(Debug::LATEX, "Changing LaTeX encoding from "
- << oldEnc.name() << " to " << newEnc.name());
+ << oldEnc.name() << " to " << newEnc.name());
os << setEncoding(newEnc.iconvName());
- if (bparams.inputenc == "default")
- return make_pair(true, 0);
+ if (bparams.inputenc == "auto-legacy-plain")
+ return make_pair(true, 0);
docstring const inputenc_arg(from_ascii(newEnc.latexName()));
OutputState * state = getOutputState();
switch (newEnc.package()) {
case Encoding::none:
case Encoding::japanese:
- // shouldn't ever reach here, see above
+ // shouldn't ever reach here (see above) but avoids warning.
return make_pair(true, 0);
case Encoding::inputenc: {
int count = inputenc_arg.length();
count += 7;
state->open_encoding_ = inputenc;
}
- // with the japanese option, inputenc is omitted.
- if (runparams.use_japanese || noswitchmacro)
+ if (noswitchmacro)
return make_pair(true, count);
os << "\\inputencoding{" << inputenc_arg << '}';
return make_pair(true, count + 16);
os << "\\egroup";
count += 7;
}
- docstring const cjkenc = (bparams.encoding().iconvName() == "UTF-8"
- && LaTeXFeatures::isAvailable("CJKutf8"))
- ? from_ascii("UTF8") : from_ascii(newEnc.latexName());
- os << "\\begin{CJK}{" << cjkenc << "}{"
+ os << "\\begin{CJK}{"
+ << from_ascii(newEnc.latexName()) << "}{"
<< from_ascii(bparams.fonts_cjk) << "}";
state->open_encoding_ = CJK;
return make_pair(true, count + 15);
}
// Dead code to avoid a warning:
return make_pair(true, 0);
-
}
} // namespace lyx