2003-11-05 12:06:20 +00:00
|
|
|
|
/**
|
2007-04-26 04:41:58 +00:00
|
|
|
|
* \file output_latex.cpp
|
2003-11-05 12:06:20 +00:00
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
|
*
|
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
*
|
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include "output_latex.h"
|
|
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Buffer.h"
|
|
|
|
|
#include "BufferParams.h"
|
|
|
|
|
#include "Encoding.h"
|
2007-10-18 15:29:51 +00:00
|
|
|
|
#include "InsetList.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Language.h"
|
2007-09-29 20:02:32 +00:00
|
|
|
|
#include "Layout.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "LyXRC.h"
|
|
|
|
|
#include "OutputParams.h"
|
|
|
|
|
#include "Paragraph.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
#include "paragraph_funcs.h"
|
|
|
|
|
#include "ParagraphParameters.h"
|
2007-11-07 23:25:08 +00:00
|
|
|
|
#include "TextClass.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "TexRow.h"
|
|
|
|
|
#include "VSpace.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2007-04-25 01:24:38 +00:00
|
|
|
|
#include "insets/InsetBibitem.h"
|
|
|
|
|
#include "insets/InsetOptArg.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-04-30 08:26:40 +00:00
|
|
|
|
#include "support/lassert.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
|
#include "support/debug.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
#include "support/lstrings.h"
|
|
|
|
|
|
2007-10-02 18:27:20 +00:00
|
|
|
|
#include <boost/next_prior.hpp>
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
|
using namespace lyx::support;
|
2007-12-12 10:16:00 +00:00
|
|
|
|
|
2008-04-10 21:49:34 +00:00
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
namespace lyx {
|
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
namespace {
|
|
|
|
|
|
2007-12-08 11:21:00 +00:00
|
|
|
|
enum OpenEncoding {
|
|
|
|
|
none,
|
|
|
|
|
inputenc,
|
|
|
|
|
CJK
|
2008-03-21 22:51:36 +00:00
|
|
|
|
};
|
2007-12-08 11:21:00 +00:00
|
|
|
|
|
|
|
|
|
static int open_encoding_ = none;
|
2008-06-03 07:51:14 +00:00
|
|
|
|
static int cjk_inherited_ = 0;
|
2007-12-08 11:21:00 +00:00
|
|
|
|
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator
|
2003-11-05 12:06:20 +00:00
|
|
|
|
TeXEnvironment(Buffer const & buf,
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Text const & text,
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator pit,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams);
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator
|
2003-11-05 12:06:20 +00:00
|
|
|
|
TeXOnePar(Buffer const & buf,
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Text const & text,
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator pit,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams,
|
|
|
|
|
string const & everypar = string());
|
|
|
|
|
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator
|
2003-11-05 12:06:20 +00:00
|
|
|
|
TeXDeeper(Buffer const & buf,
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Text const & text,
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator pit,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams)
|
|
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "TeXDeeper... " << &*pit);
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator par = pit;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-01-25 13:27:08 +00:00
|
|
|
|
ParagraphList const & paragraphs = text.paragraphs();
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
while (par != paragraphs.end() &&
|
2003-11-05 12:06:20 +00:00
|
|
|
|
par->params().depth() == pit->params().depth()) {
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (par->layout().isEnvironment()) {
|
2008-01-25 13:27:08 +00:00
|
|
|
|
par = TeXEnvironment(buf, text, par,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
os, texrow, runparams);
|
|
|
|
|
} else {
|
2008-01-25 13:27:08 +00:00
|
|
|
|
par = TeXOnePar(buf, text, par,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
os, texrow, runparams);
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "TeXDeeper...done ");
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
return par;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator
|
2003-11-05 12:06:20 +00:00
|
|
|
|
TeXEnvironment(Buffer const & buf,
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Text const & text,
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator pit,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams)
|
|
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "TeXEnvironment... " << &*pit);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
BufferParams const & bparams = buf.params();
|
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
Layout const & style = pit->forceEmptyLayout() ?
|
|
|
|
|
bparams.documentClass().emptyLayout() : pit->layout();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-01-25 13:27:08 +00:00
|
|
|
|
ParagraphList const & paragraphs = text.paragraphs();
|
|
|
|
|
|
2007-03-12 17:19:08 +00:00
|
|
|
|
Language const * const par_language = pit->getParLanguage(bparams);
|
|
|
|
|
Language const * const doc_language = bparams.language;
|
|
|
|
|
Language const * const prev_par_language =
|
2004-05-17 11:28:31 +00:00
|
|
|
|
(pit != paragraphs.begin())
|
2003-11-05 12:06:20 +00:00
|
|
|
|
? boost::prior(pit)->getParLanguage(bparams)
|
|
|
|
|
: doc_language;
|
2007-03-12 17:19:08 +00:00
|
|
|
|
if (par_language->babel() != prev_par_language->babel()) {
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
if (!lyxrc.language_command_end.empty() &&
|
2007-05-05 19:18:34 +00:00
|
|
|
|
prev_par_language->babel() != doc_language->babel() &&
|
|
|
|
|
!prev_par_language->babel().empty()) {
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(subst(
|
2006-10-19 16:51:30 +00:00
|
|
|
|
lyxrc.language_command_end,
|
|
|
|
|
"$$lang",
|
2007-03-12 17:19:08 +00:00
|
|
|
|
prev_par_language->babel()))
|
2007-11-23 14:59:35 +00:00
|
|
|
|
// the '%' is necessary to prevent unwanted whitespace
|
|
|
|
|
<< "%\n";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
2007-05-11 23:43:17 +00:00
|
|
|
|
if ((lyxrc.language_command_end.empty() ||
|
|
|
|
|
par_language->babel() != doc_language->babel()) &&
|
2007-05-05 19:18:34 +00:00
|
|
|
|
!par_language->babel().empty()) {
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(subst(
|
2006-10-19 16:51:30 +00:00
|
|
|
|
lyxrc.language_command_begin,
|
|
|
|
|
"$$lang",
|
2007-03-12 17:19:08 +00:00
|
|
|
|
par_language->babel()))
|
2007-11-23 14:59:35 +00:00
|
|
|
|
// the '%' is necessary to prevent unwanted whitespace
|
|
|
|
|
<< "%\n";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool leftindent_open = false;
|
|
|
|
|
if (!pit->params().leftIndent().zero()) {
|
2006-10-19 16:51:30 +00:00
|
|
|
|
os << "\\begin{LyXParagraphLeftIndent}{"
|
2006-10-21 00:16:43 +00:00
|
|
|
|
<< from_ascii(pit->params().leftIndent().asLatexString())
|
2006-10-19 16:51:30 +00:00
|
|
|
|
<< "}\n";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
leftindent_open = true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (style.isEnvironment()) {
|
|
|
|
|
os << "\\begin{" << from_ascii(style.latexname()) << '}';
|
|
|
|
|
if (style.optionalargs > 0) {
|
2008-02-27 20:43:16 +00:00
|
|
|
|
int ret = latexOptArgInsets(*pit, os, runparams,
|
2008-03-06 21:31:27 +00:00
|
|
|
|
style.optionalargs);
|
2006-10-12 20:21:14 +00:00
|
|
|
|
while (ret > 0) {
|
|
|
|
|
texrow.newline();
|
|
|
|
|
--ret;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (style.latextype == LATEX_LIST_ENVIRONMENT) {
|
2006-10-19 16:51:30 +00:00
|
|
|
|
os << '{'
|
2006-10-20 19:26:23 +00:00
|
|
|
|
<< pit->params().labelWidthString()
|
2006-10-19 16:51:30 +00:00
|
|
|
|
<< "}\n";
|
2008-03-06 21:31:27 +00:00
|
|
|
|
} else if (style.labeltype == LABEL_BIBLIO) {
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// ale970405
|
2006-10-19 16:51:30 +00:00
|
|
|
|
os << '{' << bibitemWidest(buf) << "}\n";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
} else
|
2008-03-06 21:31:27 +00:00
|
|
|
|
os << from_ascii(style.latexparam()) << '\n';
|
2003-11-05 12:06:20 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2007-12-08 11:21:00 +00:00
|
|
|
|
|
|
|
|
|
// in multilingual environments, the CJK tags have to be nested properly
|
|
|
|
|
bool cjk_nested = false;
|
|
|
|
|
if (par_language->encoding()->package() == Encoding::CJK &&
|
|
|
|
|
open_encoding_ != CJK && pit->isMultiLingual(bparams)) {
|
|
|
|
|
os << "\\begin{CJK}{" << from_ascii(par_language->encoding()->latexName())
|
|
|
|
|
<< "}{}%\n";
|
|
|
|
|
open_encoding_ = CJK;
|
|
|
|
|
cjk_nested = true;
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator par = pit;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
do {
|
2008-01-25 13:27:08 +00:00
|
|
|
|
par = TeXOnePar(buf, text, par, os, texrow, runparams);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
if (par == paragraphs.end()) {
|
2004-04-22 13:59:39 +00:00
|
|
|
|
// Make sure that the last paragraph is
|
|
|
|
|
// correctly terminated (because TeXOnePar does
|
|
|
|
|
// not add a \n in this case)
|
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
} else if (par->params().depth() > pit->params().depth()) {
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (par->layout().isParagraph()) {
|
2007-09-29 20:02:32 +00:00
|
|
|
|
// Thinko!
|
|
|
|
|
// How to handle this? (Lgb)
|
|
|
|
|
//&& !suffixIs(os, "\n\n")
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
// There should be at least one '\n' already
|
|
|
|
|
// but we need there to be two for Standard
|
|
|
|
|
// paragraphs that are depth-increment'ed to be
|
|
|
|
|
// output correctly. However, tables can
|
|
|
|
|
// also be paragraphs so don't adjust them.
|
|
|
|
|
// ARRae
|
|
|
|
|
// Thinkee:
|
|
|
|
|
// Will it ever harm to have one '\n' too
|
|
|
|
|
// many? i.e. that we sometimes will have
|
|
|
|
|
// three in a row. (Lgb)
|
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2008-01-25 13:27:08 +00:00
|
|
|
|
par = TeXDeeper(buf, text, par, os, texrow,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
runparams);
|
|
|
|
|
}
|
2004-05-17 11:28:31 +00:00
|
|
|
|
} while (par != paragraphs.end()
|
2003-11-05 12:06:20 +00:00
|
|
|
|
&& par->layout() == pit->layout()
|
|
|
|
|
&& par->params().depth() == pit->params().depth()
|
|
|
|
|
&& par->params().leftIndent() == pit->params().leftIndent());
|
|
|
|
|
|
2007-12-08 11:21:00 +00:00
|
|
|
|
if (open_encoding_ == CJK && cjk_nested) {
|
|
|
|
|
// We need to close the encoding even if it does not change
|
|
|
|
|
// to do correct environment nesting
|
|
|
|
|
os << "\\end{CJK}\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
open_encoding_ = none;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (style.isEnvironment()) {
|
|
|
|
|
os << "\\end{" << from_ascii(style.latexname()) << "}\n";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (leftindent_open) {
|
|
|
|
|
os << "\\end{LyXParagraphLeftIndent}\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
if (par != paragraphs.end())
|
|
|
|
|
LYXERR(Debug::LATEX, "TeXEnvironment...done " << &*par);
|
|
|
|
|
|
2005-01-20 11:44:20 +00:00
|
|
|
|
return par;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-03-21 22:51:36 +00:00
|
|
|
|
} // namespace anon
|
2007-01-30 13:23:21 +00:00
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
|
int latexOptArgInsets(Paragraph const & par, odocstream & os,
|
|
|
|
|
OutputParams const & runparams, int number)
|
2003-11-05 12:06:20 +00:00
|
|
|
|
{
|
2004-11-19 16:17:52 +00:00
|
|
|
|
int lines = 0;
|
2004-11-26 14:52:54 +00:00
|
|
|
|
|
2007-10-18 15:29:51 +00:00
|
|
|
|
InsetList::const_iterator it = par.insetList().begin();
|
|
|
|
|
InsetList::const_iterator end = par.insetList().end();
|
2004-11-19 16:17:52 +00:00
|
|
|
|
for (; it != end && number > 0 ; ++it) {
|
2007-10-13 09:04:52 +00:00
|
|
|
|
if (it->inset->lyxCode() == OPTARG_CODE) {
|
2004-11-26 14:52:54 +00:00
|
|
|
|
InsetOptArg * ins =
|
2004-11-19 16:17:52 +00:00
|
|
|
|
static_cast<InsetOptArg *>(it->inset);
|
2008-02-27 20:43:16 +00:00
|
|
|
|
lines += ins->latexOptional(os, runparams);
|
2004-11-19 16:17:52 +00:00
|
|
|
|
--number;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-11-19 16:17:52 +00:00
|
|
|
|
return lines;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-01-30 13:23:21 +00:00
|
|
|
|
namespace {
|
|
|
|
|
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator
|
2003-11-05 12:06:20 +00:00
|
|
|
|
TeXOnePar(Buffer const & buf,
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Text const & text,
|
2008-03-21 22:51:36 +00:00
|
|
|
|
ParagraphList::const_iterator const pit,
|
2007-01-09 19:25:40 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2004-11-15 13:39:06 +00:00
|
|
|
|
OutputParams const & runparams_in,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
string const & everypar)
|
|
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "TeXOnePar... " << &*pit << " '"
|
|
|
|
|
<< everypar << "'");
|
2003-11-05 12:06:20 +00:00
|
|
|
|
BufferParams const & bparams = buf.params();
|
2008-01-25 13:27:08 +00:00
|
|
|
|
ParagraphList const & paragraphs = text.paragraphs();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-03-21 22:51:36 +00:00
|
|
|
|
ParagraphList::const_iterator priorpit = pit;
|
|
|
|
|
if (priorpit != paragraphs.begin())
|
|
|
|
|
--priorpit;
|
|
|
|
|
ParagraphList::const_iterator nextpit = pit;
|
|
|
|
|
if (nextpit != paragraphs.end())
|
|
|
|
|
++nextpit;
|
|
|
|
|
|
2007-10-23 18:23:03 +00:00
|
|
|
|
if (runparams_in.verbatim) {
|
2007-12-12 19:28:07 +00:00
|
|
|
|
int const dist = distance(paragraphs.begin(), pit);
|
2007-10-30 16:22:56 +00:00
|
|
|
|
Font const outerfont = outerFont(dist, paragraphs);
|
|
|
|
|
|
|
|
|
|
// No newline if only one paragraph in this lyxtext
|
|
|
|
|
if (dist > 0) {
|
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2007-10-24 07:13:20 +00:00
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
|
/*bool need_par = */ pit->latex(bparams, outerfont,
|
2007-10-24 07:13:20 +00:00
|
|
|
|
os, texrow, runparams_in);
|
2008-03-21 22:51:36 +00:00
|
|
|
|
return nextpit;
|
2007-10-23 18:23:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
Layout const style = pit->forceEmptyLayout() ?
|
|
|
|
|
bparams.documentClass().emptyLayout() : pit->layout();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2004-11-15 13:39:06 +00:00
|
|
|
|
OutputParams runparams = runparams_in;
|
2008-03-06 21:31:27 +00:00
|
|
|
|
runparams.moving_arg |= style.needprotect;
|
2004-11-15 13:39:06 +00:00
|
|
|
|
|
2008-01-25 13:27:08 +00:00
|
|
|
|
bool const maintext = text.isMainText(buf);
|
2008-06-03 07:51:14 +00:00
|
|
|
|
// we are at the beginning of an inset and CJK is already open;
|
|
|
|
|
// we count inheritation levels to get the inset nesting right.
|
|
|
|
|
if (pit == paragraphs.begin() && !maintext
|
|
|
|
|
&& (cjk_inherited_ > 0 || open_encoding_ == CJK)) {
|
|
|
|
|
cjk_inherited_ += 1;
|
2007-12-08 11:21:00 +00:00
|
|
|
|
open_encoding_ = none;
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// This paragraph's language
|
2007-03-12 17:19:08 +00:00
|
|
|
|
Language const * const par_language = pit->getParLanguage(bparams);
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// The document's language
|
2007-03-12 17:19:08 +00:00
|
|
|
|
Language const * const doc_language = bparams.language;
|
2007-11-23 14:59:35 +00:00
|
|
|
|
// The language that was in effect when the environment this paragraph is
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// inside of was opened
|
|
|
|
|
Language const * const outer_language =
|
|
|
|
|
(runparams.local_font != 0) ?
|
|
|
|
|
runparams.local_font->language() : doc_language;
|
|
|
|
|
// The previous language that was in effect is either the language of
|
|
|
|
|
// the previous paragraph, if there is one, or else the outer language
|
|
|
|
|
// if there is no previous paragraph
|
|
|
|
|
Language const * const prev_language =
|
|
|
|
|
(pit != paragraphs.begin()) ?
|
2008-03-21 22:51:36 +00:00
|
|
|
|
priorpit->getParLanguage(bparams) : outer_language;
|
2007-07-20 01:28:20 +00:00
|
|
|
|
|
|
|
|
|
if (par_language->babel() != prev_language->babel()
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// check if we already put language command in TeXEnvironment()
|
2008-03-06 21:31:27 +00:00
|
|
|
|
&& !(style.isEnvironment()
|
2004-05-17 11:28:31 +00:00
|
|
|
|
&& (pit == paragraphs.begin() ||
|
2008-03-21 22:51:36 +00:00
|
|
|
|
(priorpit->layout() != pit->layout() &&
|
|
|
|
|
priorpit->getDepth() <= pit->getDepth())
|
|
|
|
|
|| priorpit->getDepth() < pit->getDepth())))
|
2003-11-05 12:06:20 +00:00
|
|
|
|
{
|
|
|
|
|
if (!lyxrc.language_command_end.empty() &&
|
2007-07-20 01:28:20 +00:00
|
|
|
|
prev_language->babel() != outer_language->babel() &&
|
|
|
|
|
!prev_language->babel().empty())
|
2003-11-05 12:06:20 +00:00
|
|
|
|
{
|
2007-01-09 19:25:40 +00:00
|
|
|
|
os << from_ascii(subst(lyxrc.language_command_end,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
"$$lang",
|
2007-07-20 01:28:20 +00:00
|
|
|
|
prev_language->babel()))
|
2007-11-23 14:59:35 +00:00
|
|
|
|
// the '%' is necessary to prevent unwanted whitespace
|
|
|
|
|
<< "%\n";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// We need to open a new language if we couldn't close the previous
|
|
|
|
|
// one (because there's no language_command_end); and even if we closed
|
|
|
|
|
// the previous one, if the current language is different than the
|
|
|
|
|
// outer_language (which is currently in effect once the previous one
|
|
|
|
|
// is closed).
|
2007-05-11 23:43:17 +00:00
|
|
|
|
if ((lyxrc.language_command_end.empty() ||
|
2007-07-20 01:28:20 +00:00
|
|
|
|
par_language->babel() != outer_language->babel()) &&
|
2007-05-11 23:43:17 +00:00
|
|
|
|
!par_language->babel().empty()) {
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// 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()
|
|
|
|
|
) {
|
|
|
|
|
// 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...
|
|
|
|
|
if (par_language->lang() == "farsi")
|
|
|
|
|
os << "\\textFR{";
|
|
|
|
|
else if (outer_language->lang() == "farsi")
|
|
|
|
|
os << "\\textLR{";
|
|
|
|
|
else if (par_language->lang() == "arabic_arabi")
|
|
|
|
|
os << "\\textAR{";
|
|
|
|
|
else if (outer_language->lang() == "arabic_arabi")
|
|
|
|
|
os << "\\textLR{";
|
|
|
|
|
// remaining RTL languages currently is hebrew
|
|
|
|
|
else if (par_language->rightToLeft())
|
|
|
|
|
os << "\\R{";
|
|
|
|
|
else
|
|
|
|
|
os << "\\L{";
|
|
|
|
|
}
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// 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",
|
|
|
|
|
par_language->babel()))
|
|
|
|
|
// the '%' is necessary to prevent unwanted whitespace
|
|
|
|
|
<< "%\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-05 19:19:41 +00:00
|
|
|
|
// Switch file encoding if necessary; no need to do this for "default"
|
|
|
|
|
// encoding, since this only affects the position of the outputted
|
|
|
|
|
// \inputencoding command; the encoding switch will occur when necessary
|
2007-05-06 20:26:02 +00:00
|
|
|
|
if (bparams.inputenc == "auto" &&
|
2007-12-08 11:21:00 +00:00
|
|
|
|
runparams.encoding->package() != Encoding::none) {
|
2007-04-16 18:06:01 +00:00
|
|
|
|
// Look ahead for future encoding changes.
|
|
|
|
|
// We try to output them at the beginning of the paragraph,
|
|
|
|
|
// since the \inputencoding command is not allowed e.g. in
|
|
|
|
|
// sections.
|
|
|
|
|
for (pos_type i = 0; i < pit->size(); ++i) {
|
|
|
|
|
char_type const c = pit->getChar(i);
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Encoding const * const encoding =
|
|
|
|
|
pit->getFontSettings(bparams, i).language()->encoding();
|
|
|
|
|
if (encoding->package() != Encoding::CJK &&
|
|
|
|
|
runparams.encoding->package() == Encoding::inputenc &&
|
|
|
|
|
c < 0x80)
|
2007-04-16 18:06:01 +00:00
|
|
|
|
continue;
|
|
|
|
|
if (pit->isInset(i))
|
|
|
|
|
break;
|
|
|
|
|
// All characters before c are in the ASCII range, and
|
|
|
|
|
// c is non-ASCII (but no inset), so change the
|
|
|
|
|
// encoding to that required by the language of c.
|
2008-01-25 13:27:08 +00:00
|
|
|
|
// With CJK, only add switch if we have CJK content at the beginning
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// of the paragraph
|
|
|
|
|
if (encoding->package() != Encoding::CJK || i == 0) {
|
|
|
|
|
OutputParams tmp_rp = runparams;
|
|
|
|
|
runparams.moving_arg = false;
|
|
|
|
|
pair<bool, int> enc_switch = switchEncoding(os, bparams, runparams,
|
2007-12-17 10:53:38 +00:00
|
|
|
|
*encoding);
|
2007-12-08 11:21:00 +00:00
|
|
|
|
runparams = tmp_rp;
|
|
|
|
|
// the following is necessary after a CJK environment in a multilingual
|
|
|
|
|
// context (nesting issue).
|
|
|
|
|
if (par_language->encoding()->package() == Encoding::CJK &&
|
2008-06-03 07:51:14 +00:00
|
|
|
|
open_encoding_ != CJK && cjk_inherited_ == 0) {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
os << "\\begin{CJK}{" << from_ascii(par_language->encoding()->latexName())
|
|
|
|
|
<< "}{}%\n";
|
|
|
|
|
open_encoding_ = CJK;
|
2007-07-05 19:19:41 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2007-12-08 11:21:00 +00:00
|
|
|
|
if (encoding->package() != Encoding::none && enc_switch.first) {
|
|
|
|
|
if (enc_switch.second > 0) {
|
|
|
|
|
// the '%' is necessary to prevent unwanted whitespace
|
|
|
|
|
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",
|
|
|
|
|
par_language->babel()))
|
|
|
|
|
// the '%' is necessary to prevent unwanted whitespace
|
|
|
|
|
<< "%\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
runparams.encoding = encoding;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2007-04-16 18:06:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-28 01:42:02 +00:00
|
|
|
|
bool const useSetSpace = bparams.documentClass().provides("SetSpace");
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
|
if (pit->allowParagraphCustomization()) {
|
2004-09-28 13:29:19 +00:00
|
|
|
|
if (pit->params().startOfAppendix()) {
|
|
|
|
|
os << "\\appendix\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!pit->params().spacing().isDefault()
|
|
|
|
|
&& (pit == paragraphs.begin()
|
2008-03-21 22:51:36 +00:00
|
|
|
|
|| !priorpit->hasSameLayout(*pit)))
|
2004-09-28 13:29:19 +00:00
|
|
|
|
{
|
2008-01-14 14:53:29 +00:00
|
|
|
|
os << from_ascii(pit->params().spacing().writeEnvirBegin(useSetSpace))
|
2006-10-19 16:51:30 +00:00
|
|
|
|
<< '\n';
|
2004-09-28 13:29:19 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (style.isCommand()) {
|
2004-09-28 13:29:19 +00:00
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2004-10-05 10:11:42 +00:00
|
|
|
|
}
|
2004-09-28 13:29:19 +00:00
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
switch (style.latextype) {
|
2003-11-05 12:06:20 +00:00
|
|
|
|
case LATEX_COMMAND:
|
2008-03-06 21:31:27 +00:00
|
|
|
|
os << '\\' << from_ascii(style.latexname());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
|
|
|
|
// Separate handling of optional argument inset.
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (style.optionalargs > 0) {
|
2008-02-27 20:43:16 +00:00
|
|
|
|
int ret = latexOptArgInsets(*pit, os, runparams,
|
2008-03-06 21:31:27 +00:00
|
|
|
|
style.optionalargs);
|
2004-11-19 16:17:52 +00:00
|
|
|
|
while (ret > 0) {
|
|
|
|
|
texrow.newline();
|
|
|
|
|
--ret;
|
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2008-03-06 21:31:27 +00:00
|
|
|
|
os << from_ascii(style.latexparam());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
break;
|
|
|
|
|
case LATEX_ITEM_ENVIRONMENT:
|
|
|
|
|
case LATEX_LIST_ENVIRONMENT:
|
|
|
|
|
os << "\\item ";
|
|
|
|
|
break;
|
|
|
|
|
case LATEX_BIB_ENVIRONMENT:
|
|
|
|
|
// ignore this, the inset will write itself
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
|
Font const outerfont = outerFont(distance(paragraphs.begin(), pit),
|
2007-03-18 10:59:16 +00:00
|
|
|
|
paragraphs);
|
|
|
|
|
|
2006-10-19 16:51:30 +00:00
|
|
|
|
// FIXME UNICODE
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_utf8(everypar);
|
2008-02-27 20:43:16 +00:00
|
|
|
|
bool need_par = pit->latex(bparams, outerfont,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
os, texrow, runparams);
|
|
|
|
|
|
|
|
|
|
// Make sure that \\par is done with the font of the last
|
|
|
|
|
// character if this has another size as the default.
|
|
|
|
|
// This is necessary because LaTeX (and LyX on the screen)
|
|
|
|
|
// calculates the space between the baselines according
|
|
|
|
|
// to this font. (Matthias)
|
|
|
|
|
//
|
|
|
|
|
// Is this really needed ? (Dekel)
|
|
|
|
|
// We do not need to use to change the font for the last paragraph
|
|
|
|
|
// or for a command.
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
|
Font const font = pit->empty()
|
2003-11-05 12:06:20 +00:00
|
|
|
|
? pit->getLayoutFont(bparams, outerfont)
|
2008-02-27 20:43:16 +00:00
|
|
|
|
: pit->getFont(bparams, pit->size() - 1, outerfont);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
bool is_command = style.isCommand();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (style.resfont.size() != font.fontInfo().size()
|
2008-03-21 22:51:36 +00:00
|
|
|
|
&& nextpit != paragraphs.end()
|
2003-11-05 12:06:20 +00:00
|
|
|
|
&& !is_command) {
|
|
|
|
|
if (!need_par)
|
|
|
|
|
os << '{';
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << "\\" << from_ascii(font.latexSize()) << " \\par}";
|
2003-11-05 12:06:20 +00:00
|
|
|
|
} else if (need_par) {
|
|
|
|
|
os << "\\par}";
|
|
|
|
|
} else if (is_command)
|
|
|
|
|
os << '}';
|
|
|
|
|
|
2007-01-17 22:01:08 +00:00
|
|
|
|
bool pending_newline = false;
|
2008-03-06 21:31:27 +00:00
|
|
|
|
switch (style.latextype) {
|
2003-11-05 12:06:20 +00:00
|
|
|
|
case LATEX_ITEM_ENVIRONMENT:
|
|
|
|
|
case LATEX_LIST_ENVIRONMENT:
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (nextpit != paragraphs.end()
|
|
|
|
|
&& (pit->params().depth() < nextpit->params().depth()))
|
2007-01-17 22:01:08 +00:00
|
|
|
|
pending_newline = true;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
break;
|
|
|
|
|
case LATEX_ENVIRONMENT: {
|
|
|
|
|
// if its the last paragraph of the current environment
|
|
|
|
|
// skip it otherwise fall through
|
2008-03-21 22:51:36 +00:00
|
|
|
|
ParagraphList::const_iterator next = nextpit;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-03-06 21:31:27 +00:00
|
|
|
|
if (next != paragraphs.end() && (next->layout() != pit->layout()
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|| next->params().depth() != pit->params().depth()))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fall through possible
|
|
|
|
|
default:
|
|
|
|
|
// we don't need it for the last paragraph!!!
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (nextpit != paragraphs.end())
|
2007-01-17 22:01:08 +00:00
|
|
|
|
pending_newline = true;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
|
if (pit->allowParagraphCustomization()) {
|
2004-09-28 13:29:19 +00:00
|
|
|
|
if (!pit->params().spacing().isDefault()
|
2008-03-21 22:51:36 +00:00
|
|
|
|
&& (nextpit == paragraphs.end() || !nextpit->hasSameLayout(*pit)))
|
2004-09-28 13:29:19 +00:00
|
|
|
|
{
|
2007-01-17 22:01:08 +00:00
|
|
|
|
if (pending_newline) {
|
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2008-01-14 14:53:29 +00:00
|
|
|
|
os << from_ascii(pit->params().spacing().writeEnvirEnd(useSetSpace));
|
2007-01-17 22:01:08 +00:00
|
|
|
|
pending_newline = true;
|
2004-09-28 13:29:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// Closing the language is needed for the last paragraph; it is also
|
|
|
|
|
// 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 =
|
|
|
|
|
// not for ArabTeX
|
|
|
|
|
(par_language->lang() != "arabic_arabtex" &&
|
|
|
|
|
outer_language->lang() != "arabic_arabtex") &&
|
|
|
|
|
// have we opened and \L or \R environment?
|
|
|
|
|
runparams.local_font != 0 &&
|
|
|
|
|
runparams.local_font->isRightToLeft() != par_language->rightToLeft() &&
|
|
|
|
|
// are we about to close the language?
|
2008-03-21 22:51:36 +00:00
|
|
|
|
((nextpit != paragraphs.end() &&
|
2007-07-20 01:28:20 +00:00
|
|
|
|
par_language->babel() !=
|
2008-03-21 22:51:36 +00:00
|
|
|
|
(nextpit->getParLanguage(bparams))->babel()) ||
|
|
|
|
|
(nextpit == paragraphs.end() &&
|
2007-07-20 01:28:20 +00:00
|
|
|
|
par_language->babel() != outer_language->babel()));
|
|
|
|
|
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (closing_rtl_ltr_environment || (nextpit == paragraphs.end()
|
2007-07-20 01:28:20 +00:00
|
|
|
|
&& par_language->babel() != outer_language->babel())) {
|
2004-04-22 13:59:39 +00:00
|
|
|
|
// Since \selectlanguage write the language to the aux file,
|
|
|
|
|
// we need to reset the language at the end of footnote or
|
|
|
|
|
// float.
|
|
|
|
|
|
2007-01-17 22:01:08 +00:00
|
|
|
|
if (pending_newline) {
|
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// 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 (!prev_language->babel().empty()) {
|
|
|
|
|
os << from_ascii(subst(
|
|
|
|
|
lyxrc.language_command_begin,
|
|
|
|
|
"$$lang",
|
|
|
|
|
prev_language->babel()));
|
|
|
|
|
pending_newline = true;
|
|
|
|
|
}
|
|
|
|
|
} else if (!par_language->babel().empty()) {
|
2007-05-05 19:18:34 +00:00
|
|
|
|
os << from_ascii(subst(
|
2007-12-08 11:21:00 +00:00
|
|
|
|
lyxrc.language_command_end,
|
2007-05-05 19:18:34 +00:00
|
|
|
|
"$$lang",
|
2007-12-08 11:21:00 +00:00
|
|
|
|
par_language->babel()));
|
2007-05-05 19:18:34 +00:00
|
|
|
|
pending_newline = true;
|
|
|
|
|
}
|
2007-05-05 20:27:43 +00:00
|
|
|
|
}
|
2004-04-22 13:59:39 +00:00
|
|
|
|
}
|
2007-07-20 01:28:20 +00:00
|
|
|
|
if (closing_rtl_ltr_environment)
|
|
|
|
|
os << "}";
|
2004-04-22 13:59:39 +00:00
|
|
|
|
|
2007-10-23 18:23:03 +00:00
|
|
|
|
if (pending_newline) {
|
2007-01-09 19:25:40 +00:00
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2007-07-20 01:28:20 +00:00
|
|
|
|
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// 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)
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (nextpit != paragraphs.end() && open_encoding_ == CJK &&
|
|
|
|
|
(nextpit->getParLanguage(bparams)->encoding()->package() != Encoding::CJK ||
|
|
|
|
|
nextpit->layout().isEnvironment() && nextpit->isMultiLingual(bparams))
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// in environments, CJK has to be closed later (nesting!)
|
2008-03-06 21:31:27 +00:00
|
|
|
|
&& !style.isEnvironment()) {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
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.
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (nextpit == paragraphs.end() && !style.isEnvironment()) {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
switch (open_encoding_) {
|
|
|
|
|
case CJK: {
|
|
|
|
|
// end of main text
|
2008-01-25 13:27:08 +00:00
|
|
|
|
if (maintext) {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
os << "\\end{CJK}\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
// end of an inset
|
|
|
|
|
} else
|
|
|
|
|
os << "\\end{CJK}";
|
|
|
|
|
open_encoding_ = none;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case inputenc: {
|
|
|
|
|
os << "\\egroup";
|
|
|
|
|
open_encoding_ = none;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case none:
|
|
|
|
|
default:
|
|
|
|
|
// do nothing
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// If this is the last paragraph, and a local_font was set upon entering
|
2008-03-26 22:38:41 +00:00
|
|
|
|
// 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")) {
|
2007-07-20 01:28:20 +00:00
|
|
|
|
runparams_in.encoding = runparams_in.local_font->language()->encoding();
|
2008-03-26 22:38:41 +00:00
|
|
|
|
os << setEncoding(runparams_in.encoding->iconvName());
|
2007-07-20 01:28:20 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// Otherwise, the current encoding should be set for the next paragraph.
|
|
|
|
|
else
|
|
|
|
|
runparams_in.encoding = runparams.encoding;
|
|
|
|
|
|
2007-01-09 19:25:40 +00:00
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// we don't need it for the last paragraph!!!
|
2004-04-22 13:59:39 +00:00
|
|
|
|
// Note from JMarc: we will re-add a \n explicitely in
|
|
|
|
|
// TeXEnvironment, because it is needed in this case
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (nextpit != paragraphs.end()) {
|
2003-11-05 12:06:20 +00:00
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-21 22:51:36 +00:00
|
|
|
|
if (nextpit != paragraphs.end())
|
|
|
|
|
LYXERR(Debug::LATEX, "TeXOnePar...done " << &*nextpit);
|
2006-10-26 15:01:45 +00:00
|
|
|
|
|
2008-03-21 22:51:36 +00:00
|
|
|
|
return nextpit;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-12-03 18:17:20 +00:00
|
|
|
|
} // anon namespace
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2004-02-11 14:45:44 +00:00
|
|
|
|
|
|
|
|
|
// LaTeX all paragraphs
|
2003-11-05 12:06:20 +00:00
|
|
|
|
void latexParagraphs(Buffer const & buf,
|
2008-01-25 13:27:08 +00:00
|
|
|
|
Text const & text,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
odocstream & os,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
TexRow & texrow,
|
|
|
|
|
OutputParams const & runparams,
|
|
|
|
|
string const & everypar)
|
|
|
|
|
{
|
|
|
|
|
bool was_title = false;
|
|
|
|
|
bool already_title = false;
|
2008-01-25 13:27:08 +00:00
|
|
|
|
BufferParams const & bparams = buf.params();
|
2008-02-28 01:42:02 +00:00
|
|
|
|
DocumentClass const & tclass = bparams.documentClass();
|
2008-01-25 13:27:08 +00:00
|
|
|
|
ParagraphList const & paragraphs = text.paragraphs();
|
2004-05-17 11:28:31 +00:00
|
|
|
|
ParagraphList::const_iterator par = paragraphs.begin();
|
|
|
|
|
ParagraphList::const_iterator endpar = paragraphs.end();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-04-10 21:49:34 +00:00
|
|
|
|
LASSERT(runparams.par_begin <= runparams.par_end, /**/);
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
// if only part of the paragraphs will be outputed
|
|
|
|
|
if (runparams.par_begin != runparams.par_end) {
|
|
|
|
|
par = boost::next(paragraphs.begin(), runparams.par_begin);
|
|
|
|
|
endpar = boost::next(paragraphs.begin(), runparams.par_end);
|
|
|
|
|
// runparams will be passed to nested paragraphs, so
|
|
|
|
|
// we have to reset the range parameters.
|
|
|
|
|
const_cast<OutputParams&>(runparams).par_begin = 0;
|
|
|
|
|
const_cast<OutputParams&>(runparams).par_end = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-25 13:27:08 +00:00
|
|
|
|
bool const maintext = text.isMainText(buf);
|
|
|
|
|
|
|
|
|
|
// Open a CJK environment at the beginning of the main buffer
|
|
|
|
|
// if the document's language is a CJK language
|
|
|
|
|
if (maintext && bparams.encoding().package() == Encoding::CJK) {
|
|
|
|
|
os << "\\begin{CJK}{" << from_ascii(bparams.encoding().latexName())
|
|
|
|
|
<< "}{}%\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
open_encoding_ = CJK;
|
|
|
|
|
}
|
|
|
|
|
// if "auto begin" is switched off, explicitely switch the
|
|
|
|
|
// language on at start
|
|
|
|
|
if (maintext && !lyxrc.language_auto_begin &&
|
|
|
|
|
!bparams.language->babel().empty()) {
|
|
|
|
|
// FIXME UNICODE
|
|
|
|
|
os << from_utf8(subst(lyxrc.language_command_begin,
|
|
|
|
|
"$$lang",
|
|
|
|
|
bparams.language->babel()))
|
|
|
|
|
<< '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ParagraphList::const_iterator lastpar;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// if only_body
|
|
|
|
|
while (par != endpar) {
|
2008-01-25 13:27:08 +00:00
|
|
|
|
lastpar = par;
|
2008-04-22 18:33:07 +00:00
|
|
|
|
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;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
if (tclass.titletype() == TITLE_ENVIRONMENT) {
|
2008-04-22 18:33:07 +00:00
|
|
|
|
os << "\\begin{"
|
|
|
|
|
<< from_ascii(tclass.titlename())
|
|
|
|
|
<< "}\n";
|
|
|
|
|
texrow.newline();
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2008-04-22 18:33:07 +00:00
|
|
|
|
} 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;
|
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
|
2008-04-22 18:33:07 +00:00
|
|
|
|
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);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
2007-12-12 19:28:07 +00:00
|
|
|
|
if (distance(lastpar, par) >= distance(lastpar, endpar))
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
break;
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
2008-04-22 18:33:07 +00:00
|
|
|
|
|
2003-11-05 12:06:20 +00:00
|
|
|
|
// It might be that we only have a title in this document
|
|
|
|
|
if (was_title && !already_title) {
|
|
|
|
|
if (tclass.titletype() == TITLE_ENVIRONMENT) {
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << "\\end{" << from_ascii(tclass.titlename())
|
2003-11-05 12:06:20 +00:00
|
|
|
|
<< "}\n";
|
|
|
|
|
}
|
|
|
|
|
else {
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << "\\" << from_ascii(tclass.titlename())
|
2003-11-05 12:06:20 +00:00
|
|
|
|
<< "\n";
|
|
|
|
|
}
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2008-04-22 18:33:07 +00:00
|
|
|
|
|
2008-01-25 13:27:08 +00:00
|
|
|
|
// 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() &&
|
|
|
|
|
lastpar->getParLanguage(bparams)->encoding()->package() != Encoding::CJK) {
|
|
|
|
|
os << from_utf8(subst(lyxrc.language_command_end,
|
|
|
|
|
"$$lang",
|
|
|
|
|
bparams.language->babel()))
|
|
|
|
|
<< '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
2008-04-22 18:33:07 +00:00
|
|
|
|
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// If the last paragraph is an environment, we'll have to close
|
|
|
|
|
// CJK at the very end to do proper nesting.
|
2008-01-25 13:27:08 +00:00
|
|
|
|
if (maintext && open_encoding_ == CJK) {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
os << "\\end{CJK}\n";
|
|
|
|
|
texrow.newline();
|
|
|
|
|
open_encoding_ = none;
|
|
|
|
|
}
|
2008-04-22 18:33:07 +00:00
|
|
|
|
|
2007-12-08 11:21:00 +00:00
|
|
|
|
// reset inherited encoding
|
2008-06-03 07:51:14 +00:00
|
|
|
|
if (cjk_inherited_ > 0) {
|
|
|
|
|
cjk_inherited_ -= 1;
|
|
|
|
|
if (cjk_inherited_ == 0)
|
|
|
|
|
open_encoding_ = CJK;
|
2007-12-08 11:21:00 +00:00
|
|
|
|
}
|
2003-11-05 12:06:20 +00:00
|
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
|
|
2007-07-05 19:19:41 +00:00
|
|
|
|
pair<bool, int> switchEncoding(odocstream & os, BufferParams const & bparams,
|
2007-12-17 10:53:38 +00:00
|
|
|
|
OutputParams const & runparams, Encoding const & newEnc)
|
2007-01-09 19:25:40 +00:00
|
|
|
|
{
|
2007-12-17 10:53:38 +00:00
|
|
|
|
Encoding const oldEnc = *runparams.encoding;
|
2007-12-08 11:21:00 +00:00
|
|
|
|
bool moving_arg = runparams.moving_arg;
|
2007-07-05 19:19:41 +00:00
|
|
|
|
if ((bparams.inputenc != "auto" && bparams.inputenc != "default")
|
|
|
|
|
|| moving_arg)
|
|
|
|
|
return make_pair(false, 0);
|
2007-05-07 17:10:10 +00:00
|
|
|
|
|
|
|
|
|
// Do nothing if the encoding is unchanged.
|
|
|
|
|
if (oldEnc.name() == newEnc.name())
|
2007-07-05 19:19:41 +00:00
|
|
|
|
return make_pair(false, 0);
|
2007-05-07 17:10:10 +00:00
|
|
|
|
|
2007-05-06 20:26:02 +00:00
|
|
|
|
// 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
|
2007-06-27 14:50:50 +00:00
|
|
|
|
// tis620-0 to latin1, but the text in latin1 contains ASCII only),
|
2007-05-06 20:26:02 +00:00
|
|
|
|
// but it is the best we can do
|
2007-05-07 17:10:10 +00:00
|
|
|
|
if (oldEnc.package() == Encoding::none
|
|
|
|
|
|| newEnc.package() == Encoding::none)
|
2007-07-05 19:19:41 +00:00
|
|
|
|
return make_pair(false, 0);
|
2007-05-07 17:10:10 +00:00
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "Changing LaTeX encoding from "
|
|
|
|
|
<< oldEnc.name() << " to " << newEnc.name());
|
2007-05-07 17:10:10 +00:00
|
|
|
|
os << setEncoding(newEnc.iconvName());
|
|
|
|
|
if (bparams.inputenc == "default")
|
2007-07-05 19:19:41 +00:00
|
|
|
|
return make_pair(true, 0);
|
2007-05-07 17:10:10 +00:00
|
|
|
|
|
2007-12-08 11:21:00 +00:00
|
|
|
|
docstring const inputenc_arg(from_ascii(newEnc.latexName()));
|
2007-05-07 17:10:10 +00:00
|
|
|
|
switch (newEnc.package()) {
|
|
|
|
|
case Encoding::none:
|
2007-07-05 19:19:41 +00:00
|
|
|
|
// shouldn't ever reach here, see above
|
|
|
|
|
return make_pair(true, 0);
|
2007-05-07 17:10:10 +00:00
|
|
|
|
case Encoding::inputenc: {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
int count = inputenc_arg.length();
|
|
|
|
|
if (oldEnc.package() == Encoding::CJK &&
|
|
|
|
|
open_encoding_ == CJK) {
|
2007-05-07 17:10:10 +00:00
|
|
|
|
os << "\\end{CJK}";
|
2007-12-08 11:21:00 +00:00
|
|
|
|
open_encoding_ = none;
|
2007-05-07 17:10:10 +00:00
|
|
|
|
count += 9;
|
|
|
|
|
}
|
2007-12-08 11:21:00 +00:00
|
|
|
|
else if (oldEnc.package() == Encoding::inputenc &&
|
|
|
|
|
open_encoding_ == inputenc) {
|
|
|
|
|
os << "\\egroup";
|
|
|
|
|
open_encoding_ = none;
|
|
|
|
|
count += 7;
|
|
|
|
|
}
|
|
|
|
|
if (runparams.local_font != 0 && oldEnc.package() == Encoding::CJK) {
|
|
|
|
|
// within insets, \inputenc switches need to be
|
|
|
|
|
// embraced within \bgroup ... \egroup; else CJK fails.
|
|
|
|
|
os << "\\bgroup";
|
|
|
|
|
count += 7;
|
|
|
|
|
open_encoding_ = inputenc;
|
|
|
|
|
}
|
|
|
|
|
os << "\\inputencoding{" << inputenc_arg << '}';
|
2007-07-05 19:19:41 +00:00
|
|
|
|
return make_pair(true, count + 16);
|
2007-11-15 20:04:51 +00:00
|
|
|
|
}
|
2007-05-07 17:10:10 +00:00
|
|
|
|
case Encoding::CJK: {
|
2007-12-08 11:21:00 +00:00
|
|
|
|
int count = inputenc_arg.length();
|
|
|
|
|
if (oldEnc.package() == Encoding::CJK &&
|
|
|
|
|
open_encoding_ == CJK) {
|
2007-05-07 17:10:10 +00:00
|
|
|
|
os << "\\end{CJK}";
|
|
|
|
|
count += 9;
|
2007-05-06 20:26:02 +00:00
|
|
|
|
}
|
2007-12-08 11:21:00 +00:00
|
|
|
|
if (oldEnc.package() == Encoding::inputenc &&
|
|
|
|
|
open_encoding_ == inputenc) {
|
|
|
|
|
os << "\\egroup";
|
|
|
|
|
count += 7;
|
|
|
|
|
}
|
|
|
|
|
os << "\\begin{CJK}{" << inputenc_arg << "}{}";
|
|
|
|
|
open_encoding_ = CJK;
|
2007-07-05 19:19:41 +00:00
|
|
|
|
return make_pair(true, count + 15);
|
2007-01-13 14:36:54 +00:00
|
|
|
|
}
|
2007-01-09 19:25:40 +00:00
|
|
|
|
}
|
2007-05-07 17:10:10 +00:00
|
|
|
|
// Dead code to avoid a warning:
|
2007-07-05 19:19:41 +00:00
|
|
|
|
return make_pair(true, 0);
|
2007-12-08 11:21:00 +00:00
|
|
|
|
|
2007-01-09 19:25:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
} // namespace lyx
|