#include "Buffer.h"
#include "BufferParams.h"
#include "Encoding.h"
+#include "Font.h"
#include "InsetList.h"
#include "Language.h"
#include "Layout.h"
#include "VSpace.h"
#include "insets/InsetBibitem.h"
-#include "insets/InsetOptArg.h"
+#include "insets/InsetArgument.h"
#include "support/lassert.h"
#include "support/debug.h"
#include "support/lstrings.h"
#include <boost/next_prior.hpp>
+#include <list>
using namespace std;
using namespace lyx::support;
}
+string const getPolyglossiaEnvName(Language const * lang)
+{
+ string result = lang->polyglossia();
+ if (result == "arabic")
+ // exceptional spelling; see polyglossia docs.
+ result = "Arabic";
+ return result;
+}
+
+
ParagraphList::const_iterator
TeXEnvironment(Buffer const & buf,
Text const & text,
? (use_prev_env_language ? prev_env_language_
: priorpit->getParLanguage(bparams))
: doc_language;
- if (par_language->babel() != prev_par_language->babel()) {
+ string par_lang = par_language->babel();
+ string prev_par_lang = prev_par_language->babel();
+ string doc_lang = doc_language->babel();
+ string lang_begin_command = lyxrc.language_command_begin;
+ string lang_end_command = lyxrc.language_command_end;
+
+ if (runparams.use_polyglossia) {
+ par_lang = getPolyglossiaEnvName(par_language);
+ prev_par_lang = getPolyglossiaEnvName(prev_par_language);
+ doc_lang = getPolyglossiaEnvName(doc_language);
+ lang_begin_command = "\\begin{$$lang}";
+ lang_end_command = "\\end{$$lang}";
+ }
- if (!lyxrc.language_command_end.empty() &&
- prev_par_language->babel() != doc_language->babel() &&
- !prev_par_language->babel().empty()) {
+ if (par_lang != prev_par_lang) {
+ if (!lang_end_command.empty() &&
+ prev_par_lang != doc_lang &&
+ !prev_par_lang.empty()) {
os << from_ascii(subst(
- lyxrc.language_command_end,
+ lang_end_command,
"$$lang",
- prev_par_language->babel()))
- // the '%' is necessary to prevent unwanted whitespace
- << "%\n";
+ prev_par_lang))
+ // the '%' is necessary to prevent unwanted whitespace
+ << "%\n";
texrow.newline();
}
if ((lyxrc.language_command_end.empty() ||
- par_language->babel() != doc_language->babel()) &&
- !par_language->babel().empty()) {
+ par_lang != doc_lang) &&
+ !par_lang.empty()) {
os << from_ascii(subst(
- lyxrc.language_command_begin,
+ lang_begin_command,
"$$lang",
- par_language->babel()))
- // the '%' is necessary to prevent unwanted whitespace
- << "%\n";
+ par_lang));
+ if (runparams.use_polyglossia
+ && !par_language->polyglossiaOpts().empty())
+ os << "["
+ << from_ascii(par_language->polyglossiaOpts())
+ << "]";
+ // the '%' is necessary to prevent unwanted whitespace
+ os << "%\n";
texrow.newline();
}
}
if (style.isEnvironment()) {
os << "\\begin{" << from_ascii(style.latexname()) << '}';
- if (style.optionalargs > 0) {
- int ret = latexOptArgInsets(*pit, os, runparams,
- style.optionalargs);
+ if (style.optargs != 0 || style.reqargs != 0) {
+ int ret = latexArgInsets(*pit, os, runparams, style.reqargs, style.optargs);
while (ret > 0) {
texrow.newline();
--ret;
prev_env_language_ = par_language;
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
- if (!bparams.useXetex)
+ if (!runparams.isFullUnicode())
os << setEncoding(prev_encoding->iconvName());
}
}
prev_env_language_ = par_language;
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
- if (!bparams.useXetex)
+ if (!runparams.isFullUnicode())
os << setEncoding(prev_encoding->iconvName());
}
}
} // namespace anon
-int latexOptArgInsets(Paragraph const & par, odocstream & os,
- OutputParams const & runparams, int number)
+int latexArgInsets(Paragraph const & par, odocstream & os,
+ OutputParams const & runparams, unsigned int reqargs,
+ unsigned int optargs)
{
- int lines = 0;
+ unsigned int totalargs = reqargs + optargs;
+ list<InsetArgument const *> ilist;
InsetList::const_iterator it = par.insetList().begin();
InsetList::const_iterator end = par.insetList().end();
- for (; it != end && number > 0 ; ++it) {
- if (it->inset->lyxCode() == OPTARG_CODE) {
- InsetOptArg * ins =
- static_cast<InsetOptArg *>(it->inset);
- lines += ins->latexOptional(os, runparams);
- --number;
+ for (; it != end; ++it) {
+ if (it->inset->lyxCode() == ARG_CODE) {
+ if (ilist.size() >= totalargs) {
+ LYXERR0("WARNING: Found extra argument inset.");
+ continue;
+ }
+ InsetArgument const * ins =
+ static_cast<InsetArgument const *>(it->inset);
+ ilist.push_back(ins);
+ }
+ }
+
+ if (!reqargs && ilist.size() == 0)
+ return 0;
+
+ int lines = 0;
+ bool const have_optional_args = ilist.size() > reqargs;
+ if (have_optional_args) {
+ unsigned int todo = ilist.size() - reqargs;
+ for (unsigned int i = 0; i < todo; ++i) {
+ InsetArgument const * ins = ilist.front();
+ ilist.pop_front();
+ lines += ins->latexArgument(os, runparams, true);
+ }
+ }
+
+ // we should now have no more insets than there are required
+ // arguments.
+ LASSERT(ilist.size() <= reqargs, /* */);
+ if (!reqargs)
+ return lines;
+
+ for (unsigned int i = 0; i < reqargs; ++i) {
+ if (ilist.empty())
+ // a required argument wasn't given, so we output {}
+ os << "{}";
+ else {
+ InsetArgument const * ins = ilist.front();
+ ilist.pop_front();
+ lines += ins->latexArgument(os, runparams, false);
}
}
return lines;
}
+
// FIXME: this should be anonymous
ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
Text const & text,
{
LYXERR(Debug::LATEX, "TeXOnePar... " << &*pit << " '"
<< everypar << "'");
+
BufferParams const & bparams = buf.params();
- ParagraphList const & paragraphs = text.paragraphs();
+ // FIXME This check should not really be needed.
+ // Perhaps we should issue an error if it is.
+ Layout const style = text.inset().forcePlainLayout() ?
+ bparams.documentClass().plainLayout() : pit->layout();
+ ParagraphList const & paragraphs = text.paragraphs();
ParagraphList::const_iterator const priorpit =
pit == paragraphs.begin() ? pit : boost::prior(pit);
ParagraphList::const_iterator const nextpit =
pit == paragraphs.end() ? pit : boost::next(pit);
+ if (style.inpreamble)
+ return nextpit;
+
OutputParams runparams = runparams_in;
runparams.isLastPar = nextpit == paragraphs.end();
open_encoding_ = none;
}
- if (runparams.verbatim) {
+ if (text.inset().getLayout().isPassThru()) {
int const dist = distance(paragraphs.begin(), pit);
Font const outerfont = text.outerFont(dist);
- // No newline if only one paragraph in this lyxtext
+ // No newline before first paragraph in this lyxtext
if (dist > 0) {
os << '\n';
texrow.newline();
+ if (!text.inset().getLayout().parbreakIsNewline()) {
+ os << '\n';
+ texrow.newline();
+ }
}
- /*bool need_par = */ pit->latex(bparams, outerfont,
- os, texrow, runparams, start_pos, end_pos);
+ pit->latex(bparams, outerfont, os, texrow,
+ runparams, start_pos, end_pos);
return nextpit;
}
- // FIXME This check should not really be needed.
- // Perhaps we should issue an error if it is.
- Layout const style = text.inset().forcePlainLayout() ?
- bparams.documentClass().plainLayout() : pit->layout();
+ if (style.pass_thru) {
+ int const dist = distance(paragraphs.begin(), pit);
+ Font const outerfont = text.outerFont(dist);
+ pit->latex(bparams, outerfont, os, texrow,
+ runparams, start_pos, end_pos);
+ os << '\n';
+ texrow.newline();
+ if (!style.parbreak_is_newline) {
+ os << '\n';
+ texrow.newline();
+ } else if (nextpit != paragraphs.end()) {
+ Layout const nextstyle = text.inset().forcePlainLayout() ?
+ bparams.documentClass().plainLayout() : nextpit->layout();
+ if (nextstyle.name() != style.name()) {
+ os << '\n';
+ texrow.newline();
+ }
+ }
+
+ return nextpit;
+ }
// This paragraph's language
Language const * const par_language = pit->getParLanguage(bparams);
: priorpit->getParLanguage(bparams))
: outer_language;
- if (par_language->babel() != prev_language->babel()
+ string par_lang = par_language->babel();
+ string prev_lang = prev_language->babel();
+ string doc_lang = doc_language->babel();
+ string outer_lang = outer_language->babel();
+ string lang_begin_command = lyxrc.language_command_begin;
+ string lang_end_command = lyxrc.language_command_end;
+
+ if (runparams.use_polyglossia) {
+ par_lang = getPolyglossiaEnvName(par_language);
+ prev_lang = getPolyglossiaEnvName(prev_language);
+ doc_lang = getPolyglossiaEnvName(doc_language);
+ outer_lang = getPolyglossiaEnvName(outer_language);
+ lang_begin_command = "\\begin{$$lang}";
+ lang_end_command = "\\end{$$lang}";
+ }
+ if (par_lang != prev_lang
// check if we already put language command in TeXEnvironment()
&& !(style.isEnvironment()
&& (pit == paragraphs.begin() ||
priorpit->getDepth() <= pit->getDepth())
|| priorpit->getDepth() < pit->getDepth())))
{
- if (!lyxrc.language_command_end.empty() &&
- prev_language->babel() != outer_language->babel() &&
- !prev_language->babel().empty())
+ if (!lang_end_command.empty() &&
+ prev_lang != outer_lang &&
+ !prev_lang.empty())
{
- os << from_ascii(subst(lyxrc.language_command_end,
+ os << from_ascii(subst(lang_end_command,
"$$lang",
- prev_language->babel()))
+ prev_lang))
// the '%' is necessary to prevent unwanted whitespace
<< "%\n";
texrow.newline();
// the previous one, if the current language is different than the
// outer_language (which is currently in effect once the previous one
// is closed).
- if ((lyxrc.language_command_end.empty() ||
- par_language->babel() != outer_language->babel()) &&
- !par_language->babel().empty()) {
+ if ((lang_end_command.empty() ||
+ par_lang != outer_lang) &&
+ !par_lang.empty()) {
// If we're inside an inset, and that inset is within an \L or \R
// (or equivalents), then within the inset, too, any opposite
// language paragraph should appear within an \L or \R (in addition
// to, outside of, the normal language switch commands).
// This behavior is not correct for ArabTeX, though.
- if ( // not for ArabTeX
- (par_language->lang() != "arabic_arabtex" &&
- outer_language->lang() != "arabic_arabtex") &&
- // are we in an inset?
- runparams.local_font != 0 &&
- // is the inset within an \L or \R?
- //
- // FIXME: currently, we don't check this; this means that
- // we'll have unnnecessary \L and \R commands, but that
- // doesn't seem to hurt (though latex will complain)
- //
- // is this paragraph in the opposite direction?
- runparams.local_font->isRightToLeft() !=
- par_language->rightToLeft()
- ) {
+ if (!runparams.use_polyglossia &&
+ // not for ArabTeX
+ (par_language->lang() != "arabic_arabtex" &&
+ outer_language->lang() != "arabic_arabtex") &&
+ // are we in an inset?
+ runparams.local_font != 0 &&
+ // is the inset within an \L or \R?
+ //
+ // FIXME: currently, we don't check this; this means that
+ // we'll have unnnecessary \L and \R commands, but that
+ // doesn't seem to hurt (though latex will complain)
+ //
+ // is this paragraph in the opposite direction?
+ runparams.local_font->isRightToLeft() !=
+ par_language->rightToLeft()
+ ) {
// FIXME: I don't have a working copy of the Arabi package, so
// I'm not sure if the farsi and arabic_arabi stuff is correct
// or not...
// With CJK, the CJK tag has to be closed first (see below)
if (runparams.encoding->package() != Encoding::CJK) {
os << from_ascii(subst(
- lyxrc.language_command_begin,
+ lang_begin_command,
"$$lang",
- par_language->babel()))
+ par_lang));
+ if (runparams.use_polyglossia
+ && !par_language->polyglossiaOpts().empty())
+ os << "["
+ << from_ascii(par_language->polyglossiaOpts())
+ << "]";
// the '%' is necessary to prevent unwanted whitespace
- << "%\n";
+ os << "%\n";
texrow.newline();
}
}
// With CJK, the CJK tag had to be closed first (see above)
if (runparams.encoding->package() == Encoding::CJK) {
os << from_ascii(subst(
- lyxrc.language_command_begin,
+ lang_begin_command,
"$$lang",
- par_language->babel()))
+ par_lang))
// the '%' is necessary to prevent unwanted whitespace
<< "%\n";
texrow.newline();
os << '\\' << from_ascii(style.latexname());
// Separate handling of optional argument inset.
- if (style.optionalargs > 0) {
- int ret = latexOptArgInsets(*pit, os, runparams,
- style.optionalargs);
+ if (style.optargs != 0 || style.reqargs != 0) {
+ int ret = latexArgInsets(*pit, os, runparams, style.reqargs, style.optargs);
while (ret > 0) {
texrow.newline();
--ret;
// FIXME UNICODE
os << from_utf8(everypar);
- bool need_par = pit->latex(bparams, outerfont,
- os, texrow, runparams, start_pos, end_pos);
+ pit->latex(bparams, outerfont, os, texrow,
+ runparams, start_pos, end_pos);
// Make sure that \\par is done with the font of the last
// character if this has another size as the default.
if (style.resfont.size() != font.fontInfo().size()
&& nextpit != paragraphs.end()
&& !is_command) {
- if (!need_par)
- os << '{';
+ os << '{';
os << "\\" << from_ascii(font.latexSize()) << " \\par}";
- } else if (need_par) {
- os << "\\par}";
} else if (is_command) {
os << '}';
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
- if (!bparams.useXetex)
+ if (!runparams.isFullUnicode())
os << setEncoding(prev_encoding->iconvName());
}
}
// needed if we're within an \L or \R that we may have opened above (not
// necessarily in this paragraph) and are about to close.
bool closing_rtl_ltr_environment =
+ !runparams.use_polyglossia &&
// not for ArabTeX
(par_language->lang() != "arabic_arabtex" &&
outer_language->lang() != "arabic_arabtex") &&
}
// when the paragraph uses CJK, the language has to be closed earlier
if (font.language()->encoding()->package() != Encoding::CJK) {
- if (lyxrc.language_command_end.empty()) {
+ if (lang_end_command.empty()) {
// If this is a child, we should restore the
// master language after the last paragraph.
Language const * const current_language =
&& runparams.master_language)
? runparams.master_language
: outer_language;
- if (!current_language->babel().empty()) {
+ string const current_lang = runparams.use_polyglossia ?
+ getPolyglossiaEnvName(current_language)
+ : current_language->babel();
+ if (!current_lang.empty()) {
os << from_ascii(subst(
- lyxrc.language_command_begin,
+ lang_begin_command,
"$$lang",
- current_language->babel()));
+ current_lang));
pending_newline = true;
}
- } else if (!par_language->babel().empty()) {
+ } else if (!par_lang.empty()) {
os << from_ascii(subst(
- lyxrc.language_command_end,
+ lang_end_command,
"$$lang",
- par_language->babel()));
+ par_lang));
pending_newline = true;
}
}
// If this is the last paragraph, and a local_font was set upon entering
// the inset, and we're using "auto" or "default" encoding, the encoding
// should be set back to that local_font's encoding.
- // However, do not change the encoding when XeTeX is used.
+ // However, do not change the encoding when a fully unicode aware backend
+ // such as XeTeX is used.
if (nextpit == paragraphs.end() && runparams_in.local_font != 0
&& runparams_in.encoding != runparams_in.local_font->language()->encoding()
&& (bparams.inputenc == "auto" || bparams.inputenc == "default")
- && (!bparams.useXetex)) {
+ && (!runparams.isFullUnicode())) {
runparams_in.encoding = runparams_in.local_font->language()->encoding();
os << setEncoding(runparams_in.encoding->iconvName());
}
}
// if "auto begin" is switched off, explicitly switch the
// language on at start
+ string const mainlang = runparams.use_polyglossia ?
+ getPolyglossiaEnvName(bparams.language)
+ : bparams.language->babel();
+ string const lang_begin_command = runparams.use_polyglossia ?
+ "\\begin{$$lang}" : lyxrc.language_command_begin;
+
if (maintext && !lyxrc.language_auto_begin &&
- !bparams.language->babel().empty()) {
+ !mainlang.empty()) {
// FIXME UNICODE
- os << from_utf8(subst(lyxrc.language_command_begin,
+ os << from_utf8(subst(lang_begin_command,
"$$lang",
- bparams.language->babel()))
- << '\n';
- texrow.newline();
+ mainlang));
+ if (runparams.use_polyglossia
+ && !bparams.language->polyglossiaOpts().empty())
+ os << "["
+ << from_ascii(bparams.language->polyglossiaOpts())
+ << "]";
+ os << '\n';
+ texrow.newline();
}
ParagraphList::const_iterator lastpar;
// if "auto end" is switched off, explicitly 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() &&
+ string const lang_end_command = runparams.use_polyglossia ?
+ "\\end{$$lang}" : lyxrc.language_command_end;
+ if (maintext && !lyxrc.language_auto_end && !mainlang.empty() &&
lastpar->getParLanguage(bparams)->encoding()->package() != Encoding::CJK) {
- os << from_utf8(subst(lyxrc.language_command_end,
+ os << from_utf8(subst(lang_end_command,
"$$lang",
- bparams.language->babel()))
+ mainlang))
<< '\n';
texrow.newline();
}