#include "support/convert.h"
#include "support/debug.h"
#include "support/lstrings.h"
+#include "support/textutils.h"
#include <algorithm>
#include <boost/next_prior.hpp>
if (style.isEnvironment()) {
os << "\\begin{" << from_ascii(style.latexname()) << '}';
- if (style.latexargs().size() != 0)
- latexArgInsets(*pit, os, runparams, style.latexargs());
+ if (!style.latexargs().empty()) {
+ OutputParams rp = runparams;
+ rp.local_font = &pit->getFirstFontSettings(bparams);
+ latexArgInsets(paragraphs, pit, os, rp, style.latexargs());
+ }
if (style.latextype == LATEX_LIST_ENVIRONMENT) {
os << '{'
<< pit->params().labelWidthString()
LYXERR(Debug::LATEX, "TeXEnvironment for paragraph " << par_begin << " done.");
}
-} // namespace anon
-
-void latexArgInsets(Paragraph const & par, otexstream & os,
- OutputParams const & runparams, Layout::LaTeXArgMap latexargs)
+void getArgInsets(otexstream & os, OutputParams const & runparams, Layout::LaTeXArgMap const & latexargs,
+ map<int, lyx::InsetArgument const *> ilist, vector<string> required, string const & prefix)
{
- map<int, InsetArgument const *> ilist;
- vector<string> required;
-
- InsetList::const_iterator it = par.insetList().begin();
- InsetList::const_iterator end = par.insetList().end();
- for (; it != end; ++it) {
- if (it->inset->lyxCode() == ARG_CODE) {
- InsetArgument const * ins =
- static_cast<InsetArgument const *>(it->inset);
- if (ins->name().empty())
- LYXERR0("Error: Unnamed argument inset!");
- else {
- unsigned int const nr = convert<unsigned int>(ins->name());
- ilist[nr] = ins;
- Layout::LaTeXArgMap::const_iterator const lit =
- latexargs.find(nr);
- if (lit != latexargs.end()) {
- Layout::latexarg arg = (*lit).second;
- if (!arg.requires.empty()) {
- vector<string> req = getVectorFromString(arg.requires);
- required.insert(required.end(), req.begin(), req.end());
- }
- }
- }
- }
- }
-
unsigned int const argnr = latexargs.size();
if (argnr == 0)
return;
InsetArgument const * ins = (*lit).second;
if (ins) {
Layout::LaTeXArgMap::const_iterator const lait =
- latexargs.find(convert<unsigned int>(ins->name()));
+ latexargs.find(ins->name());
if (lait != latexargs.end()) {
Layout::latexarg arg = (*lait).second;
docstring ldelim = arg.mandatory ?
ldelim = arg.ldelim;
if (!arg.rdelim.empty())
rdelim = arg.rdelim;
- ins->latexArgument(os, runparams, ldelim, rdelim);
+ ins->latexArgument(os, runparams, ldelim, rdelim, arg.presetarg);
inserted = true;
}
}
Layout::LaTeXArgMap::const_iterator lait = latexargs.begin();
Layout::LaTeXArgMap::const_iterator const laend = latexargs.end();
for (; lait != laend; ++lait) {
- if ((*lait).first == i) {
+ string const name = prefix + convert<string>(i);
+ if ((*lait).first == name) {
Layout::latexarg arg = (*lait).second;
+ docstring preset = arg.presetarg;
+ if (!arg.defaultarg.empty()) {
+ if (!preset.empty())
+ preset += ",";
+ preset += arg.defaultarg;
+ }
if (arg.mandatory) {
docstring ldelim = arg.ldelim.empty() ?
from_ascii("{") : arg.ldelim;
docstring rdelim = arg.rdelim.empty() ?
from_ascii("}") : arg.rdelim;
- os << ldelim << rdelim;
+ os << ldelim << preset << rdelim;
+ } else if (!preset.empty()) {
+ docstring ldelim = arg.ldelim.empty() ?
+ from_ascii("[") : arg.ldelim;
+ docstring rdelim = arg.rdelim.empty() ?
+ from_ascii("]") : arg.rdelim;
+ os << ldelim << preset << rdelim;
} else if (find(required.begin(), required.end(),
- convert<string>((*lait).first)) != required.end()) {
+ (*lait).first) != required.end()) {
docstring ldelim = arg.ldelim.empty() ?
from_ascii("[") : arg.ldelim;
docstring rdelim = arg.rdelim.empty() ?
}
}
+
+} // namespace anon
+
+
+void latexArgInsets(Paragraph const & par, otexstream & os,
+ OutputParams const & runparams, Layout::LaTeXArgMap const & latexargs, string const & prefix)
+{
+ map<int, InsetArgument const *> ilist;
+ vector<string> required;
+
+ InsetList::const_iterator it = par.insetList().begin();
+ InsetList::const_iterator end = par.insetList().end();
+ for (; it != end; ++it) {
+ if (it->inset->lyxCode() == ARG_CODE) {
+ InsetArgument const * ins =
+ static_cast<InsetArgument const *>(it->inset);
+ if (ins->name().empty())
+ LYXERR0("Error: Unnamed argument inset!");
+ else {
+ string const name = prefix.empty() ? ins->name() : split(ins->name(), ':');
+ unsigned int const nr = convert<unsigned int>(name);
+ ilist[nr] = ins;
+ Layout::LaTeXArgMap::const_iterator const lit =
+ latexargs.find(ins->name());
+ if (lit != latexargs.end()) {
+ Layout::latexarg const & arg = (*lit).second;
+ if (!arg.requires.empty()) {
+ vector<string> req = getVectorFromString(arg.requires);
+ required.insert(required.end(), req.begin(), req.end());
+ }
+ }
+ }
+ }
+ }
+ getArgInsets(os, runparams, latexargs, ilist, required, prefix);
+}
+
+
+void latexArgInsets(ParagraphList const & pars, ParagraphList::const_iterator pit,
+ otexstream & os, OutputParams const & runparams, Layout::LaTeXArgMap const & latexargs,
+ string const & prefix)
+{
+ map<int, InsetArgument const *> ilist;
+ vector<string> required;
+
+ depth_type const current_depth = pit->params().depth();
+ Layout const current_layout = pit->layout();
+
+ // get the first paragraph in sequence with this layout and depth
+ pit_type offset = 0;
+ while (true) {
+ if (boost::prior(pit, offset) == pars.begin())
+ break;
+ ParagraphList::const_iterator priorpit = boost::prior(pit, offset + 1);
+ if (priorpit->layout() == current_layout
+ && priorpit->params().depth() == current_depth)
+ ++offset;
+ else
+ break;
+ }
+
+ ParagraphList::const_iterator spit = boost::prior(pit, offset);
+
+ for (; spit != pars.end(); ++spit) {
+ if (spit->layout() != current_layout || spit->params().depth() < current_depth)
+ break;
+ if (spit->params().depth() > current_depth)
+ continue;
+ InsetList::const_iterator it = spit->insetList().begin();
+ InsetList::const_iterator end = spit->insetList().end();
+ for (; it != end; ++it) {
+ if (it->inset->lyxCode() == ARG_CODE) {
+ InsetArgument const * ins =
+ static_cast<InsetArgument const *>(it->inset);
+ if (ins->name().empty())
+ LYXERR0("Error: Unnamed argument inset!");
+ else {
+ string const name = prefix.empty() ? ins->name() : split(ins->name(), ':');
+ unsigned int const nr = convert<unsigned int>(name);
+ if (ilist.find(nr) == ilist.end())
+ ilist[nr] = ins;
+ Layout::LaTeXArgMap::const_iterator const lit =
+ latexargs.find(ins->name());
+ if (lit != latexargs.end()) {
+ Layout::latexarg const & arg = (*lit).second;
+ if (!arg.requires.empty()) {
+ vector<string> req = getVectorFromString(arg.requires);
+ required.insert(required.end(), req.begin(), req.end());
+ }
+ }
+ }
+ }
+ }
+ }
+ getArgInsets(os, runparams, latexargs, ilist, required, prefix);
+}
+
namespace {
// output the proper paragraph start according to latextype.
case LATEX_COMMAND:
os << '\\' << from_ascii(style.latexname());
- // Separate handling of optional argument inset.
- if (style.latexargs().size() != 0)
+ // Command arguments
+ if (!style.latexargs().empty())
latexArgInsets(par, os, runparams, style.latexargs());
- else
- os << from_ascii(style.latexparam());
+ os << from_ascii(style.latexparam());
break;
case LATEX_ITEM_ENVIRONMENT:
case LATEX_LIST_ENVIRONMENT:
- os << "\\item ";
+ os << "\\" + style.itemcommand();
+ // Item arguments
+ if (!style.itemargs().empty())
+ latexArgInsets(par, os, runparams, style.itemargs(), "item:");
+ os << " ";
break;
case LATEX_BIB_ENVIRONMENT:
// ignore this, the inset will write itself
string const & everypar,
int start_pos, int end_pos)
{
- BufferParams const & bparams = buf.params();
+ BufferParams const & bparams = runparams_in.is_child
+ ? buf.masterParams() : buf.params();
ParagraphList const & paragraphs = text.paragraphs();
Paragraph const & par = paragraphs.at(pit);
// FIXME This check should not really be needed.
open_encoding_ = none;
}
- if (text.inset().getLayout().isPassThru()) {
+ if (text.inset().isPassThru()) {
Font const outerfont = text.outerFont(pit);
// No newline before first paragraph in this lyxtext
os << '\n';
if (!style.parbreak_is_newline) {
os << '\n';
- } else if (nextpar) {
+ } else if (nextpar && !style.isEnvironment()) {
Layout const nextstyle = text.inset().forcePlainLayout()
? bparams.documentClass().plainLayout()
: nextpar->layout();
getPolyglossiaEnvName(doc_language) : doc_language->babel();
string const outer_lang = use_polyglossia ?
getPolyglossiaEnvName(outer_language) : outer_language->babel();
- string const lang_begin_command = use_polyglossia ?
+ string lang_begin_command = use_polyglossia ?
"\\begin{$$lang}" : lyxrc.language_command_begin;
- string const lang_end_command = use_polyglossia ?
+ string lang_end_command = use_polyglossia ?
"\\end{$$lang}" : lyxrc.language_command_end;
+ // the '%' is necessary to prevent unwanted whitespace
+ string lang_command_termination = "%\n";
+
+ // In some insets (such as Arguments), we cannot use \selectlanguage
+ bool const localswitch = !use_polyglossia
+ && text.inset().getLayout().forcelocalfontswitch();
+ if (localswitch) {
+ lang_begin_command = lyxrc.language_command_local;
+ lang_end_command = "}";
+ lang_command_termination.clear();
+ }
if (par_lang != prev_lang
// check if we already put language command in TeXEnvironment()
os << from_ascii(subst(lang_end_command,
"$$lang",
prev_lang))
- // the '%' is necessary to prevent unwanted whitespace
- << "%\n";
+ << lang_command_termination;
}
// We need to open a new language if we couldn't close the previous
os << "["
<< from_ascii(par_language->polyglossiaOpts())
<< "]";
- // the '%' is necessary to prevent unwanted whitespace
- os << "%\n";
+ os << lang_command_termination;
}
}
}
par.getFontSettings(bparams, i).language()->encoding();
if (encoding->package() != Encoding::CJK
&& runparams.encoding->package() == Encoding::inputenc
- && c < 0x80)
+ && isASCII(c))
continue;
if (par.isInset(i))
break;
lang_begin_command,
"$$lang",
par_lang))
- // the '%' is necessary to prevent unwanted whitespace
- << "%\n";
+ << lang_command_termination;
}
runparams.encoding = encoding;
}
}
parStartCommand(par, os, runparams, style);
-
Font const outerfont = text.outerFont(pit);
// FIXME UNICODE
os << "\\" << from_ascii(font.latexSize()) << " \\par}";
} else if (is_command) {
os << '}';
+ if (!style.postcommandargs().empty())
+ latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
if (!runparams.isFullUnicode())
// not for ArabTeX
&& (par_language->lang() != "arabic_arabtex"
&& outer_language->lang() != "arabic_arabtex")
- // have we opened and \L or \R environment?
+ // have we opened an \L or \R environment?
&& runparams.local_font != 0
&& runparams.local_font->isRightToLeft() != par_language->rightToLeft()
// are we about to close the language?
lang_begin_command,
"$$lang",
current_lang));
- pending_newline = true;
- unskip_newline = true;
+ pending_newline = !localswitch;
+ unskip_newline = !localswitch;
}
} else if (!par_lang.empty()) {
os << from_ascii(subst(
lang_end_command,
"$$lang",
par_lang));
- pending_newline = true;
- unskip_newline = true;
+ pending_newline = !localswitch;
+ unskip_newline = !localswitch;
}
}
}
OutputParams const & runparams,
string const & everypar)
{
+ LASSERT(runparams.par_begin <= runparams.par_end,
+ { os << "% LaTeX Output Error\n"; return; } );
+
BufferParams const & bparams = buf.params();
bool const maintext = text.isMainText();
}
ParagraphList const & paragraphs = text.paragraphs();
- LASSERT(runparams.par_begin <= runparams.par_end, /**/);
if (runparams.par_begin == runparams.par_end) {
// The full doc will be exported but it is easier to just rely on
{
Encoding const & oldEnc = *runparams.encoding;
bool moving_arg = runparams.moving_arg;
- if (!force && ((bparams.inputenc != "auto" && bparams.inputenc != "default")
- || moving_arg))
+ // If we switch from/to CJK, we need to switch anyway, despite custom inputenc
+ bool const from_to_cjk =
+ (oldEnc.package() == Encoding::CJK && newEnc.package() != Encoding::CJK)
+ || (oldEnc.package() != Encoding::CJK && newEnc.package() == Encoding::CJK);
+ if (!force && !from_to_cjk
+ && ((bparams.inputenc != "auto" && bparams.inputenc != "default") || moving_arg))
return make_pair(false, 0);
// Do nothing if the encoding is unchanged.