2003-08-23 00:17:00 +00:00
|
|
|
|
/**
|
2007-04-26 04:41:58 +00:00
|
|
|
|
* \file Paragraph.cpp
|
2003-08-23 00:17:00 +00:00
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 17:27:08 +00:00
|
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
|
* \author Asger Alstrup
|
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
* \author Jean-Marc Lasgouttes
|
|
|
|
|
* \author Angus Leeming
|
|
|
|
|
* \author John Levon
|
|
|
|
|
* \author Andr<EFBFBD> P<EFBFBD>nitz
|
|
|
|
|
* \author Dekel Tsur
|
|
|
|
|
* \author J<EFBFBD>rgen Vigna
|
2002-03-21 17:27:08 +00:00
|
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
|
*/
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Paragraph.h"
|
2003-05-22 22:44:30 +00:00
|
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Buffer.h"
|
|
|
|
|
#include "BufferParams.h"
|
|
|
|
|
#include "Counters.h"
|
|
|
|
|
#include "Encoding.h"
|
2003-05-22 22:44:30 +00:00
|
|
|
|
#include "debug.h"
|
2001-04-05 12:26:41 +00:00
|
|
|
|
#include "gettext.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Language.h"
|
2005-01-24 17:12:19 +00:00
|
|
|
|
#include "LaTeXFeatures.h"
|
2007-04-26 17:34:20 +00:00
|
|
|
|
#include "Color.h"
|
2007-04-28 12:58:49 +00:00
|
|
|
|
#include "Length.h"
|
2007-04-29 18:17:15 +00:00
|
|
|
|
#include "Font.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "LyXRC.h"
|
|
|
|
|
#include "Row.h"
|
|
|
|
|
#include "Messages.h"
|
|
|
|
|
#include "OutputParams.h"
|
2007-03-18 10:59:16 +00:00
|
|
|
|
#include "output_latex.h"
|
2003-10-30 08:47:16 +00:00
|
|
|
|
#include "paragraph_funcs.h"
|
2007-04-24 10:01:03 +00:00
|
|
|
|
#include "ParagraphParameters.h"
|
2006-12-29 23:54:48 +00:00
|
|
|
|
#include "rowpainter.h"
|
2003-10-30 08:47:16 +00:00
|
|
|
|
#include "sgml.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "TexRow.h"
|
|
|
|
|
#include "VSpace.h"
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
2007-07-11 16:39:26 +00:00
|
|
|
|
#include "frontends/alert.h"
|
2006-12-29 23:54:48 +00:00
|
|
|
|
#include "frontends/FontMetrics.h"
|
|
|
|
|
|
2007-04-25 01:24:38 +00:00
|
|
|
|
#include "insets/InsetBibitem.h"
|
|
|
|
|
#include "insets/InsetOptArg.h"
|
2001-12-28 13:26:54 +00:00
|
|
|
|
|
|
|
|
|
#include "support/lstrings.h"
|
2003-11-25 17:23:36 +00:00
|
|
|
|
#include "support/textutils.h"
|
2005-01-06 16:39:35 +00:00
|
|
|
|
#include "support/convert.h"
|
2006-08-13 22:54:59 +00:00
|
|
|
|
#include "support/unicode.h"
|
2003-09-06 12:36:58 +00:00
|
|
|
|
|
2003-11-28 15:53:34 +00:00
|
|
|
|
#include <boost/bind.hpp>
|
2007-04-24 10:01:03 +00:00
|
|
|
|
#include <boost/next_prior.hpp>
|
2003-10-30 08:47:16 +00:00
|
|
|
|
|
2005-11-07 11:28:11 +00:00
|
|
|
|
#include <algorithm>
|
2004-07-24 10:55:30 +00:00
|
|
|
|
#include <sstream>
|
2003-10-30 08:47:16 +00:00
|
|
|
|
|
2004-01-28 16:21:29 +00:00
|
|
|
|
using std::distance;
|
2000-03-28 02:18:55 +00:00
|
|
|
|
using std::endl;
|
2003-10-06 15:43:21 +00:00
|
|
|
|
using std::string;
|
2003-09-09 22:13:45 +00:00
|
|
|
|
using std::ostream;
|
2001-11-27 10:34:16 +00:00
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
namespace lyx {
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
using support::contains;
|
2007-07-12 13:25:44 +00:00
|
|
|
|
using support::suffixIs;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
using support::rsplit;
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Paragraph::Pimpl
|
|
|
|
|
//
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
class Encoding;
|
2007-04-29 18:58:28 +00:00
|
|
|
|
class Layout;
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Paragraph::Pimpl {
|
|
|
|
|
public:
|
|
|
|
|
///
|
|
|
|
|
Pimpl(Paragraph * owner);
|
|
|
|
|
/// "Copy constructor"
|
|
|
|
|
Pimpl(Pimpl const &, Paragraph * owner);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Change tracking
|
|
|
|
|
//
|
|
|
|
|
/// look up change at given pos
|
|
|
|
|
Change const & lookupChange(pos_type pos) const;
|
|
|
|
|
/// is there a change within the given range ?
|
|
|
|
|
bool isChanged(pos_type start, pos_type end) const;
|
|
|
|
|
/// will the paragraph be physically merged with the next
|
|
|
|
|
/// one if the imaginary end-of-par character is logically deleted?
|
|
|
|
|
bool isMergedOnEndOfParDeletion(bool trackChanges) const;
|
|
|
|
|
/// set change for the entire par
|
|
|
|
|
void setChange(Change const & change);
|
|
|
|
|
/// set change at given pos
|
|
|
|
|
void setChange(pos_type pos, Change const & change);
|
|
|
|
|
/// accept changes within the given range
|
|
|
|
|
void acceptChanges(BufferParams const & bparams, pos_type start, pos_type end);
|
|
|
|
|
/// reject changes within the given range
|
|
|
|
|
void rejectChanges(BufferParams const & bparams, pos_type start, pos_type end);
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
value_type getChar(pos_type pos) const;
|
|
|
|
|
///
|
|
|
|
|
void insertChar(pos_type pos, value_type c, Change const & change);
|
|
|
|
|
///
|
2007-04-29 13:39:47 +00:00
|
|
|
|
void insertInset(pos_type pos, Inset * inset, Change const & change);
|
2007-04-24 10:01:03 +00:00
|
|
|
|
/// (logically) erase the char at pos; return true if it was actually erased
|
|
|
|
|
bool eraseChar(pos_type pos, bool trackChanges);
|
|
|
|
|
/// (logically) erase the given range; return the number of chars actually erased
|
|
|
|
|
int eraseChars(pos_type start, pos_type end, bool trackChanges);
|
|
|
|
|
///
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset * inset_owner;
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
/** A font entry covers a range of positions. Notice that the
|
|
|
|
|
entries in the list are inserted in random order.
|
|
|
|
|
I don't think it's worth the effort to implement a more effective
|
|
|
|
|
datastructure, because the number of different fonts in a paragraph
|
|
|
|
|
is limited. (Asger)
|
|
|
|
|
Nevertheless, I decided to store fontlist using a sorted vector:
|
|
|
|
|
fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
|
|
|
|
|
pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
|
|
|
|
|
and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
|
|
|
|
|
(font_1 covers the chars 0,...,pos_1) (Dekel)
|
|
|
|
|
*/
|
|
|
|
|
class FontTable {
|
|
|
|
|
public:
|
|
|
|
|
///
|
2007-04-29 18:17:15 +00:00
|
|
|
|
FontTable(pos_type p, Font const & f)
|
2007-04-24 10:01:03 +00:00
|
|
|
|
: pos_(p), font_(f)
|
|
|
|
|
{}
|
|
|
|
|
///
|
|
|
|
|
pos_type pos() const { return pos_; }
|
|
|
|
|
///
|
|
|
|
|
void pos(pos_type p) { pos_ = p; }
|
|
|
|
|
///
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const & font() const { return font_; }
|
2007-04-24 10:01:03 +00:00
|
|
|
|
///
|
2007-04-29 18:17:15 +00:00
|
|
|
|
void font(Font const & f) { font_ = f;}
|
2007-04-24 10:01:03 +00:00
|
|
|
|
private:
|
|
|
|
|
/// End position of paragraph this font attribute covers
|
|
|
|
|
pos_type pos_;
|
|
|
|
|
/** Font. Interpretation of the font values:
|
2007-04-29 18:17:15 +00:00
|
|
|
|
If a value is Font::INHERIT_*, it means that the font
|
2007-04-24 10:01:03 +00:00
|
|
|
|
attribute is inherited from either the layout of this
|
|
|
|
|
paragraph or, in the case of nested paragraphs, from the
|
|
|
|
|
layout in the environment one level up until completely
|
|
|
|
|
resolved.
|
2007-04-29 18:17:15 +00:00
|
|
|
|
The values Font::IGNORE_* and Font::TOGGLE are NOT
|
2007-04-24 10:01:03 +00:00
|
|
|
|
allowed in these font tables.
|
|
|
|
|
*/
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font_;
|
2007-04-24 10:01:03 +00:00
|
|
|
|
};
|
|
|
|
|
///
|
|
|
|
|
friend class matchFT;
|
|
|
|
|
///
|
|
|
|
|
class matchFT {
|
|
|
|
|
public:
|
|
|
|
|
/// used by lower_bound and upper_bound
|
|
|
|
|
int operator()(FontTable const & a, FontTable const & b) const {
|
|
|
|
|
return a.pos() < b.pos();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
typedef std::vector<FontTable> FontList;
|
|
|
|
|
///
|
|
|
|
|
FontList fontlist;
|
|
|
|
|
|
|
|
|
|
/// Output the surrogate pair formed by \p c and \p next to \p os.
|
|
|
|
|
/// \return the number of characters written.
|
|
|
|
|
int latexSurrogatePair(odocstream & os, value_type c, value_type next,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Encoding const &);
|
2007-04-24 10:01:03 +00:00
|
|
|
|
/// Output a space in appropriate formatting (or a surrogate pair
|
|
|
|
|
/// if the next character is a combining character).
|
|
|
|
|
/// \return whether a surrogate pair was output.
|
|
|
|
|
bool simpleTeXBlanks(Encoding const &,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
odocstream &, TexRow & texrow,
|
2007-04-24 10:01:03 +00:00
|
|
|
|
pos_type & i,
|
|
|
|
|
unsigned int & column,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const & font,
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout const & style);
|
2007-04-24 10:01:03 +00:00
|
|
|
|
///
|
|
|
|
|
void simpleTeXSpecialChars(Buffer const &, BufferParams const &,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
odocstream &,
|
2007-07-20 01:28:20 +00:00
|
|
|
|
TexRow & texrow, OutputParams &,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Font & running_font,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font & basefont,
|
|
|
|
|
Font const & outerfont,
|
2007-04-24 10:01:03 +00:00
|
|
|
|
bool & open_font,
|
2007-05-08 17:46:03 +00:00
|
|
|
|
Change & running_change,
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout const & style,
|
2007-04-24 10:01:03 +00:00
|
|
|
|
pos_type & i,
|
|
|
|
|
unsigned int & column, value_type const c);
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
void validate(LaTeXFeatures & features,
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout const & layout) const;
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
unsigned int id_;
|
|
|
|
|
///
|
|
|
|
|
static unsigned int paragraph_id;
|
|
|
|
|
///
|
|
|
|
|
ParagraphParameters params;
|
|
|
|
|
|
2007-07-09 20:52:34 +00:00
|
|
|
|
//private:
|
2007-04-24 10:01:03 +00:00
|
|
|
|
///
|
|
|
|
|
pos_type size() const { return owner_->size(); }
|
|
|
|
|
/// match a string against a particular point in the paragraph
|
|
|
|
|
bool isTextAt(std::string const & str, pos_type pos) const;
|
|
|
|
|
|
|
|
|
|
/// for recording and looking up changes
|
|
|
|
|
Changes changes_;
|
|
|
|
|
|
|
|
|
|
/// Who owns us?
|
|
|
|
|
Paragraph * owner_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using std::endl;
|
|
|
|
|
using std::upper_bound;
|
|
|
|
|
using std::lower_bound;
|
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialization of the counter for the paragraph id's,
|
|
|
|
|
unsigned int Paragraph::Pimpl::paragraph_id = 0;
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
struct special_phrase {
|
|
|
|
|
string phrase;
|
|
|
|
|
docstring macro;
|
|
|
|
|
bool builtin;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
special_phrase const special_phrases[] = {
|
|
|
|
|
{ "LyX", from_ascii("\\LyX{}"), false },
|
|
|
|
|
{ "TeX", from_ascii("\\TeX{}"), true },
|
|
|
|
|
{ "LaTeX2e", from_ascii("\\LaTeXe{}"), true },
|
|
|
|
|
{ "LaTeX", from_ascii("\\LaTeX{}"), true },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
size_t const phrases_nr = sizeof(special_phrases)/sizeof(special_phrase);
|
|
|
|
|
|
|
|
|
|
} // namespace anon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Paragraph::Pimpl::Pimpl(Paragraph * owner)
|
|
|
|
|
: owner_(owner)
|
|
|
|
|
{
|
|
|
|
|
inset_owner = 0;
|
|
|
|
|
id_ = paragraph_id++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Paragraph::Pimpl::Pimpl(Pimpl const & p, Paragraph * owner)
|
|
|
|
|
: params(p.params), changes_(p.changes_), owner_(owner)
|
|
|
|
|
{
|
|
|
|
|
inset_owner = p.inset_owner;
|
|
|
|
|
fontlist = p.fontlist;
|
|
|
|
|
id_ = paragraph_id++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Paragraph::Pimpl::isChanged(pos_type start, pos_type end) const
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(start >= 0 && start <= size());
|
|
|
|
|
BOOST_ASSERT(end > start && end <= size() + 1);
|
|
|
|
|
|
|
|
|
|
return changes_.isChanged(start, end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Paragraph::Pimpl::isMergedOnEndOfParDeletion(bool trackChanges) const {
|
|
|
|
|
// keep the logic here in sync with the logic of eraseChars()
|
|
|
|
|
|
|
|
|
|
if (!trackChanges) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Change change = changes_.lookup(size());
|
|
|
|
|
|
|
|
|
|
return change.type == Change::INSERTED && change.author == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::setChange(Change const & change)
|
|
|
|
|
{
|
|
|
|
|
// beware of the imaginary end-of-par character!
|
|
|
|
|
changes_.set(change, 0, size() + 1);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Propagate the change recursively - but not in case of DELETED!
|
|
|
|
|
*
|
|
|
|
|
* Imagine that your co-author makes changes in an existing inset. He
|
|
|
|
|
* sends your document to you and you come to the conclusion that the
|
|
|
|
|
* inset should go completely. If you erase it, LyX must not delete all
|
|
|
|
|
* text within the inset. Otherwise, the change tracked insertions of
|
|
|
|
|
* your co-author get lost and there is no way to restore them later.
|
|
|
|
|
*
|
|
|
|
|
* Conclusion: An inset's content should remain untouched if you delete it
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (change.type != Change::DELETED) {
|
|
|
|
|
for (pos_type pos = 0; pos < size(); ++pos) {
|
|
|
|
|
if (owner_->isInset(pos)) {
|
|
|
|
|
owner_->getInset(pos)->setChange(change);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::setChange(pos_type pos, Change const & change)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(pos >= 0 && pos <= size());
|
|
|
|
|
|
|
|
|
|
changes_.set(change, pos);
|
|
|
|
|
|
|
|
|
|
// see comment in setChange(Change const &) above
|
|
|
|
|
|
|
|
|
|
if (change.type != Change::DELETED &&
|
|
|
|
|
pos < size() && owner_->isInset(pos)) {
|
|
|
|
|
owner_->getInset(pos)->setChange(change);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Change const & Paragraph::Pimpl::lookupChange(pos_type pos) const
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(pos >= 0 && pos <= size());
|
|
|
|
|
|
|
|
|
|
return changes_.lookup(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::acceptChanges(BufferParams const & bparams, pos_type start, pos_type end)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(start >= 0 && start <= size());
|
|
|
|
|
BOOST_ASSERT(end > start && end <= size() + 1);
|
|
|
|
|
|
|
|
|
|
for (pos_type pos = start; pos < end; ++pos) {
|
|
|
|
|
switch (lookupChange(pos).type) {
|
|
|
|
|
case Change::UNCHANGED:
|
|
|
|
|
// accept changes in nested inset
|
|
|
|
|
if (pos < size() && owner_->isInset(pos)) {
|
|
|
|
|
owner_->getInset(pos)->acceptChanges(bparams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Change::INSERTED:
|
|
|
|
|
changes_.set(Change(Change::UNCHANGED), pos);
|
|
|
|
|
// also accept changes in nested inset
|
|
|
|
|
if (pos < size() && owner_->isInset(pos)) {
|
|
|
|
|
owner_->getInset(pos)->acceptChanges(bparams);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Change::DELETED:
|
|
|
|
|
// Suppress access to non-existent
|
|
|
|
|
// "end-of-paragraph char"
|
|
|
|
|
if (pos < size()) {
|
|
|
|
|
eraseChar(pos, false);
|
|
|
|
|
--end;
|
|
|
|
|
--pos;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::rejectChanges(BufferParams const & bparams, pos_type start, pos_type end)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(start >= 0 && start <= size());
|
|
|
|
|
BOOST_ASSERT(end > start && end <= size() + 1);
|
|
|
|
|
|
|
|
|
|
for (pos_type pos = start; pos < end; ++pos) {
|
|
|
|
|
switch (lookupChange(pos).type) {
|
|
|
|
|
case Change::UNCHANGED:
|
|
|
|
|
// reject changes in nested inset
|
|
|
|
|
if (pos < size() && owner_->isInset(pos)) {
|
|
|
|
|
owner_->getInset(pos)->rejectChanges(bparams);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Change::INSERTED:
|
|
|
|
|
// Suppress access to non-existent
|
|
|
|
|
// "end-of-paragraph char"
|
|
|
|
|
if (pos < size()) {
|
|
|
|
|
eraseChar(pos, false);
|
|
|
|
|
--end;
|
|
|
|
|
--pos;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Change::DELETED:
|
|
|
|
|
changes_.set(Change(Change::UNCHANGED), pos);
|
|
|
|
|
|
|
|
|
|
// Do NOT reject changes within a deleted inset!
|
|
|
|
|
// There may be insertions of a co-author inside of it!
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Paragraph::value_type Paragraph::Pimpl::getChar(pos_type pos) const
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(pos >= 0 && pos <= size());
|
|
|
|
|
|
|
|
|
|
return owner_->getChar(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::insertChar(pos_type pos, value_type c, Change const & change)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(pos >= 0 && pos <= size());
|
|
|
|
|
|
|
|
|
|
// track change
|
|
|
|
|
changes_.insert(change, pos);
|
|
|
|
|
|
|
|
|
|
// This is actually very common when parsing buffers (and
|
|
|
|
|
// maybe inserting ascii text)
|
|
|
|
|
if (pos == size()) {
|
|
|
|
|
// when appending characters, no need to update tables
|
|
|
|
|
owner_->text_.push_back(c);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner_->text_.insert(owner_->text_.begin() + pos, c);
|
|
|
|
|
|
|
|
|
|
// Update the font table.
|
2007-04-29 18:17:15 +00:00
|
|
|
|
FontTable search_font(pos, Font());
|
2007-05-28 22:27:45 +00:00
|
|
|
|
for (FontList::iterator it
|
2007-04-24 10:01:03 +00:00
|
|
|
|
= lower_bound(fontlist.begin(), fontlist.end(), search_font, matchFT());
|
|
|
|
|
it != fontlist.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
it->pos(it->pos() + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the insets
|
|
|
|
|
owner_->insetlist.increasePosAfterPos(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
void Paragraph::Pimpl::insertInset(pos_type pos, Inset * inset,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Change const & change)
|
2007-04-24 10:01:03 +00:00
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(inset);
|
|
|
|
|
BOOST_ASSERT(pos >= 0 && pos <= size());
|
|
|
|
|
|
|
|
|
|
insertChar(pos, META_INSET, change);
|
|
|
|
|
BOOST_ASSERT(owner_->text_[pos] == META_INSET);
|
|
|
|
|
|
|
|
|
|
// Add a new entry in the insetlist.
|
|
|
|
|
owner_->insetlist.insert(inset, pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Paragraph::Pimpl::eraseChar(pos_type pos, bool trackChanges)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(pos >= 0 && pos <= size());
|
|
|
|
|
|
|
|
|
|
// keep the logic here in sync with the logic of isMergedOnEndOfParDeletion()
|
|
|
|
|
|
|
|
|
|
if (trackChanges) {
|
|
|
|
|
Change change = changes_.lookup(pos);
|
|
|
|
|
|
2007-05-28 22:27:45 +00:00
|
|
|
|
// set the character to DELETED if
|
2007-04-24 10:01:03 +00:00
|
|
|
|
// a) it was previously unchanged or
|
|
|
|
|
// b) it was inserted by a co-author
|
|
|
|
|
|
|
|
|
|
if (change.type == Change::UNCHANGED ||
|
|
|
|
|
(change.type == Change::INSERTED && change.author != 0)) {
|
|
|
|
|
setChange(pos, Change(Change::DELETED));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (change.type == Change::DELETED)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Don't physically access the imaginary end-of-paragraph character.
|
|
|
|
|
// eraseChar() can only mark it as DELETED. A physical deletion of
|
|
|
|
|
// end-of-par must be handled externally.
|
|
|
|
|
if (pos == size()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// track change
|
|
|
|
|
changes_.erase(pos);
|
|
|
|
|
|
|
|
|
|
// if it is an inset, delete the inset entry
|
|
|
|
|
if (owner_->text_[pos] == Paragraph::META_INSET) {
|
|
|
|
|
owner_->insetlist.erase(pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner_->text_.erase(owner_->text_.begin() + pos);
|
|
|
|
|
|
|
|
|
|
// Erase entries in the tables.
|
2007-04-29 18:17:15 +00:00
|
|
|
|
FontTable search_font(pos, Font());
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
FontList::iterator it =
|
|
|
|
|
lower_bound(fontlist.begin(),
|
|
|
|
|
fontlist.end(),
|
|
|
|
|
search_font, matchFT());
|
|
|
|
|
if (it != fontlist.end() && it->pos() == pos &&
|
|
|
|
|
(pos == 0 ||
|
|
|
|
|
(it != fontlist.begin()
|
|
|
|
|
&& boost::prior(it)->pos() == pos - 1))) {
|
|
|
|
|
// If it is a multi-character font
|
|
|
|
|
// entry, we just make it smaller
|
|
|
|
|
// (see update below), otherwise we
|
|
|
|
|
// should delete it.
|
|
|
|
|
unsigned int const i = it - fontlist.begin();
|
|
|
|
|
fontlist.erase(fontlist.begin() + i);
|
|
|
|
|
it = fontlist.begin() + i;
|
|
|
|
|
if (i > 0 && i < fontlist.size() &&
|
|
|
|
|
fontlist[i - 1].font() == fontlist[i].font()) {
|
|
|
|
|
fontlist.erase(fontlist.begin() + i - 1);
|
|
|
|
|
it = fontlist.begin() + i - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update all other entries
|
|
|
|
|
FontList::iterator fend = fontlist.end();
|
|
|
|
|
for (; it != fend; ++it)
|
|
|
|
|
it->pos(it->pos() - 1);
|
|
|
|
|
|
|
|
|
|
// Update the insetlist
|
|
|
|
|
owner_->insetlist.decreasePosAfterPos(pos);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Paragraph::Pimpl::eraseChars(pos_type start, pos_type end, bool trackChanges)
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(start >= 0 && start <= size());
|
|
|
|
|
BOOST_ASSERT(end >= start && end <= size() + 1);
|
|
|
|
|
|
|
|
|
|
pos_type i = start;
|
|
|
|
|
for (pos_type count = end - start; count; --count) {
|
|
|
|
|
if (!eraseChar(i, trackChanges))
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
return end - i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Paragraph::Pimpl::latexSurrogatePair(odocstream & os, value_type c,
|
|
|
|
|
value_type next, Encoding const & encoding)
|
|
|
|
|
{
|
|
|
|
|
// Writing next here may circumvent a possible font change between
|
|
|
|
|
// c and next. Since next is only output if it forms a surrogate pair
|
|
|
|
|
// with c we can ignore this:
|
|
|
|
|
// A font change inside a surrogate pair does not make sense and is
|
|
|
|
|
// hopefully impossible to input.
|
|
|
|
|
// FIXME: change tracking
|
|
|
|
|
// Is this correct WRT change tracking?
|
|
|
|
|
docstring const latex1 = encoding.latexChar(next);
|
|
|
|
|
docstring const latex2 = encoding.latexChar(c);
|
|
|
|
|
os << latex1 << '{' << latex2 << '}';
|
|
|
|
|
return latex1.length() + latex2.length() + 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Paragraph::Pimpl::simpleTeXBlanks(Encoding const & encoding,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
|
|
|
|
pos_type & i,
|
2007-04-24 10:01:03 +00:00
|
|
|
|
unsigned int & column,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const & font,
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout const & style)
|
2007-04-24 10:01:03 +00:00
|
|
|
|
{
|
|
|
|
|
if (style.pass_thru)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (i < size() - 1) {
|
|
|
|
|
char_type next = getChar(i + 1);
|
|
|
|
|
if (Encodings::isCombiningChar(next)) {
|
|
|
|
|
// This space has an accent, so we must always output it.
|
|
|
|
|
column += latexSurrogatePair(os, ' ', next, encoding) - 1;
|
|
|
|
|
++i;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lyxrc.plaintext_linelen > 0
|
|
|
|
|
&& column > lyxrc.plaintext_linelen
|
|
|
|
|
&& i
|
|
|
|
|
&& getChar(i - 1) != ' '
|
|
|
|
|
&& (i < size() - 1)
|
|
|
|
|
// same in FreeSpacing mode
|
|
|
|
|
&& !owner_->isFreeSpacing()
|
|
|
|
|
// In typewriter mode, we want to avoid
|
|
|
|
|
// ! . ? : at the end of a line
|
2007-04-29 18:17:15 +00:00
|
|
|
|
&& !(font.family() == Font::TYPEWRITER_FAMILY
|
2007-04-24 10:01:03 +00:00
|
|
|
|
&& (getChar(i - 1) == '.'
|
|
|
|
|
|| getChar(i - 1) == '?'
|
|
|
|
|
|| getChar(i - 1) == ':'
|
|
|
|
|
|| getChar(i - 1) == '!'))) {
|
|
|
|
|
os << '\n';
|
|
|
|
|
texrow.newline();
|
|
|
|
|
texrow.start(owner_->id(), i + 1);
|
|
|
|
|
column = 0;
|
|
|
|
|
} else if (style.free_spacing) {
|
|
|
|
|
os << '~';
|
|
|
|
|
} else {
|
|
|
|
|
os << ' ';
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Paragraph::Pimpl::isTextAt(string const & str, pos_type pos) const
|
|
|
|
|
{
|
|
|
|
|
pos_type const len = str.length();
|
|
|
|
|
|
|
|
|
|
// is the paragraph large enough?
|
|
|
|
|
if (pos + len > size())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// does the wanted text start at point?
|
|
|
|
|
for (string::size_type i = 0; i < str.length(); ++i) {
|
|
|
|
|
// Caution: direct comparison of characters works only
|
|
|
|
|
// because str is pure ASCII.
|
|
|
|
|
if (str[i] != owner_->text_[pos + i])
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// is there a font change in middle of the word?
|
|
|
|
|
FontList::const_iterator cit = fontlist.begin();
|
|
|
|
|
FontList::const_iterator end = fontlist.end();
|
|
|
|
|
for (; cit != end; ++cit) {
|
|
|
|
|
if (cit->pos() >= pos)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cit != end && pos + len - 1 > cit->pos())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
|
|
|
|
|
BufferParams const & bparams,
|
|
|
|
|
odocstream & os,
|
|
|
|
|
TexRow & texrow,
|
2007-07-20 01:28:20 +00:00
|
|
|
|
OutputParams & runparams,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font & running_font,
|
|
|
|
|
Font & basefont,
|
|
|
|
|
Font const & outerfont,
|
2007-04-24 10:01:03 +00:00
|
|
|
|
bool & open_font,
|
2007-05-08 17:46:03 +00:00
|
|
|
|
Change & running_change,
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout const & style,
|
2007-04-24 10:01:03 +00:00
|
|
|
|
pos_type & i,
|
|
|
|
|
unsigned int & column,
|
|
|
|
|
value_type const c)
|
|
|
|
|
{
|
|
|
|
|
if (style.pass_thru) {
|
|
|
|
|
if (c != Paragraph::META_INSET) {
|
|
|
|
|
if (c != '\0')
|
|
|
|
|
// FIXME UNICODE: This can fail if c cannot
|
|
|
|
|
// be encoded in the current encoding.
|
|
|
|
|
os.put(c);
|
|
|
|
|
} else
|
|
|
|
|
owner_->getInset(i)->plaintext(buf, os, runparams);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Two major modes: LaTeX or plain
|
|
|
|
|
// Handle here those cases common to both modes
|
|
|
|
|
// and then split to handle the two modes separately.
|
|
|
|
|
switch (c) {
|
|
|
|
|
case Paragraph::META_INSET: {
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset * inset = owner_->getInset(i);
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
// FIXME: remove this check
|
|
|
|
|
if (!inset)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// FIXME: move this to InsetNewline::latex
|
2007-04-29 13:39:47 +00:00
|
|
|
|
if (inset->lyxCode() == Inset::NEWLINE_CODE) {
|
2007-04-24 10:01:03 +00:00
|
|
|
|
// newlines are handled differently here than
|
|
|
|
|
// the default in simpleTeXSpecialChars().
|
|
|
|
|
if (!style.newline_allowed) {
|
|
|
|
|
os << '\n';
|
|
|
|
|
} else {
|
|
|
|
|
if (open_font) {
|
|
|
|
|
column += running_font.latexWriteEndChanges(
|
2007-05-06 20:26:02 +00:00
|
|
|
|
os, bparams, runparams,
|
|
|
|
|
basefont, basefont);
|
2007-04-24 10:01:03 +00:00
|
|
|
|
open_font = false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
if (running_font.family() == Font::TYPEWRITER_FAMILY)
|
2007-04-24 10:01:03 +00:00
|
|
|
|
os << '~';
|
|
|
|
|
|
|
|
|
|
basefont = owner_->getLayoutFont(bparams, outerfont);
|
|
|
|
|
running_font = basefont;
|
|
|
|
|
|
|
|
|
|
if (runparams.moving_arg)
|
|
|
|
|
os << "\\protect ";
|
|
|
|
|
|
|
|
|
|
os << "\\\\\n";
|
|
|
|
|
}
|
|
|
|
|
texrow.newline();
|
|
|
|
|
texrow.start(owner_->id(), i + 1);
|
|
|
|
|
column = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-21 18:10:55 +00:00
|
|
|
|
if (lookupChange(i).type == Change::DELETED) {
|
|
|
|
|
if( ++runparams.inDeletedInset == 1)
|
|
|
|
|
runparams.changeOfDeletedInset = lookupChange(i);
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-24 10:01:03 +00:00
|
|
|
|
if (inset->canTrackChanges()) {
|
2007-05-08 17:46:03 +00:00
|
|
|
|
column += Changes::latexMarkChange(os, bparams, running_change,
|
|
|
|
|
Change(Change::UNCHANGED));
|
|
|
|
|
running_change = Change(Change::UNCHANGED);
|
2007-04-24 10:01:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool close = false;
|
|
|
|
|
odocstream::pos_type const len = os.tellp();
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
if ((inset->lyxCode() == Inset::GRAPHICS_CODE
|
|
|
|
|
|| inset->lyxCode() == Inset::MATH_CODE
|
|
|
|
|
|| inset->lyxCode() == Inset::URL_CODE)
|
2007-04-24 10:01:03 +00:00
|
|
|
|
&& running_font.isRightToLeft()) {
|
2007-05-31 18:53:01 +00:00
|
|
|
|
if (running_font.language()->lang() == "farsi")
|
|
|
|
|
os << "\\beginL{}";
|
|
|
|
|
else
|
|
|
|
|
os << "\\L{";
|
2007-04-24 10:01:03 +00:00
|
|
|
|
close = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_WARNINGS
|
|
|
|
|
#warning Bug: we can have an empty font change here!
|
|
|
|
|
// if there has just been a font change, we are going to close it
|
|
|
|
|
// right now, which means stupid latex code like \textsf{}. AFAIK,
|
|
|
|
|
// this does not harm dvi output. A minor bug, thus (JMarc)
|
|
|
|
|
#endif
|
2007-07-20 01:28:20 +00:00
|
|
|
|
// Some insets cannot be inside a font change command.
|
|
|
|
|
// However, even such insets *can* be placed in \L or \R
|
|
|
|
|
// or their equivalents (for RTL language switches), so we don't
|
|
|
|
|
// close the language in those cases.
|
|
|
|
|
// ArabTeX, though, cannot handle this special behavior, it seems.
|
|
|
|
|
bool arabtex = basefont.language()->lang() == "arabic_arabtex" ||
|
|
|
|
|
running_font.language()->lang() == "arabic_arabtex";
|
2007-04-24 10:01:03 +00:00
|
|
|
|
if (open_font && inset->noFontChange()) {
|
2007-07-20 01:28:20 +00:00
|
|
|
|
bool closeLanguage = arabtex ||
|
|
|
|
|
basefont.isRightToLeft() == running_font.isRightToLeft();
|
|
|
|
|
unsigned int count = running_font.latexWriteEndChanges(
|
2007-05-06 20:26:02 +00:00
|
|
|
|
os, bparams, runparams,
|
2007-07-20 01:28:20 +00:00
|
|
|
|
basefont, basefont, closeLanguage);
|
|
|
|
|
column += count;
|
|
|
|
|
// if any font properties were closed, update the running_font,
|
|
|
|
|
// making sure, however, to leave the language as it was
|
|
|
|
|
if (count > 0) {
|
|
|
|
|
// FIXME: probably a better way to keep track of the old
|
|
|
|
|
// language, than copying the entire font?
|
|
|
|
|
Font const copy_font(running_font);
|
|
|
|
|
basefont = owner_->getLayoutFont(bparams, outerfont);
|
|
|
|
|
running_font = basefont;
|
|
|
|
|
if (!closeLanguage)
|
|
|
|
|
running_font.setLanguage(copy_font.language());
|
|
|
|
|
// leave font open if language is still open
|
|
|
|
|
open_font = (running_font.language() == basefont.language());
|
|
|
|
|
if (closeLanguage)
|
|
|
|
|
runparams.local_font = &basefont;
|
|
|
|
|
}
|
2007-04-24 10:01:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tmp = inset->latex(buf, os, runparams);
|
|
|
|
|
|
2007-05-31 18:53:01 +00:00
|
|
|
|
if (close) {
|
|
|
|
|
if (running_font.language()->lang() == "farsi")
|
|
|
|
|
os << "\\endL{}";
|
|
|
|
|
else
|
|
|
|
|
os << '}';
|
|
|
|
|
}
|
2007-04-24 10:01:03 +00:00
|
|
|
|
|
|
|
|
|
if (tmp) {
|
|
|
|
|
for (int j = 0; j < tmp; ++j) {
|
|
|
|
|
texrow.newline();
|
|
|
|
|
}
|
|
|
|
|
texrow.start(owner_->id(), i + 1);
|
|
|
|
|
column = 0;
|
|
|
|
|
} else {
|
|
|
|
|
column += os.tellp() - len;
|
|
|
|
|
}
|
2007-07-21 18:10:55 +00:00
|
|
|
|
|
|
|
|
|
if (lookupChange(i).type == Change::DELETED) {
|
|
|
|
|
--runparams.inDeletedInset;
|
|
|
|
|
}
|
2007-04-24 10:01:03 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
// And now for the special cases within each mode
|
|
|
|
|
|
|
|
|
|
switch (c) {
|
|
|
|
|
case '\\':
|
|
|
|
|
os << "\\textbackslash{}";
|
|
|
|
|
column += 15;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '|': case '<': case '>':
|
|
|
|
|
// In T1 encoding, these characters exist
|
|
|
|
|
if (lyxrc.fontenc == "T1") {
|
|
|
|
|
os.put(c);
|
|
|
|
|
//... but we should avoid ligatures
|
|
|
|
|
if ((c == '>' || c == '<')
|
|
|
|
|
&& i <= size() - 2
|
|
|
|
|
&& getChar(i + 1) == c) {
|
|
|
|
|
//os << "\\textcompwordmark{}";
|
|
|
|
|
//column += 19;
|
|
|
|
|
// Jean-Marc, have a look at
|
|
|
|
|
// this. I<>think this works
|
|
|
|
|
// equally well:
|
|
|
|
|
os << "\\,{}";
|
|
|
|
|
// Lgb
|
|
|
|
|
column += 3;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// Typewriter font also has them
|
2007-04-29 18:17:15 +00:00
|
|
|
|
if (running_font.family() == Font::TYPEWRITER_FAMILY) {
|
2007-04-24 10:01:03 +00:00
|
|
|
|
os.put(c);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// Otherwise, we use what LaTeX
|
|
|
|
|
// provides us.
|
|
|
|
|
switch (c) {
|
|
|
|
|
case '<':
|
|
|
|
|
os << "\\textless{}";
|
|
|
|
|
column += 10;
|
|
|
|
|
break;
|
|
|
|
|
case '>':
|
|
|
|
|
os << "\\textgreater{}";
|
|
|
|
|
column += 13;
|
|
|
|
|
break;
|
|
|
|
|
case '|':
|
|
|
|
|
os << "\\textbar{}";
|
|
|
|
|
column += 9;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '-': // "--" in Typewriter mode -> "-{}-"
|
|
|
|
|
if (i <= size() - 2 &&
|
|
|
|
|
getChar(i + 1) == '-' &&
|
2007-04-29 18:17:15 +00:00
|
|
|
|
running_font.family() == Font::TYPEWRITER_FAMILY) {
|
2007-04-24 10:01:03 +00:00
|
|
|
|
os << "-{}";
|
|
|
|
|
column += 2;
|
|
|
|
|
} else {
|
|
|
|
|
os << '-';
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '\"':
|
|
|
|
|
os << "\\char`\\\"{}";
|
|
|
|
|
column += 9;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '$': case '&':
|
|
|
|
|
case '%': case '#': case '{':
|
|
|
|
|
case '}': case '_':
|
|
|
|
|
os << '\\';
|
|
|
|
|
os.put(c);
|
|
|
|
|
column += 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '~':
|
|
|
|
|
os << "\\textasciitilde{}";
|
|
|
|
|
column += 16;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '^':
|
|
|
|
|
os << "\\textasciicircum{}";
|
|
|
|
|
column += 17;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '*': case '[':
|
|
|
|
|
// avoid being mistaken for optional arguments
|
|
|
|
|
os << '{';
|
|
|
|
|
os.put(c);
|
|
|
|
|
os << '}';
|
|
|
|
|
column += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ' ':
|
|
|
|
|
// Blanks are printed before font switching.
|
|
|
|
|
// Sure? I am not! (try nice-latex)
|
|
|
|
|
// I am sure it's correct. LyX might be smarter
|
|
|
|
|
// in the future, but for now, nothing wrong is
|
|
|
|
|
// written. (Asger)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
|
|
// I assume this is hack treating typewriter as verbatim
|
|
|
|
|
// FIXME UNICODE: This can fail if c cannot be encoded
|
|
|
|
|
// in the current encoding.
|
2007-04-29 18:17:15 +00:00
|
|
|
|
if (running_font.family() == Font::TYPEWRITER_FAMILY) {
|
2007-04-24 10:01:03 +00:00
|
|
|
|
if (c != '\0') {
|
|
|
|
|
os.put(c);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// LyX, LaTeX etc.
|
|
|
|
|
|
|
|
|
|
// FIXME: if we have "LaTeX" with a font
|
|
|
|
|
// change in the middle (before the 'T', then
|
|
|
|
|
// the "TeX" part is still special cased.
|
|
|
|
|
// Really we should only operate this on
|
|
|
|
|
// "words" for some definition of word
|
|
|
|
|
|
|
|
|
|
size_t pnr = 0;
|
|
|
|
|
|
|
|
|
|
for (; pnr < phrases_nr; ++pnr) {
|
|
|
|
|
if (isTextAt(special_phrases[pnr].phrase, i)) {
|
|
|
|
|
os << special_phrases[pnr].macro;
|
|
|
|
|
i += special_phrases[pnr].phrase.length() - 1;
|
|
|
|
|
column += special_phrases[pnr].macro.length() - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pnr == phrases_nr && c != '\0') {
|
|
|
|
|
Encoding const & encoding = *(runparams.encoding);
|
|
|
|
|
if (i < size() - 1) {
|
|
|
|
|
char_type next = getChar(i + 1);
|
|
|
|
|
if (Encodings::isCombiningChar(next)) {
|
|
|
|
|
column += latexSurrogatePair(os, c, next, encoding) - 1;
|
|
|
|
|
++i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
docstring const latex = encoding.latexChar(c);
|
|
|
|
|
if (latex.length() > 1 &&
|
|
|
|
|
latex[latex.length() - 1] != '}') {
|
|
|
|
|
// Prevent eating of a following
|
|
|
|
|
// space or command corruption by
|
|
|
|
|
// following characters
|
|
|
|
|
column += latex.length() + 1;
|
|
|
|
|
os << latex << "{}";
|
|
|
|
|
} else {
|
|
|
|
|
column += latex.length() - 1;
|
|
|
|
|
os << latex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::Pimpl::validate(LaTeXFeatures & features,
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout const & layout) const
|
2007-04-24 10:01:03 +00:00
|
|
|
|
{
|
|
|
|
|
BufferParams const & bparams = features.bufferParams();
|
|
|
|
|
|
|
|
|
|
// check the params.
|
|
|
|
|
if (!params.spacing().isDefault())
|
|
|
|
|
features.require("setspace");
|
|
|
|
|
|
|
|
|
|
// then the layouts
|
|
|
|
|
features.useLayout(layout.name());
|
|
|
|
|
|
|
|
|
|
// then the fonts
|
|
|
|
|
Language const * doc_language = bparams.language;
|
|
|
|
|
|
|
|
|
|
FontList::const_iterator fcit = fontlist.begin();
|
|
|
|
|
FontList::const_iterator fend = fontlist.end();
|
|
|
|
|
for (; fcit != fend; ++fcit) {
|
2007-04-29 18:17:15 +00:00
|
|
|
|
if (fcit->font().noun() == Font::ON) {
|
2007-04-24 10:01:03 +00:00
|
|
|
|
LYXERR(Debug::LATEX) << "font.noun: "
|
|
|
|
|
<< fcit->font().noun()
|
|
|
|
|
<< endl;
|
|
|
|
|
features.require("noun");
|
|
|
|
|
LYXERR(Debug::LATEX) << "Noun enabled. Font: "
|
|
|
|
|
<< to_utf8(fcit->font().stateText(0))
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
switch (fcit->font().color()) {
|
2007-04-26 17:34:20 +00:00
|
|
|
|
case Color::none:
|
|
|
|
|
case Color::inherit:
|
|
|
|
|
case Color::ignore:
|
2007-04-24 10:01:03 +00:00
|
|
|
|
// probably we should put here all interface colors used for
|
|
|
|
|
// font displaying! For now I just add this ones I know of (Jug)
|
2007-04-26 17:34:20 +00:00
|
|
|
|
case Color::latex:
|
|
|
|
|
case Color::note:
|
2007-04-24 10:01:03 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
features.require("color");
|
|
|
|
|
LYXERR(Debug::LATEX) << "Color enabled. Font: "
|
|
|
|
|
<< to_utf8(fcit->font().stateText(0))
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Language const * language = fcit->font().language();
|
|
|
|
|
if (language->babel() != doc_language->babel() &&
|
|
|
|
|
language != ignore_language &&
|
|
|
|
|
language != latex_language)
|
|
|
|
|
{
|
|
|
|
|
features.useLanguage(language);
|
|
|
|
|
LYXERR(Debug::LATEX) << "Found language "
|
2007-05-06 20:26:02 +00:00
|
|
|
|
<< language->lang() << endl;
|
2007-04-24 10:01:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!params.leftIndent().zero())
|
|
|
|
|
features.require("ParagraphLeftIndent");
|
|
|
|
|
|
|
|
|
|
// then the insets
|
|
|
|
|
InsetList::const_iterator icit = owner_->insetlist.begin();
|
|
|
|
|
InsetList::const_iterator iend = owner_->insetlist.end();
|
|
|
|
|
for (; icit != iend; ++icit) {
|
|
|
|
|
if (icit->inset) {
|
|
|
|
|
icit->inset->validate(features);
|
|
|
|
|
if (layout.needprotect &&
|
2007-04-29 13:39:47 +00:00
|
|
|
|
icit->inset->lyxCode() == Inset::FOOT_CODE)
|
2007-04-24 10:01:03 +00:00
|
|
|
|
features.require("NeedLyXFootnoteCode");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// then the contents
|
|
|
|
|
for (pos_type i = 0; i < size() ; ++i) {
|
|
|
|
|
for (size_t pnr = 0; pnr < phrases_nr; ++pnr) {
|
|
|
|
|
if (!special_phrases[pnr].builtin
|
|
|
|
|
&& isTextAt(special_phrases[pnr].phrase, i)) {
|
|
|
|
|
features.require(special_phrases[pnr].phrase);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Encodings::validate(getChar(i), features);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace lyx
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Paragraph
|
|
|
|
|
//
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
namespace lyx {
|
2006-12-19 14:27:38 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
Paragraph::Paragraph()
|
2004-11-30 01:59:49 +00:00
|
|
|
|
: begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this))
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
itemdepth = 0;
|
2002-03-07 10:51:45 +00:00
|
|
|
|
params().clear();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-11-13 13:43:44 +00:00
|
|
|
|
Paragraph::Paragraph(Paragraph const & par)
|
2006-12-29 23:54:48 +00:00
|
|
|
|
: itemdepth(par.itemdepth), insetlist(par.insetlist),
|
2006-12-19 14:27:38 +00:00
|
|
|
|
layout_(par.layout_),
|
|
|
|
|
text_(par.text_), begin_of_body_(par.begin_of_body_),
|
|
|
|
|
pimpl_(new Paragraph::Pimpl(*par.pimpl_, this))
|
2001-05-08 10:50:09 +00:00
|
|
|
|
{
|
2004-03-19 16:36:52 +00:00
|
|
|
|
//lyxerr << "Paragraph::Paragraph(Paragraph const&)" << endl;
|
2002-08-14 22:15:18 +00:00
|
|
|
|
InsetList::iterator it = insetlist.begin();
|
|
|
|
|
InsetList::iterator end = insetlist.end();
|
2004-01-26 10:13:15 +00:00
|
|
|
|
for (; it != end; ++it)
|
|
|
|
|
it->inset = it->inset->clone().release();
|
2001-05-08 10:50:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-03-19 16:36:52 +00:00
|
|
|
|
Paragraph & Paragraph::operator=(Paragraph const & par)
|
2003-06-04 07:14:05 +00:00
|
|
|
|
{
|
|
|
|
|
// needed as we will destroy the pimpl_ before copying it
|
2004-03-19 16:36:52 +00:00
|
|
|
|
if (&par != this) {
|
|
|
|
|
itemdepth = par.itemdepth;
|
|
|
|
|
|
|
|
|
|
insetlist = par.insetlist;
|
|
|
|
|
InsetList::iterator it = insetlist.begin();
|
|
|
|
|
InsetList::iterator end = insetlist.end();
|
|
|
|
|
for (; it != end; ++it)
|
|
|
|
|
it->inset = it->inset->clone().release();
|
|
|
|
|
|
|
|
|
|
layout_ = par.layout();
|
|
|
|
|
text_ = par.text_;
|
|
|
|
|
begin_of_body_ = par.begin_of_body_;
|
|
|
|
|
|
|
|
|
|
delete pimpl_;
|
|
|
|
|
pimpl_ = new Pimpl(*par.pimpl_, this);
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
2003-06-04 07:14:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-11-13 13:43:44 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
Paragraph::~Paragraph()
|
2001-05-08 10:50:09 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
delete pimpl_;
|
2001-05-08 10:50:09 +00:00
|
|
|
|
//
|
2001-06-25 00:06:33 +00:00
|
|
|
|
//lyxerr << "Paragraph::paragraph_id = "
|
|
|
|
|
// << Paragraph::paragraph_id << endl;
|
2001-05-08 10:50:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-08-28 07:41:31 +00:00
|
|
|
|
void Paragraph::write(Buffer const & buf, ostream & os,
|
2002-03-21 17:27:08 +00:00
|
|
|
|
BufferParams const & bparams,
|
2002-08-26 09:31:09 +00:00
|
|
|
|
depth_type & dth) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-05-08 13:28:44 +00:00
|
|
|
|
// The beginning or end of a deeper (i.e. nested) area?
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (dth != params().depth()) {
|
|
|
|
|
if (params().depth() > dth) {
|
|
|
|
|
while (params().depth() > dth) {
|
2004-08-16 11:27:51 +00:00
|
|
|
|
os << "\n\\begin_deeper";
|
2001-05-08 13:28:44 +00:00
|
|
|
|
++dth;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2001-05-08 13:28:44 +00:00
|
|
|
|
} else {
|
2001-06-25 00:06:33 +00:00
|
|
|
|
while (params().depth() < dth) {
|
2004-08-16 11:27:51 +00:00
|
|
|
|
os << "\n\\end_deeper";
|
2001-05-08 13:28:44 +00:00
|
|
|
|
--dth;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-05-08 13:28:44 +00:00
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2001-05-08 13:28:44 +00:00
|
|
|
|
// First write the layout
|
2007-07-11 13:39:08 +00:00
|
|
|
|
os << "\n\\begin_layout " << to_utf8(layout()->name()) << '\n';
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2003-03-12 06:53:49 +00:00
|
|
|
|
params().write(os);
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font1(Font::ALL_INHERIT, bparams.language);
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
|
Change running_change = Change(Change::UNCHANGED);
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2000-07-15 23:51:46 +00:00
|
|
|
|
int column = 0;
|
2006-03-11 13:31:41 +00:00
|
|
|
|
for (pos_type i = 0; i <= size(); ++i) {
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2006-05-08 20:30:52 +00:00
|
|
|
|
Change change = pimpl_->lookupChange(i);
|
2006-10-26 19:00:28 +00:00
|
|
|
|
Changes::lyxMarkChange(os, column, running_change, change);
|
2003-02-08 19:18:01 +00:00
|
|
|
|
running_change = change;
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2006-03-11 13:31:41 +00:00
|
|
|
|
if (i == size())
|
|
|
|
|
break;
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Write font changes
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font2 = getFontSettings(bparams, i);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (font2 != font1) {
|
2001-08-11 18:31:14 +00:00
|
|
|
|
font2.lyxWriteChanges(font1, os);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
column = 0;
|
|
|
|
|
font1 = font2;
|
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
value_type const c = getChar(i);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
switch (c) {
|
1999-11-15 12:01:38 +00:00
|
|
|
|
case META_INSET:
|
2000-02-22 00:36:17 +00:00
|
|
|
|
{
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset const * inset = getInset(i);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (inset)
|
2001-06-28 10:25:20 +00:00
|
|
|
|
if (inset->directWrite()) {
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// international char, let it write
|
|
|
|
|
// code directly so it's shorter in
|
|
|
|
|
// the file
|
2001-06-28 10:25:20 +00:00
|
|
|
|
inset->write(buf, os);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else {
|
2005-01-06 16:52:08 +00:00
|
|
|
|
if (i)
|
|
|
|
|
os << '\n';
|
|
|
|
|
os << "\\begin_inset ";
|
2001-06-28 10:25:20 +00:00
|
|
|
|
inset->write(buf, os);
|
2004-08-16 11:27:51 +00:00
|
|
|
|
os << "\n\\end_inset\n\n";
|
1999-09-27 18:44:28 +00:00
|
|
|
|
column = 0;
|
|
|
|
|
}
|
2000-02-22 00:36:17 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
1999-12-07 00:44:53 +00:00
|
|
|
|
case '\\':
|
2004-08-16 11:27:51 +00:00
|
|
|
|
os << "\n\\backslash\n";
|
1999-09-27 18:44:28 +00:00
|
|
|
|
column = 0;
|
|
|
|
|
break;
|
|
|
|
|
case '.':
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (i + 1 < size() && getChar(i + 1) == ' ') {
|
1999-12-07 00:44:53 +00:00
|
|
|
|
os << ".\n";
|
1999-11-04 01:40:20 +00:00
|
|
|
|
column = 0;
|
|
|
|
|
} else
|
2002-11-27 10:30:28 +00:00
|
|
|
|
os << '.';
|
1999-09-27 18:44:28 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
1999-11-15 12:01:38 +00:00
|
|
|
|
if ((column > 70 && c == ' ')
|
2000-02-29 02:19:17 +00:00
|
|
|
|
|| column > 79) {
|
2002-11-27 10:30:28 +00:00
|
|
|
|
os << '\n';
|
1999-09-27 18:44:28 +00:00
|
|
|
|
column = 0;
|
|
|
|
|
}
|
|
|
|
|
// this check is to amend a bug. LyX sometimes
|
|
|
|
|
// inserts '\0' this could cause problems.
|
2006-08-13 22:54:59 +00:00
|
|
|
|
if (c != '\0') {
|
|
|
|
|
std::vector<char> tmp = ucs4_to_utf8(c);
|
|
|
|
|
tmp.push_back('\0');
|
|
|
|
|
os << &tmp[0];
|
|
|
|
|
} else
|
2001-06-25 00:06:33 +00:00
|
|
|
|
lyxerr << "ERROR (Paragraph::writeFile):"
|
1999-10-07 18:44:17 +00:00
|
|
|
|
" NULL char in structure." << endl;
|
2000-01-24 18:34:46 +00:00
|
|
|
|
++column;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-02-08 19:18:01 +00:00
|
|
|
|
|
2003-07-27 21:39:54 +00:00
|
|
|
|
os << "\n\\end_layout\n";
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
void Paragraph::validate(LaTeXFeatures & features) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2002-07-20 16:42:15 +00:00
|
|
|
|
pimpl_->validate(features, *layout());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-21 17:05:20 +00:00
|
|
|
|
bool Paragraph::eraseChar(pos_type pos, bool trackChanges)
|
2003-03-04 19:52:35 +00:00
|
|
|
|
{
|
2006-10-21 17:05:20 +00:00
|
|
|
|
return pimpl_->eraseChar(pos, trackChanges);
|
2003-03-04 19:52:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-22 14:36:08 +00:00
|
|
|
|
int Paragraph::eraseChars(pos_type start, pos_type end, bool trackChanges)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2006-10-22 14:36:08 +00:00
|
|
|
|
return pimpl_->eraseChars(start, end, trackChanges);
|
2003-02-08 19:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2006-10-22 10:15:23 +00:00
|
|
|
|
void Paragraph::insert(pos_type start, docstring const & str,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Font const & font, Change const & change)
|
2003-11-04 12:01:15 +00:00
|
|
|
|
{
|
2005-07-16 12:02:31 +00:00
|
|
|
|
for (size_t i = 0, n = str.size(); i != n ; ++i)
|
2006-10-20 11:44:58 +00:00
|
|
|
|
insertChar(start + i, str[i], font, change);
|
2003-11-04 12:01:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-08-13 20:26:26 +00:00
|
|
|
|
void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
bool trackChanges)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2006-10-20 11:44:58 +00:00
|
|
|
|
pimpl_->insertChar(pos, c, Change(trackChanges ?
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Change::INSERTED : Change::UNCHANGED));
|
2006-10-20 11:44:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Font const & font, bool trackChanges)
|
2006-10-20 11:44:58 +00:00
|
|
|
|
{
|
|
|
|
|
pimpl_->insertChar(pos, c, Change(trackChanges ?
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Change::INSERTED : Change::UNCHANGED));
|
2006-10-20 11:44:58 +00:00
|
|
|
|
setFont(pos, font);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
|
2001-11-26 16:42:04 +00:00
|
|
|
|
void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Font const & font, Change const & change)
|
2000-06-28 13:35:52 +00:00
|
|
|
|
{
|
2004-08-05 15:14:29 +00:00
|
|
|
|
pimpl_->insertChar(pos, c, change);
|
|
|
|
|
setFont(pos, font);
|
2000-06-28 13:35:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
void Paragraph::insertInset(pos_type pos, Inset * inset,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Change const & change)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2004-08-05 15:14:29 +00:00
|
|
|
|
pimpl_->insertInset(pos, inset, change);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
void Paragraph::insertInset(pos_type pos, Inset * inset,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
Font const & font, Change const & change)
|
2000-06-28 13:35:52 +00:00
|
|
|
|
{
|
2004-08-05 15:14:29 +00:00
|
|
|
|
pimpl_->insertInset(pos, inset, change);
|
2007-07-05 17:47:25 +00:00
|
|
|
|
// Set the font/language of the inset...
|
2004-08-05 15:14:29 +00:00
|
|
|
|
setFont(pos, font);
|
2007-07-05 17:47:25 +00:00
|
|
|
|
// ... as well as the font/language of the text inside the inset
|
|
|
|
|
// FIXME: This is far from perfect. It basically overrides work being done
|
|
|
|
|
// in the InsetText constructor. Also, it doesn't work for Tables
|
|
|
|
|
// (precisely because each cell's font/language is set in the Table's
|
|
|
|
|
// constructor, so by now it's too late). The long-term solution should
|
|
|
|
|
// be moving current_font into Cursor, and getting rid of all this...
|
|
|
|
|
// (see http://thread.gmane.org/gmane.editors.lyx.devel/88869/focus=88944)
|
|
|
|
|
if (inset->asTextInset()) {
|
|
|
|
|
inset->asTextInset()->text_.current_font = font;
|
|
|
|
|
inset->asTextInset()->text_.real_current_font = font;
|
|
|
|
|
}
|
2000-06-28 13:35:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
bool Paragraph::insetAllowed(Inset_code code)
|
2000-04-10 14:29:05 +00:00
|
|
|
|
{
|
2004-04-13 06:27:29 +00:00
|
|
|
|
return !pimpl_->inset_owner || pimpl_->inset_owner->insetAllowed(code);
|
2000-04-10 14:29:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-05-18 13:26:04 +00:00
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Gets uninstantiated font setting at position.
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const Paragraph::getFontSettings(BufferParams const & bparams,
|
2002-03-21 17:27:08 +00:00
|
|
|
|
pos_type pos) const
|
2001-04-04 21:47:26 +00:00
|
|
|
|
{
|
2004-02-20 11:00:41 +00:00
|
|
|
|
if (pos > size()) {
|
|
|
|
|
lyxerr << " pos: " << pos << " size: " << size() << endl;
|
|
|
|
|
BOOST_ASSERT(pos <= size());
|
|
|
|
|
}
|
2002-03-13 18:23:38 +00:00
|
|
|
|
|
|
|
|
|
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
|
|
|
|
|
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
|
2003-07-28 12:51:24 +00:00
|
|
|
|
for (; cit != end; ++cit)
|
2002-03-13 23:13:35 +00:00
|
|
|
|
if (cit->pos() >= pos)
|
2002-03-13 18:23:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2003-03-11 15:01:29 +00:00
|
|
|
|
if (cit != end)
|
2003-07-28 12:51:24 +00:00
|
|
|
|
return cit->font();
|
2001-07-27 12:03:36 +00:00
|
|
|
|
|
2003-07-28 12:51:24 +00:00
|
|
|
|
if (pos == size() && !empty())
|
|
|
|
|
return getFontSettings(bparams, pos - 1);
|
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
return Font(Font::ALL_INHERIT, getParLanguage(bparams));
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-28 12:51:24 +00:00
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
FontSpan Paragraph::fontSpan(pos_type pos) const
|
2003-07-27 10:42:11 +00:00
|
|
|
|
{
|
2003-09-09 17:25:35 +00:00
|
|
|
|
BOOST_ASSERT(pos <= size());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
pos_type start = 0;
|
2003-07-27 10:42:11 +00:00
|
|
|
|
|
|
|
|
|
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
|
|
|
|
|
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
|
2005-06-10 14:55:01 +00:00
|
|
|
|
for (; cit != end; ++cit) {
|
2005-11-07 11:28:11 +00:00
|
|
|
|
if (cit->pos() >= pos) {
|
|
|
|
|
if (pos >= beginOfBody())
|
|
|
|
|
return FontSpan(std::max(start, beginOfBody()),
|
|
|
|
|
cit->pos());
|
|
|
|
|
else
|
2006-04-05 23:56:29 +00:00
|
|
|
|
return FontSpan(start,
|
|
|
|
|
std::min(beginOfBody() - 1,
|
2005-11-07 11:28:11 +00:00
|
|
|
|
cit->pos()));
|
|
|
|
|
}
|
2005-06-10 14:55:01 +00:00
|
|
|
|
start = cit->pos() + 1;
|
|
|
|
|
}
|
2003-07-28 12:51:24 +00:00
|
|
|
|
|
2003-07-27 10:42:11 +00:00
|
|
|
|
// This should not happen, but if so, we take no chances.
|
2003-08-07 11:59:09 +00:00
|
|
|
|
//lyxerr << "Paragraph::getEndPosOfFontSpan: This should not happen!"
|
|
|
|
|
// << endl;
|
2005-07-18 12:13:32 +00:00
|
|
|
|
return FontSpan(pos, pos);
|
2003-07-27 10:42:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-12-29 12:48:02 +00:00
|
|
|
|
|
2000-03-17 10:14:46 +00:00
|
|
|
|
// Gets uninstantiated font setting at position 0
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const Paragraph::getFirstFontSettings(BufferParams const & bparams) const
|
2000-03-17 10:14:46 +00:00
|
|
|
|
{
|
2002-08-10 15:21:07 +00:00
|
|
|
|
if (!empty() && !pimpl_->fontlist.empty())
|
2001-11-27 10:34:16 +00:00
|
|
|
|
return pimpl_->fontlist[0].font();
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
return Font(Font::ALL_INHERIT, bparams.language);
|
2000-03-17 10:14:46 +00:00
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2000-06-08 23:16:16 +00:00
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Gets the fully instantiated font at a given position in a paragraph
|
2007-04-29 23:33:02 +00:00
|
|
|
|
// This is basically the same function as Text::GetFont() in text2.cpp.
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// The difference is that this one is used for generating the LaTeX file,
|
|
|
|
|
// and thus cosmetic "improvements" are disallowed: This has to deliver
|
|
|
|
|
// the true picture of the buffer. (Asger)
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const Paragraph::getFont(BufferParams const & bparams, pos_type pos,
|
|
|
|
|
Font const & outerfont) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2003-09-09 17:25:35 +00:00
|
|
|
|
BOOST_ASSERT(pos >= 0);
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout_ptr const & lout = layout();
|
2002-06-24 20:28:12 +00:00
|
|
|
|
|
2003-11-13 13:43:44 +00:00
|
|
|
|
pos_type const body_pos = beginOfBody();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font layoutfont;
|
2003-03-09 12:37:22 +00:00
|
|
|
|
if (pos < body_pos)
|
2002-06-24 20:28:12 +00:00
|
|
|
|
layoutfont = lout->labelfont;
|
2001-08-03 18:28:11 +00:00
|
|
|
|
else
|
2002-06-24 20:28:12 +00:00
|
|
|
|
layoutfont = lout->font;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font = getFontSettings(bparams, pos);
|
2003-10-21 16:15:14 +00:00
|
|
|
|
font.realize(layoutfont);
|
|
|
|
|
font.realize(outerfont);
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
|
font.realize(bparams.getFont());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2003-10-21 16:15:14 +00:00
|
|
|
|
return font;
|
2001-08-03 18:28:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const Paragraph::getLabelFont
|
|
|
|
|
(BufferParams const & bparams, Font const & outerfont) const
|
2001-08-03 18:28:11 +00:00
|
|
|
|
{
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font tmpfont = layout()->labelfont;
|
2001-08-03 18:28:11 +00:00
|
|
|
|
tmpfont.setLanguage(getParLanguage(bparams));
|
2003-04-15 00:49:11 +00:00
|
|
|
|
tmpfont.realize(outerfont);
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
|
tmpfont.realize(bparams.getFont());
|
2003-07-27 21:59:06 +00:00
|
|
|
|
return tmpfont;
|
2001-08-03 18:28:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const Paragraph::getLayoutFont
|
|
|
|
|
(BufferParams const & bparams, Font const & outerfont) const
|
2001-08-03 18:28:11 +00:00
|
|
|
|
{
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font tmpfont = layout()->font;
|
2001-08-03 18:28:11 +00:00
|
|
|
|
tmpfont.setLanguage(getParLanguage(bparams));
|
2003-04-15 00:49:11 +00:00
|
|
|
|
tmpfont.realize(outerfont);
|
The Grand Font Selection Redesign:
* lib/lyx2lyx/LyX.py (format_relation): add file format 247 (from Georg BAUM).
* lib/lyx2lyx/lyx_1_5.py: add convert_font_settings, revert_font_settings (from Georg BAUM).
* lib/chkconfig.ltx: Test for newly supported font packages
* lib/doc/LaTeXConfig.lyx.in: document newly supported font packages
* lib/doc/UserGuide.lyx: document new UI.
* lib/doc/Extended.lyx: update PostScript font documentation
* development/FORMAT: document file format change 246->247.
* src/tex-strings.[Ch]: new strings tex_fonts_roman, tex_fonts_sans,
tex_fonts_monospaced (with GUI equivalents).
* src/buffer.C: Format up to 247.
* src/bufferparams.C:
new params fontsRoman, fontsSans, fontsTypewriter, fontsDefaultFamily,
fontsSC, fontsOSF, fontsSansScale and fontsTypewriterScale
(LyXFont const BufferParams::getFont): consider switch of default family.
(string const BufferParams::loadFonts): new method to get all the LaTeX
font stuff done.
* src/paragraph.C
(LyXFont const Paragraph::getFont):
(LyXFont const Paragraph::getLabelFont):
(LyXFont const Paragraph::getLayoutFont): user buffer's not textclass's
default font
* src/text.C
(int LyXText::leftMargin):
(int LyXText::rightMargin): user buffer's not textclass's default font
* src/text2.C
(LyXFont LyXText::getFont):
(LyXFont LyXText::getLayoutFont):
(LyXFont LyXText::getLabelFont): check if the family of the default document
font has been customized.
* src/frontends/gtk/GDocument.[Ch]: implement new font ui (from Georg BAUM).
* src/frontends/gtk/glade/document.glade: implement new font ui (from Georg BAUM).
* src/frontends/qt3/Makefile.dialogs: add new FontModuleBase
* src/frontends/qt3/ui/FontModuleBase.ui: new File
* src/frontends/qt3/ui/TextLayoutModuleBase.ui: remove font widgets
* src/frontends/qt3/QDocument.C
* src/frontends/qt3/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/Makefile.dialogs: add new FontUi
* src/frontends/qt4/QDocumentDialog.[Ch]: implement new font ui
* src/frontends/qt4/ui/FontUi.ui: new File
* src/frontends/qt4/ui/TextLayoutUi.ui: remove font widgets
* src/frontends/qt4/ui/compile_uic.sh: add new FontUi
* src/frontends/xforms/FormDocument.[Ch]: implement new font ui
* src/frontends/xforms/forms/form_document.fd: add new font tab.
* src/frontends/controllers/ControlDocument.[Ch]
(char ControlDocument::fontfamilies):
(char ControlDocument::fontfamilies_gui):
(bool ControlDocument::isFontAvailable):
(bool ControlDocument::providesSC):
(bool ControlDocument::providesOSF):
(bool ControlDocument::providesScale): new methods, providing font info.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14143 a592a061-630c-0410-9148-cb99ea01b6c8
2006-06-19 08:10:17 +00:00
|
|
|
|
tmpfont.realize(bparams.getFont());
|
2003-07-27 21:59:06 +00:00
|
|
|
|
return tmpfont;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns the height of the highest font in range
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font_size Paragraph::highestFontInRange
|
|
|
|
|
(pos_type startpos, pos_type endpos, Font_size def_size) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (pimpl_->fontlist.empty())
|
2001-07-31 12:57:06 +00:00
|
|
|
|
return def_size;
|
2000-07-15 23:51:46 +00:00
|
|
|
|
|
2002-03-13 18:23:38 +00:00
|
|
|
|
Pimpl::FontList::const_iterator end_it = pimpl_->fontlist.begin();
|
2003-10-27 11:44:10 +00:00
|
|
|
|
Pimpl::FontList::const_iterator const end = pimpl_->fontlist.end();
|
2002-03-13 18:23:38 +00:00
|
|
|
|
for (; end_it != end; ++end_it) {
|
2002-03-13 23:13:35 +00:00
|
|
|
|
if (end_it->pos() >= endpos)
|
2002-03-13 18:23:38 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end_it != end)
|
2000-06-20 12:49:14 +00:00
|
|
|
|
++end_it;
|
|
|
|
|
|
2002-03-13 18:23:38 +00:00
|
|
|
|
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
|
|
|
|
|
for (; cit != end; ++cit) {
|
2002-03-13 23:13:35 +00:00
|
|
|
|
if (cit->pos() >= startpos)
|
2002-03-13 18:23:38 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font::FONT_SIZE maxsize = Font::SIZE_TINY;
|
2001-08-03 18:28:11 +00:00
|
|
|
|
for (; cit != end_it; ++cit) {
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font::FONT_SIZE size = cit->font().size();
|
|
|
|
|
if (size == Font::INHERIT_SIZE)
|
2001-07-31 12:57:06 +00:00
|
|
|
|
size = def_size;
|
2007-04-29 18:17:15 +00:00
|
|
|
|
if (size > maxsize && size <= Font::SIZE_HUGER)
|
2000-06-20 12:49:14 +00:00
|
|
|
|
maxsize = size;
|
1999-11-04 01:40:20 +00:00
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
return maxsize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
Paragraph::value_type
|
2001-12-18 15:29:54 +00:00
|
|
|
|
Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const
|
2001-02-11 09:58:20 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
value_type c = getChar(pos);
|
2001-02-11 09:58:20 +00:00
|
|
|
|
if (!lyxrc.rtl_support)
|
|
|
|
|
return c;
|
|
|
|
|
|
|
|
|
|
value_type uc = c;
|
|
|
|
|
switch (c) {
|
|
|
|
|
case '(':
|
|
|
|
|
uc = ')';
|
|
|
|
|
break;
|
|
|
|
|
case ')':
|
|
|
|
|
uc = '(';
|
|
|
|
|
break;
|
|
|
|
|
case '[':
|
|
|
|
|
uc = ']';
|
|
|
|
|
break;
|
|
|
|
|
case ']':
|
|
|
|
|
uc = '[';
|
|
|
|
|
break;
|
|
|
|
|
case '{':
|
|
|
|
|
uc = '}';
|
|
|
|
|
break;
|
|
|
|
|
case '}':
|
|
|
|
|
uc = '{';
|
|
|
|
|
break;
|
|
|
|
|
case '<':
|
|
|
|
|
uc = '>';
|
|
|
|
|
break;
|
|
|
|
|
case '>':
|
|
|
|
|
uc = '<';
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (uc != c && getFontSettings(bparams, pos).isRightToLeft())
|
2001-02-11 09:58:20 +00:00
|
|
|
|
return uc;
|
|
|
|
|
else
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-04 21:47:26 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
void Paragraph::setFont(pos_type pos, Font const & font)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2003-09-09 17:25:35 +00:00
|
|
|
|
BOOST_ASSERT(pos <= size());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// First, reduce font against layout/label font
|
2007-04-26 04:41:58 +00:00
|
|
|
|
// Update: The setCharFont() routine in text2.cpp already
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// reduces font, so we don't need to do that here. (Asger)
|
|
|
|
|
// No need to simplify this because it will disappear
|
|
|
|
|
// in a new kernel. (Asger)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Next search font table
|
2000-01-11 01:59:00 +00:00
|
|
|
|
|
2002-03-13 18:23:38 +00:00
|
|
|
|
Pimpl::FontList::iterator beg = pimpl_->fontlist.begin();
|
|
|
|
|
Pimpl::FontList::iterator it = beg;
|
|
|
|
|
Pimpl::FontList::iterator endit = pimpl_->fontlist.end();
|
|
|
|
|
for (; it != endit; ++it) {
|
2002-03-13 23:13:35 +00:00
|
|
|
|
if (it->pos() >= pos)
|
2002-03-13 18:23:38 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2005-07-15 22:10:25 +00:00
|
|
|
|
size_t const i = distance(beg, it);
|
2002-03-13 18:23:38 +00:00
|
|
|
|
bool notfound = (it == endit);
|
2000-06-20 12:49:14 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (!notfound && pimpl_->fontlist[i].font() == font)
|
2000-06-20 12:49:14 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool begin = pos == 0 || notfound ||
|
2002-03-13 18:23:38 +00:00
|
|
|
|
(i > 0 && pimpl_->fontlist[i - 1].pos() == pos - 1);
|
2000-06-20 12:49:14 +00:00
|
|
|
|
// Is position pos is a beginning of a font block?
|
2001-06-25 00:06:33 +00:00
|
|
|
|
bool end = !notfound && pimpl_->fontlist[i].pos() == pos;
|
2000-06-20 12:49:14 +00:00
|
|
|
|
// Is position pos is the end of a font block?
|
|
|
|
|
if (begin && end) { // A single char block
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (i + 1 < pimpl_->fontlist.size() &&
|
|
|
|
|
pimpl_->fontlist[i + 1].font() == font) {
|
2000-06-20 12:49:14 +00:00
|
|
|
|
// Merge the singleton block with the next block
|
2001-06-25 00:06:33 +00:00
|
|
|
|
pimpl_->fontlist.erase(pimpl_->fontlist.begin() + i);
|
|
|
|
|
if (i > 0 && pimpl_->fontlist[i - 1].font() == font)
|
2002-08-11 16:27:10 +00:00
|
|
|
|
pimpl_->fontlist.erase(pimpl_->fontlist.begin() + i - 1);
|
2001-06-25 00:06:33 +00:00
|
|
|
|
} else if (i > 0 && pimpl_->fontlist[i - 1].font() == font) {
|
2000-06-20 12:49:14 +00:00
|
|
|
|
// Merge the singleton block with the previous block
|
2001-06-25 00:06:33 +00:00
|
|
|
|
pimpl_->fontlist[i - 1].pos(pos);
|
|
|
|
|
pimpl_->fontlist.erase(pimpl_->fontlist.begin() + i);
|
2000-06-20 12:49:14 +00:00
|
|
|
|
} else
|
2001-06-25 00:06:33 +00:00
|
|
|
|
pimpl_->fontlist[i].font(font);
|
2000-06-20 12:49:14 +00:00
|
|
|
|
} else if (begin) {
|
2001-06-25 00:06:33 +00:00
|
|
|
|
if (i > 0 && pimpl_->fontlist[i - 1].font() == font)
|
|
|
|
|
pimpl_->fontlist[i - 1].pos(pos);
|
2000-06-20 12:49:14 +00:00
|
|
|
|
else
|
2001-06-25 00:06:33 +00:00
|
|
|
|
pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i,
|
|
|
|
|
Pimpl::FontTable(pos, font));
|
2000-06-20 12:49:14 +00:00
|
|
|
|
} else if (end) {
|
2001-06-25 00:06:33 +00:00
|
|
|
|
pimpl_->fontlist[i].pos(pos - 1);
|
|
|
|
|
if (!(i + 1 < pimpl_->fontlist.size() &&
|
|
|
|
|
pimpl_->fontlist[i + 1].font() == font))
|
|
|
|
|
pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i + 1,
|
|
|
|
|
Pimpl::FontTable(pos, font));
|
2000-06-20 12:49:14 +00:00
|
|
|
|
} else { // The general case. The block is splitted into 3 blocks
|
2002-03-21 17:27:08 +00:00
|
|
|
|
pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i,
|
2001-06-25 00:06:33 +00:00
|
|
|
|
Pimpl::FontTable(pos - 1, pimpl_->fontlist[i].font()));
|
|
|
|
|
pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i + 1,
|
|
|
|
|
Pimpl::FontTable(pos, font));
|
1999-11-04 01:40:20 +00:00
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-09 00:56:42 +00:00
|
|
|
|
|
2003-04-29 10:56:15 +00:00
|
|
|
|
void Paragraph::makeSameLayout(Paragraph const & par)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2003-04-29 10:56:15 +00:00
|
|
|
|
layout(par.layout());
|
2001-06-29 09:58:56 +00:00
|
|
|
|
// move to pimpl?
|
2003-04-29 10:56:15 +00:00
|
|
|
|
params() = par.params();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-01-21 21:11:27 +00:00
|
|
|
|
bool Paragraph::stripLeadingSpaces(bool trackChanges)
|
2000-05-26 16:13:01 +00:00
|
|
|
|
{
|
2003-06-07 17:45:43 +00:00
|
|
|
|
if (isFreeSpacing())
|
2007-02-20 08:34:04 +00:00
|
|
|
|
return false;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-01-14 18:27:27 +00:00
|
|
|
|
int pos = 0;
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
|
|
while (pos < size() && (isNewline(pos) || isLineSeparator(pos))) {
|
|
|
|
|
if (eraseChar(pos, trackChanges))
|
|
|
|
|
++count;
|
|
|
|
|
else
|
|
|
|
|
++pos;
|
2000-05-26 16:13:01 +00:00
|
|
|
|
}
|
2001-04-27 07:19:08 +00:00
|
|
|
|
|
2007-02-20 08:34:04 +00:00
|
|
|
|
return count > 0 || pos > 0;
|
2000-05-26 16:13:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2003-04-29 10:56:15 +00:00
|
|
|
|
bool Paragraph::hasSameLayout(Paragraph const & par) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2003-12-01 13:35:49 +00:00
|
|
|
|
return par.layout() == layout() && params().sameLayout(par.params());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
depth_type Paragraph::getDepth() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
return params().depth();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
depth_type Paragraph::getMaxDepthAfter() const
|
2002-02-28 15:07:11 +00:00
|
|
|
|
{
|
2003-03-11 16:38:37 +00:00
|
|
|
|
if (layout()->isEnvironment())
|
2002-02-28 15:07:11 +00:00
|
|
|
|
return params().depth() + 1;
|
|
|
|
|
else
|
|
|
|
|
return params().depth();
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-11 16:38:37 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
char Paragraph::getAlign() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2006-12-17 10:11:28 +00:00
|
|
|
|
if (params().align() == LYX_ALIGN_LAYOUT)
|
|
|
|
|
return layout()->align;
|
|
|
|
|
else
|
|
|
|
|
return params().align();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-20 19:26:23 +00:00
|
|
|
|
docstring const & Paragraph::getLabelstring() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
return params().labelString();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// the next two functions are for the manual labels
|
2006-10-20 19:26:23 +00:00
|
|
|
|
docstring const Paragraph::getLabelWidthString() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-09-10 13:44:49 +00:00
|
|
|
|
if (layout()->margintype == MARGIN_MANUAL)
|
2001-06-25 00:06:33 +00:00
|
|
|
|
return params().labelWidthString();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
else
|
2006-10-20 19:26:23 +00:00
|
|
|
|
return _("Senseless with this layout!");
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-20 19:26:23 +00:00
|
|
|
|
void Paragraph::setLabelWidthString(docstring const & s)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
params().labelWidthString(s);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-01-15 16:58:14 +00:00
|
|
|
|
docstring const Paragraph::translateIfPossible(docstring const & s,
|
|
|
|
|
BufferParams const & bparams) const
|
|
|
|
|
{
|
|
|
|
|
if (!support::isAscii(s) || s.empty()) {
|
|
|
|
|
// This must be a user defined layout. We cannot translate
|
|
|
|
|
// this, since gettext accepts only ascii keys.
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
// Probably standard layout, try to translate
|
|
|
|
|
Messages & m = getMessages(getParLanguage(bparams)->code());
|
|
|
|
|
return m.get(to_ascii(s));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
docstring Paragraph::expandLabel(Layout_ptr const & layout,
|
2007-01-15 16:58:14 +00:00
|
|
|
|
BufferParams const & bparams, bool process_appendix) const
|
|
|
|
|
{
|
2007-04-29 19:53:54 +00:00
|
|
|
|
TextClass const & tclass = bparams.getTextClass();
|
2007-01-15 16:58:14 +00:00
|
|
|
|
|
|
|
|
|
docstring fmt;
|
|
|
|
|
if (process_appendix && params().appendix())
|
|
|
|
|
fmt = translateIfPossible(layout->labelstring_appendix(),
|
|
|
|
|
bparams);
|
|
|
|
|
else
|
|
|
|
|
fmt = translateIfPossible(layout->labelstring(), bparams);
|
|
|
|
|
|
|
|
|
|
// handle 'inherited level parts' in 'fmt',
|
|
|
|
|
// i.e. the stuff between '@' in '@Section@.\arabic{subsection}'
|
|
|
|
|
size_t const i = fmt.find('@', 0);
|
|
|
|
|
if (i != docstring::npos) {
|
|
|
|
|
size_t const j = fmt.find('@', i + 1);
|
|
|
|
|
if (j != docstring::npos) {
|
|
|
|
|
docstring parent(fmt, i + 1, j - i - 1);
|
2007-07-11 13:39:08 +00:00
|
|
|
|
docstring label = expandLabel(tclass[parent], bparams);
|
2007-01-15 16:58:14 +00:00
|
|
|
|
fmt = docstring(fmt, 0, i) + label + docstring(fmt, j + 1, docstring::npos);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tclass.counters().counterLabel(fmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
void Paragraph::applyLayout(Layout_ptr const & new_layout)
|
2001-04-04 21:47:26 +00:00
|
|
|
|
{
|
2002-03-02 16:39:54 +00:00
|
|
|
|
layout(new_layout);
|
2007-07-11 16:39:26 +00:00
|
|
|
|
LyXAlignment const oldAlign = params().align();
|
2007-08-26 19:55:46 +00:00
|
|
|
|
|
|
|
|
|
if (!(oldAlign & layout()->alignpossible)) {
|
2007-07-11 16:39:26 +00:00
|
|
|
|
frontend::Alert::warning(_("Alignment not permitted"),
|
|
|
|
|
_("The new layout does not permit the alignment previously used.\nSetting to default."));
|
|
|
|
|
params().align(LYX_ALIGN_LAYOUT);
|
|
|
|
|
}
|
2001-04-04 21:47:26 +00:00
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
|
2004-03-24 17:06:17 +00:00
|
|
|
|
pos_type Paragraph::beginOfBody() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2003-11-13 13:43:44 +00:00
|
|
|
|
return begin_of_body_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Paragraph::setBeginOfBody()
|
|
|
|
|
{
|
|
|
|
|
if (layout()->labeltype != LABEL_MANUAL) {
|
|
|
|
|
begin_of_body_ = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2003-02-14 00:41:44 +00:00
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
// Unroll the first two cycles of the loop
|
|
|
|
|
// and remember the previous character to
|
2003-10-17 10:31:47 +00:00
|
|
|
|
// remove unnecessary getChar() calls
|
2001-11-26 16:42:04 +00:00
|
|
|
|
pos_type i = 0;
|
2003-11-13 13:43:44 +00:00
|
|
|
|
pos_type end = size();
|
|
|
|
|
if (i < end && !isNewline(i)) {
|
1999-11-04 01:40:20 +00:00
|
|
|
|
++i;
|
2006-10-22 10:15:23 +00:00
|
|
|
|
char_type previous_char = 0;
|
|
|
|
|
char_type temp = 0;
|
2003-11-13 13:43:44 +00:00
|
|
|
|
if (i < end) {
|
|
|
|
|
previous_char = text_[i];
|
2003-03-12 19:16:42 +00:00
|
|
|
|
if (!isNewline(i)) {
|
1999-11-04 01:40:20 +00:00
|
|
|
|
++i;
|
2003-11-13 13:43:44 +00:00
|
|
|
|
while (i < end && previous_char != ' ') {
|
|
|
|
|
temp = text_[i];
|
2003-03-12 19:16:42 +00:00
|
|
|
|
if (isNewline(i))
|
|
|
|
|
break;
|
|
|
|
|
++i;
|
|
|
|
|
previous_char = temp;
|
|
|
|
|
}
|
1999-11-04 01:40:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2003-11-13 13:43:44 +00:00
|
|
|
|
begin_of_body_ = i;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// returns -1 if inset not found
|
2007-04-29 13:39:47 +00:00
|
|
|
|
int Paragraph::getPositionOfInset(Inset const * inset) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// Find the entry.
|
2003-05-29 01:13:18 +00:00
|
|
|
|
InsetList::const_iterator it = insetlist.begin();
|
|
|
|
|
InsetList::const_iterator end = insetlist.end();
|
2003-02-17 15:16:14 +00:00
|
|
|
|
for (; it != end; ++it)
|
2003-05-29 01:13:18 +00:00
|
|
|
|
if (it->inset == inset)
|
|
|
|
|
return it->pos;
|
2000-01-11 01:59:00 +00:00
|
|
|
|
return -1;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-02-17 15:16:14 +00:00
|
|
|
|
|
2003-05-27 22:41:04 +00:00
|
|
|
|
InsetBibitem * Paragraph::bibitem() const
|
2003-02-17 15:16:14 +00:00
|
|
|
|
{
|
2003-11-25 11:17:27 +00:00
|
|
|
|
if (!insetlist.empty()) {
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset * inset = insetlist.begin()->inset;
|
|
|
|
|
if (inset->lyxCode() == Inset::BIBITEM_CODE)
|
2003-11-25 11:17:27 +00:00
|
|
|
|
return static_cast<InsetBibitem *>(inset);
|
|
|
|
|
}
|
2002-08-23 09:05:32 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2004-04-08 15:03:33 +00:00
|
|
|
|
bool Paragraph::forceDefaultParagraphs() const
|
|
|
|
|
{
|
2005-11-17 08:41:56 +00:00
|
|
|
|
return inInset() && inInset()->forceDefaultParagraphs(0);
|
2004-04-08 15:03:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-09-19 07:25:36 +00:00
|
|
|
|
namespace {
|
|
|
|
|
|
2003-12-01 13:35:49 +00:00
|
|
|
|
// paragraphs inside floats need different alignment tags to avoid
|
2004-01-28 16:21:29 +00:00
|
|
|
|
// unwanted space
|
2003-09-19 07:25:36 +00:00
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
bool noTrivlistCentering(Inset::Code code)
|
2003-09-19 07:25:36 +00:00
|
|
|
|
{
|
2007-04-29 13:39:47 +00:00
|
|
|
|
return code == Inset::FLOAT_CODE || code == Inset::WRAP_CODE;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string correction(string const & orig)
|
|
|
|
|
{
|
|
|
|
|
if (orig == "flushleft")
|
|
|
|
|
return "raggedright";
|
|
|
|
|
if (orig == "flushright")
|
|
|
|
|
return "raggedleft";
|
|
|
|
|
if (orig == "center")
|
|
|
|
|
return "centering";
|
|
|
|
|
return orig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string const corrected_env(string const & suffix, string const & env,
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset::Code code)
|
2003-09-19 07:25:36 +00:00
|
|
|
|
{
|
|
|
|
|
string output = suffix + "{";
|
2004-04-08 15:03:33 +00:00
|
|
|
|
if (noTrivlistCentering(code))
|
2003-09-19 07:25:36 +00:00
|
|
|
|
output += correction(env);
|
|
|
|
|
else
|
|
|
|
|
output += env;
|
2006-12-04 07:27:49 +00:00
|
|
|
|
output += "}";
|
|
|
|
|
if (suffix == "\\begin")
|
|
|
|
|
output += "\n";
|
|
|
|
|
return output;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
}
|
2003-09-21 23:00:47 +00:00
|
|
|
|
|
2006-12-08 18:20:38 +00:00
|
|
|
|
|
2007-02-25 13:20:29 +00:00
|
|
|
|
void adjust_row_column(string const & str, TexRow & texrow, int & column)
|
2006-12-08 18:20:38 +00:00
|
|
|
|
{
|
|
|
|
|
if (!contains(str, "\n"))
|
2007-02-25 13:20:29 +00:00
|
|
|
|
column += str.size();
|
2006-12-08 18:20:38 +00:00
|
|
|
|
else {
|
|
|
|
|
string tmp;
|
2007-02-25 13:20:29 +00:00
|
|
|
|
texrow.newline();
|
|
|
|
|
column = rsplit(str, tmp, '\n').size();
|
2006-12-08 18:20:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-19 07:25:36 +00:00
|
|
|
|
} // namespace anon
|
|
|
|
|
|
2002-08-15 07:53:46 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
// This could go to ParagraphParameters if we want to
|
|
|
|
|
int Paragraph::startTeXParParams(BufferParams const & bparams,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2007-02-25 13:20:29 +00:00
|
|
|
|
bool moving_arg) const
|
2002-01-19 20:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
int column = 0;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
if (params().noindent()) {
|
|
|
|
|
os << "\\noindent ";
|
|
|
|
|
column += 10;
|
|
|
|
|
}
|
2007-06-28 00:48:06 +00:00
|
|
|
|
|
|
|
|
|
LyXAlignment const curAlign = params().align();
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-06-28 00:48:06 +00:00
|
|
|
|
if (curAlign == layout()->align)
|
|
|
|
|
return column;
|
|
|
|
|
|
|
|
|
|
switch (curAlign) {
|
2002-07-01 14:31:57 +00:00
|
|
|
|
case LYX_ALIGN_NONE:
|
|
|
|
|
case LYX_ALIGN_BLOCK:
|
|
|
|
|
case LYX_ALIGN_LAYOUT:
|
|
|
|
|
case LYX_ALIGN_SPECIAL:
|
|
|
|
|
break;
|
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
|
case LYX_ALIGN_CENTER:
|
|
|
|
|
if (moving_arg) {
|
|
|
|
|
os << "\\protect";
|
2004-05-17 11:28:31 +00:00
|
|
|
|
column += 8;
|
2002-07-01 14:31:57 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2002-08-10 15:21:07 +00:00
|
|
|
|
|
2007-06-28 00:48:06 +00:00
|
|
|
|
switch (curAlign) {
|
2002-01-19 20:24:04 +00:00
|
|
|
|
case LYX_ALIGN_NONE:
|
|
|
|
|
case LYX_ALIGN_BLOCK:
|
|
|
|
|
case LYX_ALIGN_LAYOUT:
|
|
|
|
|
case LYX_ALIGN_SPECIAL:
|
|
|
|
|
break;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
case LYX_ALIGN_LEFT: {
|
|
|
|
|
string output;
|
|
|
|
|
if (getParLanguage(bparams)->babel() != "hebrew")
|
2004-04-08 15:03:33 +00:00
|
|
|
|
output = corrected_env("\\begin", "flushleft", ownerCode());
|
2003-09-19 07:25:36 +00:00
|
|
|
|
else
|
2004-04-08 15:03:33 +00:00
|
|
|
|
output = corrected_env("\\begin", "flushright", ownerCode());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(output);
|
2007-02-25 13:20:29 +00:00
|
|
|
|
adjust_row_column(output, texrow, column);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
break;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
} case LYX_ALIGN_RIGHT: {
|
|
|
|
|
string output;
|
|
|
|
|
if (getParLanguage(bparams)->babel() != "hebrew")
|
2004-04-08 15:03:33 +00:00
|
|
|
|
output = corrected_env("\\begin", "flushright", ownerCode());
|
2003-09-19 07:25:36 +00:00
|
|
|
|
else
|
2004-04-08 15:03:33 +00:00
|
|
|
|
output = corrected_env("\\begin", "flushleft", ownerCode());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(output);
|
2007-02-25 13:20:29 +00:00
|
|
|
|
adjust_row_column(output, texrow, column);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
break;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
} case LYX_ALIGN_CENTER: {
|
|
|
|
|
string output;
|
2004-04-08 15:03:33 +00:00
|
|
|
|
output = corrected_env("\\begin", "center", ownerCode());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(output);
|
2007-02-25 13:20:29 +00:00
|
|
|
|
adjust_row_column(output, texrow, column);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2003-09-19 07:25:36 +00:00
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
return column;
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-15 07:53:46 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
// This could go to ParagraphParameters if we want to
|
2007-05-28 22:27:45 +00:00
|
|
|
|
int Paragraph::endTeXParParams(BufferParams const & bparams,
|
|
|
|
|
odocstream & os, TexRow & texrow,
|
2007-02-25 13:20:29 +00:00
|
|
|
|
bool moving_arg) const
|
2002-01-19 20:24:04 +00:00
|
|
|
|
{
|
|
|
|
|
int column = 0;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2002-07-01 14:31:57 +00:00
|
|
|
|
switch (params().align()) {
|
|
|
|
|
case LYX_ALIGN_NONE:
|
|
|
|
|
case LYX_ALIGN_BLOCK:
|
|
|
|
|
case LYX_ALIGN_LAYOUT:
|
|
|
|
|
case LYX_ALIGN_SPECIAL:
|
|
|
|
|
break;
|
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
|
case LYX_ALIGN_CENTER:
|
|
|
|
|
if (moving_arg) {
|
|
|
|
|
os << "\\protect";
|
|
|
|
|
column = 8;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2002-08-10 15:21:07 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
switch (params().align()) {
|
|
|
|
|
case LYX_ALIGN_NONE:
|
|
|
|
|
case LYX_ALIGN_BLOCK:
|
|
|
|
|
case LYX_ALIGN_LAYOUT:
|
|
|
|
|
case LYX_ALIGN_SPECIAL:
|
|
|
|
|
break;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
case LYX_ALIGN_LEFT: {
|
|
|
|
|
string output;
|
|
|
|
|
if (getParLanguage(bparams)->babel() != "hebrew")
|
2006-12-04 07:27:49 +00:00
|
|
|
|
output = corrected_env("\n\\par\\end", "flushleft", ownerCode());
|
2003-09-19 07:25:36 +00:00
|
|
|
|
else
|
2006-12-04 07:27:49 +00:00
|
|
|
|
output = corrected_env("\n\\par\\end", "flushright", ownerCode());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(output);
|
2007-02-25 13:20:29 +00:00
|
|
|
|
adjust_row_column(output, texrow, column);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
break;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
} case LYX_ALIGN_RIGHT: {
|
|
|
|
|
string output;
|
|
|
|
|
if (getParLanguage(bparams)->babel() != "hebrew")
|
2006-12-04 07:27:49 +00:00
|
|
|
|
output = corrected_env("\n\\par\\end", "flushright", ownerCode());
|
2003-09-19 07:25:36 +00:00
|
|
|
|
else
|
2006-12-04 07:27:49 +00:00
|
|
|
|
output = corrected_env("\n\\par\\end", "flushleft", ownerCode());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(output);
|
2007-02-25 13:20:29 +00:00
|
|
|
|
adjust_row_column(output, texrow, column);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
break;
|
2003-09-19 07:25:36 +00:00
|
|
|
|
} case LYX_ALIGN_CENTER: {
|
|
|
|
|
string output;
|
2006-12-04 07:27:49 +00:00
|
|
|
|
output = corrected_env("\n\\par\\end", "center", ownerCode());
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_ascii(output);
|
2007-02-25 13:20:29 +00:00
|
|
|
|
adjust_row_column(output, texrow, column);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2003-09-19 07:25:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
return column;
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// This one spits out the text of the paragraph
|
2003-08-28 07:41:31 +00:00
|
|
|
|
bool Paragraph::simpleTeXOnePar(Buffer const & buf,
|
2002-03-21 17:27:08 +00:00
|
|
|
|
BufferParams const & bparams,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const & outerfont,
|
2006-10-19 16:51:30 +00:00
|
|
|
|
odocstream & os, TexRow & texrow,
|
2004-05-17 11:28:31 +00:00
|
|
|
|
OutputParams const & runparams) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::LATEX) << "SimpleTeXOnePar... " << this << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
bool return_value = false;
|
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout_ptr style;
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2002-01-08 14:24:49 +00:00
|
|
|
|
// well we have to check if we are in an inset with unlimited
|
2003-10-06 14:10:59 +00:00
|
|
|
|
// length (all in one row) if that is true then we don't allow
|
2002-01-08 14:24:49 +00:00
|
|
|
|
// any special options in the paragraph and also we don't allow
|
2007-01-17 21:22:19 +00:00
|
|
|
|
// any environment other than the default layout of the text class
|
|
|
|
|
// to be valid!
|
2004-04-08 15:03:33 +00:00
|
|
|
|
bool asdefault = forceDefaultParagraphs();
|
2002-01-08 14:24:49 +00:00
|
|
|
|
|
|
|
|
|
if (asdefault) {
|
2007-04-29 19:53:54 +00:00
|
|
|
|
style = bparams.getTextClass().defaultLayout();
|
2002-01-08 14:24:49 +00:00
|
|
|
|
} else {
|
2002-06-24 20:28:12 +00:00
|
|
|
|
style = layout();
|
2002-01-08 14:24:49 +00:00
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-01-07 17:58:36 +00:00
|
|
|
|
// Current base font for all inherited font changes, without any
|
|
|
|
|
// change caused by an individual character, except for the language:
|
|
|
|
|
// It is set to the language of the first character.
|
|
|
|
|
// As long as we are in the label, this font is the base font of the
|
2007-01-07 18:40:06 +00:00
|
|
|
|
// label. Before the first body character it is set to the base font
|
2007-01-07 17:58:36 +00:00
|
|
|
|
// of the body.
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font basefont;
|
2005-02-08 13:18:05 +00:00
|
|
|
|
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// Maybe we have to create a optional argument.
|
2003-11-13 13:43:44 +00:00
|
|
|
|
pos_type body_pos = beginOfBody();
|
2003-01-08 09:03:32 +00:00
|
|
|
|
unsigned int column = 0;
|
2001-06-27 14:10:35 +00:00
|
|
|
|
|
2003-03-09 12:37:22 +00:00
|
|
|
|
if (body_pos > 0) {
|
2004-08-13 23:30:26 +00:00
|
|
|
|
// the optional argument is kept in curly brackets in
|
|
|
|
|
// case it contains a ']'
|
|
|
|
|
os << "[{";
|
|
|
|
|
column += 2;
|
2003-04-15 00:49:11 +00:00
|
|
|
|
basefont = getLabelFont(bparams, outerfont);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else {
|
2003-04-15 00:49:11 +00:00
|
|
|
|
basefont = getLayoutFont(bparams, outerfont);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Which font is currently active?
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font running_font(basefont);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Do we have an open font change?
|
|
|
|
|
bool open_font = false;
|
|
|
|
|
|
2007-05-08 17:46:03 +00:00
|
|
|
|
Change runningChange = Change(Change::UNCHANGED);
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2003-05-07 21:27:29 +00:00
|
|
|
|
texrow.start(id(), 0);
|
1999-11-04 01:40:20 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
// if the paragraph is empty, the loop will not be entered at all
|
2002-08-10 15:21:07 +00:00
|
|
|
|
if (empty()) {
|
2002-06-24 20:28:12 +00:00
|
|
|
|
if (style->isCommand()) {
|
2002-01-19 20:24:04 +00:00
|
|
|
|
os << '{';
|
|
|
|
|
++column;
|
|
|
|
|
}
|
|
|
|
|
if (!asdefault)
|
2007-02-25 13:20:29 +00:00
|
|
|
|
column += startTeXParParams(bparams, os, texrow,
|
2004-11-15 13:39:06 +00:00
|
|
|
|
runparams.moving_arg);
|
2002-01-19 20:24:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-11-26 16:42:04 +00:00
|
|
|
|
for (pos_type i = 0; i < size(); ++i) {
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// First char in paragraph or after label?
|
2003-03-09 12:37:22 +00:00
|
|
|
|
if (i == body_pos) {
|
|
|
|
|
if (body_pos > 0) {
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (open_font) {
|
2007-01-09 19:25:40 +00:00
|
|
|
|
column += running_font.latexWriteEndChanges(
|
2007-05-06 20:26:02 +00:00
|
|
|
|
os, bparams, runparams,
|
|
|
|
|
basefont, basefont);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
open_font = false;
|
|
|
|
|
}
|
2003-04-15 00:49:11 +00:00
|
|
|
|
basefont = getLayoutFont(bparams, outerfont);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
running_font = basefont;
|
2007-02-09 23:52:22 +00:00
|
|
|
|
|
2007-05-08 17:46:03 +00:00
|
|
|
|
column += Changes::latexMarkChange(os, bparams,
|
|
|
|
|
runningChange, Change(Change::UNCHANGED));
|
|
|
|
|
runningChange = Change(Change::UNCHANGED);
|
2007-02-09 23:52:22 +00:00
|
|
|
|
|
2004-08-13 23:30:26 +00:00
|
|
|
|
os << "}] ";
|
|
|
|
|
column +=3;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2002-06-24 20:28:12 +00:00
|
|
|
|
if (style->isCommand()) {
|
2000-03-06 02:42:40 +00:00
|
|
|
|
os << '{';
|
2000-01-20 01:41:55 +00:00
|
|
|
|
++column;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2002-01-19 20:24:04 +00:00
|
|
|
|
if (!asdefault)
|
2007-05-28 22:27:45 +00:00
|
|
|
|
column += startTeXParParams(bparams, os,
|
2007-02-25 13:20:29 +00:00
|
|
|
|
texrow,
|
2004-11-15 13:39:06 +00:00
|
|
|
|
runparams.moving_arg);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2007-07-21 18:10:55 +00:00
|
|
|
|
Change const & change = runparams.inDeletedInset ? runparams.changeOfDeletedInset
|
|
|
|
|
: pimpl_->lookupChange(i);
|
2007-05-08 17:46:03 +00:00
|
|
|
|
|
|
|
|
|
if (bparams.outputChanges && runningChange != change) {
|
|
|
|
|
if (open_font) {
|
|
|
|
|
column += running_font.latexWriteEndChanges(
|
|
|
|
|
os, bparams, runparams, basefont, basefont);
|
|
|
|
|
open_font = false;
|
|
|
|
|
}
|
|
|
|
|
basefont = getLayoutFont(bparams, outerfont);
|
|
|
|
|
running_font = basefont;
|
|
|
|
|
|
|
|
|
|
column += Changes::latexMarkChange(os, bparams, runningChange, change);
|
|
|
|
|
runningChange = change;
|
|
|
|
|
}
|
2007-02-09 23:52:22 +00:00
|
|
|
|
|
|
|
|
|
// do not output text which is marked deleted
|
|
|
|
|
// if change tracking output is disabled
|
2007-05-08 17:46:03 +00:00
|
|
|
|
if (!bparams.outputChanges && change.type == Change::DELETED) {
|
2007-02-09 23:52:22 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++column;
|
2007-05-28 22:27:45 +00:00
|
|
|
|
|
2007-03-18 10:59:16 +00:00
|
|
|
|
value_type const c = getChar(i);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// Fully instantiated font
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const font = getFont(bparams, i, outerfont);
|
2001-04-27 07:19:08 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const last_font = running_font;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-02-12 20:51:00 +00:00
|
|
|
|
// Do we need to close the previous font?
|
2002-04-11 13:35:03 +00:00
|
|
|
|
if (open_font &&
|
|
|
|
|
(font != running_font ||
|
|
|
|
|
font.language() != running_font.language()))
|
|
|
|
|
{
|
2007-01-09 19:25:40 +00:00
|
|
|
|
column += running_font.latexWriteEndChanges(
|
2007-05-06 20:26:02 +00:00
|
|
|
|
os, bparams, runparams, basefont,
|
2007-03-18 10:59:16 +00:00
|
|
|
|
(i == body_pos-1) ? basefont : font);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
running_font = basefont;
|
|
|
|
|
open_font = false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-18 10:59:16 +00:00
|
|
|
|
// Switch file encoding if necessary
|
2007-05-06 20:26:02 +00:00
|
|
|
|
if (runparams.encoding->package() == Encoding::inputenc &&
|
|
|
|
|
font.language()->encoding()->package() == Encoding::inputenc) {
|
2007-07-05 19:19:41 +00:00
|
|
|
|
std::pair<bool, int> const enc_switch = switchEncoding(os, bparams,
|
2007-05-06 20:26:02 +00:00
|
|
|
|
runparams.moving_arg, *(runparams.encoding),
|
|
|
|
|
*(font.language()->encoding()));
|
2007-07-05 19:19:41 +00:00
|
|
|
|
if (enc_switch.first) {
|
|
|
|
|
column += enc_switch.second;
|
2007-05-06 20:26:02 +00:00
|
|
|
|
runparams.encoding = font.language()->encoding();
|
|
|
|
|
}
|
2007-03-18 10:59:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-02-11 23:52:07 +00:00
|
|
|
|
// Do we need to change font?
|
|
|
|
|
if ((font != running_font ||
|
|
|
|
|
font.language() != running_font.language()) &&
|
|
|
|
|
i != body_pos - 1)
|
|
|
|
|
{
|
2007-07-12 13:25:44 +00:00
|
|
|
|
odocstringstream ods;
|
|
|
|
|
column += font.latexWriteStartChanges(ods, bparams,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
runparams, basefont,
|
|
|
|
|
last_font);
|
2007-02-11 23:52:07 +00:00
|
|
|
|
running_font = font;
|
|
|
|
|
open_font = true;
|
2007-07-12 13:25:44 +00:00
|
|
|
|
docstring fontchange = ods.str();
|
|
|
|
|
// check if the fontchange ends with a trailing blank
|
|
|
|
|
// (like "\small " (see bug 3382)
|
|
|
|
|
if (suffixIs(fontchange, ' ') && c == ' ')
|
|
|
|
|
os << fontchange.substr(0, fontchange.size() - 1)
|
|
|
|
|
<< from_ascii("{}");
|
|
|
|
|
else
|
|
|
|
|
os << fontchange;
|
2007-02-11 23:52:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-08 23:16:16 +00:00
|
|
|
|
if (c == ' ') {
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Do not print the separation of the optional argument
|
2007-03-13 20:06:04 +00:00
|
|
|
|
// if style->pass_thru is false. This works because
|
|
|
|
|
// simpleTeXSpecialChars ignores spaces if
|
|
|
|
|
// style->pass_thru is false.
|
2003-03-09 12:37:22 +00:00
|
|
|
|
if (i != body_pos - 1) {
|
2007-04-16 18:20:49 +00:00
|
|
|
|
if (pimpl_->simpleTeXBlanks(
|
2007-04-16 18:06:01 +00:00
|
|
|
|
*(runparams.encoding), os, texrow,
|
Add machinery to output arbitrary unicode characters with LaTeX commands
read from a text file.
* src/encoding.[Ch]
(Encoding::latexChar): New, output a character to LaTeX
(Encoding::validate): New, add needed preamble stuff for a character
(Encodings::read): Read new unicodesymbols file
(Encodings::isCombiningChar): New, is a character a combining char?
* src/paragraph_pimpl.C
(isEncoding): Delete, no longer needed
(getEncoding): New, get the real encoding of a font
(Paragraph::Pimpl::latexSurrogatePair): New, output a surrogate pair
to LaTeX
(Paragraph::Pimpl::simpleTeXBlanks): Use latexSurrogatePair if needed
(Paragraph::Pimpl::simpleTeXSpecialChars): Ditto, and replace several
hardcoded characters with a call of encoding.latexChar()
(Paragraph::Pimpl::validate): replace several hardcoded characters
with a call of encoding.validate()
* src/support/debugstream.h
(basic_debugstream::disable): New, disable the stream completely
(basic_debugstream::enable): New, reenable the stream
* src/lyx_main.[Ch]: Adjust to changes above
* src/paragraph.C: Ditto
* lib/unicodesymbols: New file with UCS4 -> LaTeX command mapping.
It is far from complete yet, but contains most accents on latin
characters.
* lib/Makefile.am: add lib/unicodesymbols
* development/scons/scons_manifest.py: ditto
* development/tools/unicodesymbols.py: Helper script to update
lib/unicodesymbols with new symbols
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16920 a592a061-630c-0410-9148-cb99ea01b6c8
2007-01-28 21:27:45 +00:00
|
|
|
|
i, column, font, *style))
|
|
|
|
|
// A surrogate pair was output. We
|
|
|
|
|
// must not call simpleTeXSpecialChars
|
|
|
|
|
// in this iteration, since
|
|
|
|
|
// simpleTeXBlanks incremented i, and
|
|
|
|
|
// simpleTeXSpecialChars would output
|
|
|
|
|
// the combining character again.
|
|
|
|
|
continue;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-09 23:52:22 +00:00
|
|
|
|
OutputParams rp = runparams;
|
|
|
|
|
rp.free_spacing = style->free_spacing;
|
|
|
|
|
rp.local_font = &font;
|
|
|
|
|
rp.intitle = style->intitle;
|
2007-04-16 18:06:01 +00:00
|
|
|
|
pimpl_->simpleTeXSpecialChars(buf, bparams, os,
|
2007-03-13 19:46:56 +00:00
|
|
|
|
texrow, rp, running_font,
|
2007-02-09 23:52:22 +00:00
|
|
|
|
basefont, outerfont, open_font,
|
2007-05-08 17:46:03 +00:00
|
|
|
|
runningChange, *style, i, column, c);
|
2007-07-20 01:28:20 +00:00
|
|
|
|
|
|
|
|
|
// Set the encoding to that returned from simpleTeXSpecialChars (see
|
|
|
|
|
// comment for encoding member in OutputParams.h)
|
|
|
|
|
runparams.encoding = rp.encoding;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we have an open font definition, we have to close it
|
|
|
|
|
if (open_font) {
|
2001-07-27 12:03:36 +00:00
|
|
|
|
#ifdef FIXED_LANGUAGE_END_DETECTION
|
2001-04-27 07:19:08 +00:00
|
|
|
|
if (next_) {
|
|
|
|
|
running_font
|
2007-05-06 20:26:02 +00:00
|
|
|
|
.latexWriteEndChanges(os, bparams, runparams,
|
|
|
|
|
basefont,
|
2007-03-18 10:59:16 +00:00
|
|
|
|
next_->getFont(bparams, 0, outerfont));
|
2001-04-27 07:19:08 +00:00
|
|
|
|
} else {
|
2007-05-06 20:26:02 +00:00
|
|
|
|
running_font.latexWriteEndChanges(os, bparams,
|
|
|
|
|
runparams, basefont, basefont);
|
2001-04-27 07:19:08 +00:00
|
|
|
|
}
|
2001-07-27 12:03:36 +00:00
|
|
|
|
#else
|
|
|
|
|
#ifdef WITH_WARNINGS
|
2001-09-09 22:02:19 +00:00
|
|
|
|
//#warning For now we ALWAYS have to close the foreign font settings if they are
|
|
|
|
|
//#warning there as we start another \selectlanguage with the next paragraph if
|
|
|
|
|
//#warning we are in need of this. This should be fixed sometime (Jug)
|
2001-07-27 12:03:36 +00:00
|
|
|
|
#endif
|
2007-05-06 20:26:02 +00:00
|
|
|
|
running_font.latexWriteEndChanges(os, bparams, runparams,
|
|
|
|
|
basefont, basefont);
|
2001-07-27 12:03:36 +00:00
|
|
|
|
#endif
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-05-08 17:46:03 +00:00
|
|
|
|
column += Changes::latexMarkChange(os, bparams, runningChange, Change(Change::UNCHANGED));
|
2007-02-09 23:52:22 +00:00
|
|
|
|
|
2000-01-11 01:59:00 +00:00
|
|
|
|
// Needed if there is an optional argument but no contents.
|
2003-03-09 12:37:22 +00:00
|
|
|
|
if (body_pos > 0 && body_pos == size()) {
|
2005-04-11 15:09:54 +00:00
|
|
|
|
os << "}]~";
|
1999-11-04 01:40:20 +00:00
|
|
|
|
return_value = false;
|
|
|
|
|
}
|
1999-11-15 12:01:38 +00:00
|
|
|
|
|
2002-01-08 14:24:49 +00:00
|
|
|
|
if (!asdefault) {
|
2007-05-28 22:27:45 +00:00
|
|
|
|
column += endTeXParParams(bparams, os, texrow,
|
2007-02-25 13:20:29 +00:00
|
|
|
|
runparams.moving_arg);
|
2002-01-08 14:24:49 +00:00
|
|
|
|
}
|
2001-06-27 14:10:35 +00:00
|
|
|
|
|
2007-04-01 10:09:49 +00:00
|
|
|
|
LYXERR(Debug::LATEX) << "SimpleTeXOnePar...done " << this << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-10-30 08:47:16 +00:00
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
enum PAR_TAG {
|
2004-01-26 10:13:15 +00:00
|
|
|
|
PAR_NONE=0,
|
2003-10-30 08:47:16 +00:00
|
|
|
|
TT = 1,
|
|
|
|
|
SF = 2,
|
|
|
|
|
BF = 4,
|
|
|
|
|
IT = 8,
|
|
|
|
|
SL = 16,
|
|
|
|
|
EM = 32
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string tag_name(PAR_TAG const & pt) {
|
|
|
|
|
switch (pt) {
|
2004-01-26 10:13:15 +00:00
|
|
|
|
case PAR_NONE: return "!-- --";
|
2003-10-30 08:47:16 +00:00
|
|
|
|
case TT: return "tt";
|
|
|
|
|
case SF: return "sf";
|
|
|
|
|
case BF: return "bf";
|
|
|
|
|
case IT: return "it";
|
|
|
|
|
case SL: return "sl";
|
|
|
|
|
case EM: return "em";
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
|
|
|
|
void operator|=(PAR_TAG & p1, PAR_TAG const & p2)
|
|
|
|
|
{
|
|
|
|
|
p1 = static_cast<PAR_TAG>(p1 | p2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
|
|
|
|
void reset(PAR_TAG & p1, PAR_TAG const & p2)
|
|
|
|
|
{
|
|
|
|
|
p1 = static_cast<PAR_TAG>(p1 & ~p2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // anon
|
|
|
|
|
|
|
|
|
|
|
2004-10-30 13:05:31 +00:00
|
|
|
|
bool Paragraph::emptyTag() const
|
|
|
|
|
{
|
|
|
|
|
for (pos_type i = 0; i < size(); ++i) {
|
|
|
|
|
if (isInset(i)) {
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset const * inset = getInset(i);
|
|
|
|
|
Inset::Code lyx_code = inset->lyxCode();
|
|
|
|
|
if (lyx_code != Inset::TOC_CODE &&
|
|
|
|
|
lyx_code != Inset::INCLUDE_CODE &&
|
|
|
|
|
lyx_code != Inset::GRAPHICS_CODE &&
|
|
|
|
|
lyx_code != Inset::ERT_CODE &&
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
|
lyx_code != Inset::LISTINGS_CODE &&
|
2007-04-29 13:39:47 +00:00
|
|
|
|
lyx_code != Inset::FLOAT_CODE &&
|
|
|
|
|
lyx_code != Inset::TABULAR_CODE) {
|
2004-10-30 13:05:31 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2005-01-06 15:40:49 +00:00
|
|
|
|
value_type c = getChar(i);
|
|
|
|
|
if (c != ' ' && c != '\t')
|
2004-10-30 13:05:31 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-11-02 11:25:20 +00:00
|
|
|
|
string Paragraph::getID(Buffer const & buf, OutputParams const & runparams) const
|
2004-05-14 15:47:35 +00:00
|
|
|
|
{
|
|
|
|
|
for (pos_type i = 0; i < size(); ++i) {
|
|
|
|
|
if (isInset(i)) {
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset const * inset = getInset(i);
|
|
|
|
|
Inset::Code lyx_code = inset->lyxCode();
|
|
|
|
|
if (lyx_code == Inset::LABEL_CODE) {
|
2004-10-29 23:08:04 +00:00
|
|
|
|
string const id = static_cast<InsetCommand const *>(inset)->getContents();
|
2006-10-22 11:13:18 +00:00
|
|
|
|
return "id='" + to_utf8(sgml::cleanID(buf, runparams, from_utf8(id))) + "'";
|
2004-05-14 15:47:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return string();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-19 21:00:33 +00:00
|
|
|
|
pos_type Paragraph::getFirstWord(Buffer const & buf, odocstream & os, OutputParams const & runparams) const
|
2004-10-24 23:53:42 +00:00
|
|
|
|
{
|
|
|
|
|
pos_type i;
|
|
|
|
|
for (i = 0; i < size(); ++i) {
|
|
|
|
|
if (isInset(i)) {
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset const * inset = getInset(i);
|
2004-10-24 23:53:42 +00:00
|
|
|
|
inset->docbook(buf, os, runparams);
|
|
|
|
|
} else {
|
2005-01-06 15:40:49 +00:00
|
|
|
|
value_type c = getChar(i);
|
2004-10-24 23:53:42 +00:00
|
|
|
|
if (c == ' ')
|
|
|
|
|
break;
|
2006-10-21 11:38:43 +00:00
|
|
|
|
os << sgml::escapeChar(c);
|
2007-05-28 22:27:45 +00:00
|
|
|
|
}
|
2004-10-24 23:53:42 +00:00
|
|
|
|
}
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
2004-10-30 22:14:02 +00:00
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
|
bool Paragraph::onlyText(Buffer const & buf, Font const & outerfont, pos_type initial) const
|
2004-10-30 22:14:02 +00:00
|
|
|
|
{
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font_old;
|
2004-10-30 22:14:02 +00:00
|
|
|
|
|
|
|
|
|
for (pos_type i = initial; i < size(); ++i) {
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font = getFont(buf.params(), i, outerfont);
|
2004-10-30 22:14:02 +00:00
|
|
|
|
if (isInset(i))
|
|
|
|
|
return false;
|
2005-01-06 15:40:49 +00:00
|
|
|
|
if (i != initial && font != font_old)
|
2004-10-30 22:14:02 +00:00
|
|
|
|
return false;
|
|
|
|
|
font_old = font;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-10-30 08:47:16 +00:00
|
|
|
|
void Paragraph::simpleDocBookOnePar(Buffer const & buf,
|
2006-10-19 21:00:33 +00:00
|
|
|
|
odocstream & os,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const & outerfont,
|
2004-10-24 23:53:42 +00:00
|
|
|
|
pos_type initial) const
|
2003-10-30 08:47:16 +00:00
|
|
|
|
{
|
|
|
|
|
bool emph_flag = false;
|
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout_ptr const & style = layout();
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font_old =
|
2003-12-01 13:35:49 +00:00
|
|
|
|
style->labeltype == LABEL_MANUAL ? style->labelfont : style->font;
|
2003-10-30 08:47:16 +00:00
|
|
|
|
|
2005-01-06 15:40:49 +00:00
|
|
|
|
if (style->pass_thru && !onlyText(buf, outerfont, initial))
|
2004-10-30 22:14:02 +00:00
|
|
|
|
os << "]]>";
|
2005-01-06 15:40:49 +00:00
|
|
|
|
|
2003-10-30 08:47:16 +00:00
|
|
|
|
// parsing main loop
|
2004-10-24 23:53:42 +00:00
|
|
|
|
for (pos_type i = initial; i < size(); ++i) {
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font = getFont(buf.params(), i, outerfont);
|
2003-10-30 08:47:16 +00:00
|
|
|
|
|
|
|
|
|
// handle <emphasis> tag
|
|
|
|
|
if (font_old.emph() != font.emph()) {
|
2007-04-29 18:17:15 +00:00
|
|
|
|
if (font.emph() == Font::ON) {
|
2003-10-30 08:47:16 +00:00
|
|
|
|
os << "<emphasis>";
|
|
|
|
|
emph_flag = true;
|
2004-10-24 23:53:42 +00:00
|
|
|
|
} else if (i != initial) {
|
2003-10-30 08:47:16 +00:00
|
|
|
|
os << "</emphasis>";
|
|
|
|
|
emph_flag = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isInset(i)) {
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset const * inset = getInset(i);
|
2004-05-14 15:47:35 +00:00
|
|
|
|
inset->docbook(buf, os, runparams);
|
2003-10-30 08:47:16 +00:00
|
|
|
|
} else {
|
2005-01-06 15:40:49 +00:00
|
|
|
|
value_type c = getChar(i);
|
2003-10-30 08:47:16 +00:00
|
|
|
|
|
2004-10-24 23:53:42 +00:00
|
|
|
|
if (style->pass_thru)
|
2007-05-28 22:27:45 +00:00
|
|
|
|
os.put(c);
|
2004-10-24 23:53:42 +00:00
|
|
|
|
else
|
2007-05-28 22:27:45 +00:00
|
|
|
|
os << sgml::escapeChar(c);
|
2003-10-30 08:47:16 +00:00
|
|
|
|
}
|
|
|
|
|
font_old = font;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (emph_flag) {
|
|
|
|
|
os << "</emphasis>";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (style->free_spacing)
|
|
|
|
|
os << '\n';
|
2005-01-06 15:40:49 +00:00
|
|
|
|
if (style->pass_thru && !onlyText(buf, outerfont, initial))
|
2004-10-30 22:14:02 +00:00
|
|
|
|
os << "<![CDATA[";
|
2003-10-30 08:47:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-11-26 16:42:04 +00:00
|
|
|
|
bool Paragraph::isNewline(pos_type pos) const
|
1999-11-15 12:01:38 +00:00
|
|
|
|
{
|
2004-10-05 10:11:42 +00:00
|
|
|
|
return isInset(pos)
|
2007-04-29 13:39:47 +00:00
|
|
|
|
&& getInset(pos)->lyxCode() == Inset::NEWLINE_CODE;
|
1999-11-15 12:01:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-11-26 16:42:04 +00:00
|
|
|
|
bool Paragraph::isLineSeparator(pos_type pos) const
|
1999-11-15 12:01:38 +00:00
|
|
|
|
{
|
2002-02-13 10:37:28 +00:00
|
|
|
|
value_type const c = getChar(pos);
|
2006-04-08 09:09:57 +00:00
|
|
|
|
return isLineSeparatorChar(c)
|
2005-07-18 12:57:08 +00:00
|
|
|
|
|| (c == Paragraph::META_INSET && getInset(pos) &&
|
2002-03-21 17:27:08 +00:00
|
|
|
|
getInset(pos)->isLineSeparator());
|
1999-11-15 12:01:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Used by the spellchecker
|
2001-11-26 16:42:04 +00:00
|
|
|
|
bool Paragraph::isLetter(pos_type pos) const
|
1999-11-15 12:01:38 +00:00
|
|
|
|
{
|
2002-03-21 17:27:08 +00:00
|
|
|
|
if (isInset(pos))
|
2001-11-13 14:47:35 +00:00
|
|
|
|
return getInset(pos)->isLetter();
|
2004-11-18 14:58:54 +00:00
|
|
|
|
else {
|
|
|
|
|
value_type const c = getChar(pos);
|
2006-04-08 09:09:57 +00:00
|
|
|
|
return isLetterChar(c) || isDigit(c);
|
2004-11-18 14:58:54 +00:00
|
|
|
|
}
|
1999-11-15 12:01:38 +00:00
|
|
|
|
}
|
2000-02-22 00:36:17 +00:00
|
|
|
|
|
2000-04-10 21:40:13 +00:00
|
|
|
|
|
2000-06-08 23:16:16 +00:00
|
|
|
|
Language const *
|
2002-03-21 17:27:08 +00:00
|
|
|
|
Paragraph::getParLanguage(BufferParams const & bparams) const
|
2000-03-17 10:14:46 +00:00
|
|
|
|
{
|
2003-07-27 21:59:06 +00:00
|
|
|
|
if (!empty())
|
2006-02-05 13:20:16 +00:00
|
|
|
|
return getFirstFontSettings(bparams).language();
|
2004-04-05 09:36:28 +00:00
|
|
|
|
#ifdef WITH_WARNINGS
|
2003-04-16 08:12:22 +00:00
|
|
|
|
#warning FIXME we should check the prev par as well (Lgb)
|
2004-04-05 09:36:28 +00:00
|
|
|
|
#endif
|
2003-07-27 21:59:06 +00:00
|
|
|
|
return bparams.language;
|
2000-03-17 10:14:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-04-10 21:40:13 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const
|
2000-03-17 10:14:46 +00:00
|
|
|
|
{
|
2000-07-21 18:47:54 +00:00
|
|
|
|
return lyxrc.rtl_support
|
2006-04-09 00:26:19 +00:00
|
|
|
|
&& getParLanguage(bparams)->rightToLeft()
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
|
&& ownerCode() != Inset::ERT_CODE
|
|
|
|
|
&& ownerCode() != Inset::LISTINGS_CODE;
|
2000-03-17 10:14:46 +00:00
|
|
|
|
}
|
2000-02-22 00:36:17 +00:00
|
|
|
|
|
2000-04-10 21:40:13 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
void Paragraph::changeLanguage(BufferParams const & bparams,
|
2003-04-15 00:11:03 +00:00
|
|
|
|
Language const * from, Language const * to)
|
2000-02-22 00:36:17 +00:00
|
|
|
|
{
|
2006-11-12 17:02:43 +00:00
|
|
|
|
// change language including dummy font change at the end
|
|
|
|
|
for (pos_type i = 0; i <= size(); ++i) {
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font = getFontSettings(bparams, i);
|
2000-04-10 21:40:13 +00:00
|
|
|
|
if (font.language() == from) {
|
|
|
|
|
font.setLanguage(to);
|
2001-06-25 00:06:33 +00:00
|
|
|
|
setFont(i, font);
|
2000-04-10 21:40:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-02-22 00:36:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-04-10 21:40:13 +00:00
|
|
|
|
|
2004-02-25 12:00:53 +00:00
|
|
|
|
bool Paragraph::isMultiLingual(BufferParams const & bparams) const
|
2000-02-22 00:36:17 +00:00
|
|
|
|
{
|
2000-10-10 12:36:36 +00:00
|
|
|
|
Language const * doc_language = bparams.language;
|
2002-03-13 18:23:38 +00:00
|
|
|
|
Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
|
|
|
|
|
Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
|
2002-03-21 17:27:08 +00:00
|
|
|
|
|
2002-03-13 18:23:38 +00:00
|
|
|
|
for (; cit != end; ++cit)
|
2001-08-11 18:31:14 +00:00
|
|
|
|
if (cit->font().language() != ignore_language &&
|
|
|
|
|
cit->font().language() != latex_language &&
|
2003-07-31 13:38:06 +00:00
|
|
|
|
cit->font().language() != doc_language)
|
2000-04-10 21:40:13 +00:00
|
|
|
|
return true;
|
|
|
|
|
return false;
|
2000-02-22 00:36:17 +00:00
|
|
|
|
}
|
2000-05-19 16:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Convert the paragraph to a string.
|
|
|
|
|
// Used for building the table of contents
|
2006-10-11 19:40:50 +00:00
|
|
|
|
docstring const Paragraph::asString(Buffer const & buffer, bool label) const
|
2003-10-31 18:45:43 +00:00
|
|
|
|
{
|
2007-01-19 16:23:13 +00:00
|
|
|
|
return asString(buffer, 0, size(), label);
|
2000-05-19 16:46:01 +00:00
|
|
|
|
}
|
2000-05-20 21:37:05 +00:00
|
|
|
|
|
|
|
|
|
|
2006-10-11 19:40:50 +00:00
|
|
|
|
docstring const Paragraph::asString(Buffer const & buffer,
|
2002-11-08 01:08:27 +00:00
|
|
|
|
pos_type beg, pos_type end, bool label) const
|
2000-05-20 21:37:05 +00:00
|
|
|
|
{
|
2003-10-31 18:45:43 +00:00
|
|
|
|
|
2007-01-19 16:23:13 +00:00
|
|
|
|
odocstringstream os;
|
2000-07-19 17:16:27 +00:00
|
|
|
|
|
2001-09-12 10:41:25 +00:00
|
|
|
|
if (beg == 0 && label && !params().labelString().empty())
|
2006-10-20 19:26:23 +00:00
|
|
|
|
os << params().labelString() << ' ';
|
2000-05-20 21:37:05 +00:00
|
|
|
|
|
2001-11-26 16:42:04 +00:00
|
|
|
|
for (pos_type i = beg; i < end; ++i) {
|
2007-05-17 21:47:32 +00:00
|
|
|
|
value_type const c = getChar(i);
|
2006-04-08 09:09:57 +00:00
|
|
|
|
if (isPrintable(c))
|
2006-10-11 19:40:50 +00:00
|
|
|
|
os.put(c);
|
2003-03-13 10:30:28 +00:00
|
|
|
|
else if (c == META_INSET)
|
2007-01-19 16:23:13 +00:00
|
|
|
|
getInset(i)->textString(buffer, os);
|
2000-05-20 21:37:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-09-15 11:00:00 +00:00
|
|
|
|
return os.str();
|
2000-05-20 21:37:05 +00:00
|
|
|
|
}
|
2000-06-23 15:02:46 +00:00
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
void Paragraph::setInsetOwner(Inset * inset)
|
2000-06-23 15:02:46 +00:00
|
|
|
|
{
|
2003-06-04 07:14:05 +00:00
|
|
|
|
pimpl_->inset_owner = inset;
|
2000-06-23 15:02:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-01-08 22:21:57 +00:00
|
|
|
|
Change const & Paragraph::lookupChange(pos_type pos) const
|
2003-02-08 19:18:01 +00:00
|
|
|
|
{
|
2006-03-11 13:31:41 +00:00
|
|
|
|
BOOST_ASSERT(pos <= size());
|
2006-05-08 20:30:52 +00:00
|
|
|
|
return pimpl_->lookupChange(pos);
|
2003-02-08 19:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
|
bool Paragraph::isChanged(pos_type start, pos_type end) const
|
|
|
|
|
{
|
|
|
|
|
return pimpl_->isChanged(start, end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-11-24 21:16:46 +00:00
|
|
|
|
bool Paragraph::isMergedOnEndOfParDeletion(bool trackChanges) const
|
|
|
|
|
{
|
|
|
|
|
return pimpl_->isMergedOnEndOfParDeletion(trackChanges);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-19 07:12:48 +00:00
|
|
|
|
void Paragraph::setChange(Change const & change)
|
2003-03-04 19:52:35 +00:00
|
|
|
|
{
|
2006-10-19 07:12:48 +00:00
|
|
|
|
pimpl_->setChange(change);
|
2003-03-04 19:52:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
void Paragraph::setChange(pos_type pos, Change const & change)
|
2003-02-08 19:18:01 +00:00
|
|
|
|
{
|
2006-10-19 07:12:48 +00:00
|
|
|
|
pimpl_->setChange(pos, change);
|
2003-02-08 19:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2007-01-23 21:53:16 +00:00
|
|
|
|
void Paragraph::acceptChanges(BufferParams const & bparams, pos_type start, pos_type end)
|
2003-02-08 19:18:01 +00:00
|
|
|
|
{
|
2007-01-23 21:53:16 +00:00
|
|
|
|
return pimpl_->acceptChanges(bparams, start, end);
|
2003-02-08 19:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2007-01-23 21:53:16 +00:00
|
|
|
|
void Paragraph::rejectChanges(BufferParams const & bparams, pos_type start, pos_type end)
|
2003-02-08 19:18:01 +00:00
|
|
|
|
{
|
2007-01-23 21:53:16 +00:00
|
|
|
|
return pimpl_->rejectChanges(bparams, start, end);
|
2003-02-08 19:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-03 21:15:49 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
int Paragraph::id() const
|
|
|
|
|
{
|
|
|
|
|
return pimpl_->id_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
Layout_ptr const & Paragraph::layout() const
|
2002-03-02 16:39:54 +00:00
|
|
|
|
{
|
|
|
|
|
return layout_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 18:58:28 +00:00
|
|
|
|
void Paragraph::layout(Layout_ptr const & new_layout)
|
2001-06-25 00:06:33 +00:00
|
|
|
|
{
|
2002-03-02 16:39:54 +00:00
|
|
|
|
layout_ = new_layout;
|
2001-06-25 00:06:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset * Paragraph::inInset() const
|
2001-02-16 09:25:43 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
return pimpl_->inset_owner;
|
2001-02-16 09:25:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset::Code Paragraph::ownerCode() const
|
2004-04-08 15:03:33 +00:00
|
|
|
|
{
|
|
|
|
|
return pimpl_->inset_owner
|
2007-04-29 13:39:47 +00:00
|
|
|
|
? pimpl_->inset_owner->lyxCode() : Inset::NO_CODE;
|
2004-04-08 15:03:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
ParagraphParameters & Paragraph::params()
|
|
|
|
|
{
|
|
|
|
|
return pimpl_->params;
|
|
|
|
|
}
|
|
|
|
|
|
2001-07-17 13:01:41 +00:00
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
ParagraphParameters const & Paragraph::params() const
|
2001-02-16 09:25:43 +00:00
|
|
|
|
{
|
2001-06-25 00:06:33 +00:00
|
|
|
|
return pimpl_->params;
|
2001-02-16 09:25:43 +00:00
|
|
|
|
}
|
2001-06-27 14:10:35 +00:00
|
|
|
|
|
2001-07-17 13:01:41 +00:00
|
|
|
|
|
2001-11-29 16:29:30 +00:00
|
|
|
|
bool Paragraph::isFreeSpacing() const
|
|
|
|
|
{
|
2003-06-07 17:45:43 +00:00
|
|
|
|
if (layout()->free_spacing)
|
|
|
|
|
return true;
|
|
|
|
|
|
2001-11-29 16:29:30 +00:00
|
|
|
|
// for now we just need this, later should we need this in some
|
2007-04-29 13:39:47 +00:00
|
|
|
|
// other way we can always add a function to Inset too.
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
|
return ownerCode() == Inset::ERT_CODE || ownerCode() == Inset::LISTINGS_CODE;
|
2001-11-29 16:29:30 +00:00
|
|
|
|
}
|
2003-05-27 20:59:03 +00:00
|
|
|
|
|
|
|
|
|
|
2003-06-07 17:45:43 +00:00
|
|
|
|
bool Paragraph::allowEmpty() const
|
|
|
|
|
{
|
|
|
|
|
if (layout()->keepempty)
|
|
|
|
|
return true;
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
|
return ownerCode() == Inset::ERT_CODE || ownerCode() == Inset::LISTINGS_CODE;
|
2003-06-07 17:45:43 +00:00
|
|
|
|
}
|
2003-10-24 09:45:07 +00:00
|
|
|
|
|
|
|
|
|
|
2006-08-13 22:54:59 +00:00
|
|
|
|
char_type Paragraph::transformChar(char_type c, pos_type pos) const
|
2003-10-27 12:41:26 +00:00
|
|
|
|
{
|
|
|
|
|
if (!Encodings::is_arabic(c))
|
2007-03-26 08:24:38 +00:00
|
|
|
|
return c;
|
2003-10-27 12:41:26 +00:00
|
|
|
|
|
2007-04-27 20:37:57 +00:00
|
|
|
|
value_type prev_char = ' ';
|
2006-04-09 02:30:40 +00:00
|
|
|
|
value_type next_char = ' ';
|
2003-10-27 12:41:26 +00:00
|
|
|
|
|
2007-04-27 20:37:57 +00:00
|
|
|
|
for (pos_type i = pos - 1; i >= 0; --i) {
|
|
|
|
|
value_type const par_char = getChar(i);
|
|
|
|
|
if (!Encodings::isComposeChar_arabic(par_char)) {
|
|
|
|
|
prev_char = par_char;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-27 12:41:26 +00:00
|
|
|
|
for (pos_type i = pos + 1, end = size(); i < end; ++i) {
|
2006-04-09 02:30:40 +00:00
|
|
|
|
value_type const par_char = getChar(i);
|
2006-04-09 00:26:19 +00:00
|
|
|
|
if (!Encodings::isComposeChar_arabic(par_char)) {
|
2003-10-27 12:41:26 +00:00
|
|
|
|
next_char = par_char;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Encodings::is_arabic(next_char)) {
|
|
|
|
|
if (Encodings::is_arabic(prev_char) &&
|
|
|
|
|
!Encodings::is_arabic_special(prev_char))
|
2006-04-09 00:26:19 +00:00
|
|
|
|
return Encodings::transformChar(c, Encodings::FORM_MEDIAL);
|
2003-10-27 12:41:26 +00:00
|
|
|
|
else
|
2006-04-09 00:26:19 +00:00
|
|
|
|
return Encodings::transformChar(c, Encodings::FORM_INITIAL);
|
2003-10-27 12:41:26 +00:00
|
|
|
|
} else {
|
|
|
|
|
if (Encodings::is_arabic(prev_char) &&
|
|
|
|
|
!Encodings::is_arabic_special(prev_char))
|
2006-04-09 00:26:19 +00:00
|
|
|
|
return Encodings::transformChar(c, Encodings::FORM_FINAL);
|
2003-10-27 12:41:26 +00:00
|
|
|
|
else
|
2006-04-09 00:26:19 +00:00
|
|
|
|
return Encodings::transformChar(c, Encodings::FORM_ISOLATED);
|
2003-10-27 12:41:26 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-11-30 01:59:49 +00:00
|
|
|
|
|
|
|
|
|
|
2006-10-21 07:24:11 +00:00
|
|
|
|
bool Paragraph::hfillExpansion(Row const & row, pos_type pos) const
|
|
|
|
|
{
|
|
|
|
|
if (!isHfill(pos))
|
|
|
|
|
return false;
|
|
|
|
|
|
2007-01-07 10:25:45 +00:00
|
|
|
|
BOOST_ASSERT(pos >= row.pos() && pos < row.endpos());
|
|
|
|
|
|
|
|
|
|
// expand at the end of a row only if there is another hfill on the same row
|
|
|
|
|
if (pos == row.endpos() - 1) {
|
|
|
|
|
for (pos_type i = row.pos(); i < pos; i++) {
|
|
|
|
|
if (isHfill(i))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2006-10-21 07:24:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-07 10:42:10 +00:00
|
|
|
|
// expand at the beginning of a row only if it is the first row of a paragraph
|
2007-01-07 10:25:45 +00:00
|
|
|
|
if (pos == row.pos()) {
|
2007-01-07 10:42:10 +00:00
|
|
|
|
return pos == 0;
|
2007-01-07 10:25:45 +00:00
|
|
|
|
}
|
2006-10-21 07:24:11 +00:00
|
|
|
|
|
2007-01-07 10:25:45 +00:00
|
|
|
|
// do not expand in some labels
|
2006-10-21 07:24:11 +00:00
|
|
|
|
if (layout()->margintype != MARGIN_MANUAL && pos < beginOfBody())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// if there is anything between the first char of the row and
|
2007-01-07 10:25:45 +00:00
|
|
|
|
// the specified position that is neither a newline nor an hfill,
|
|
|
|
|
// the hfill will be expanded, otherwise it won't
|
2007-01-07 10:42:10 +00:00
|
|
|
|
for (pos_type i = row.pos(); i < pos; i++) {
|
|
|
|
|
if (!isNewline(i) && !isHfill(i))
|
|
|
|
|
return true;
|
2007-01-07 10:25:45 +00:00
|
|
|
|
}
|
2007-01-07 10:42:10 +00:00
|
|
|
|
return false;
|
2006-10-21 07:24:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-05-19 19:29:50 +00:00
|
|
|
|
int Paragraph::checkBiblio(bool track_changes)
|
2006-12-29 23:54:48 +00:00
|
|
|
|
{
|
2007-05-19 19:29:50 +00:00
|
|
|
|
//FIXME From JS:
|
2007-05-28 22:27:45 +00:00
|
|
|
|
//This is getting more and more a mess. ...We really should clean
|
2007-05-19 19:29:50 +00:00
|
|
|
|
//up this bibitem issue for 1.6. See also bug 2743.
|
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
// Add bibitem insets if necessary
|
|
|
|
|
if (layout()->labeltype != LABEL_BIBLIO)
|
2007-05-19 19:29:50 +00:00
|
|
|
|
return 0;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
|
|
|
|
bool hasbibitem = !insetlist.empty()
|
|
|
|
|
// Insist on it being in pos 0
|
|
|
|
|
&& getChar(0) == Paragraph::META_INSET
|
2007-04-29 13:39:47 +00:00
|
|
|
|
&& insetlist.begin()->inset->lyxCode() == Inset::BIBITEM_CODE;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-05-14 09:24:17 +00:00
|
|
|
|
docstring oldkey;
|
|
|
|
|
docstring oldlabel;
|
|
|
|
|
|
2007-05-19 19:29:50 +00:00
|
|
|
|
// remove a bibitem in pos != 0
|
|
|
|
|
// restore it later in pos 0 if necessary
|
2007-05-14 09:24:17 +00:00
|
|
|
|
// (e.g. if a user inserts contents _before_ the item)
|
2007-05-19 19:29:50 +00:00
|
|
|
|
// we're assuming there's only one of these, which there
|
|
|
|
|
// should be.
|
|
|
|
|
int erasedInsetPosition = -1;
|
|
|
|
|
InsetList::iterator it = insetlist.begin();
|
|
|
|
|
InsetList::iterator end = insetlist.end();
|
2007-05-14 09:24:17 +00:00
|
|
|
|
for (; it != end; ++it)
|
|
|
|
|
if (it->inset->lyxCode() == Inset::BIBITEM_CODE
|
|
|
|
|
&& it->pos > 0) {
|
|
|
|
|
InsetBibitem * olditem = static_cast<InsetBibitem *>(it->inset);
|
|
|
|
|
oldkey = olditem->getParam("key");
|
|
|
|
|
oldlabel = olditem->getParam("label");
|
2007-05-19 19:29:50 +00:00
|
|
|
|
erasedInsetPosition = it->pos;
|
|
|
|
|
eraseChar(erasedInsetPosition, track_changes);
|
|
|
|
|
break;
|
2007-05-14 09:24:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-05-19 19:29:50 +00:00
|
|
|
|
//There was an InsetBibitem at the beginning, and we didn't
|
|
|
|
|
//have to erase one.
|
|
|
|
|
if (hasbibitem && erasedInsetPosition < 0)
|
|
|
|
|
return 0;
|
2007-05-28 22:27:45 +00:00
|
|
|
|
|
|
|
|
|
//There was an InsetBibitem at the beginning and we did have to
|
2007-05-19 19:29:50 +00:00
|
|
|
|
//erase one. So we give its properties to the beginning inset.
|
|
|
|
|
if (hasbibitem) {
|
2007-05-28 22:27:45 +00:00
|
|
|
|
InsetBibitem * inset =
|
2007-05-19 19:29:50 +00:00
|
|
|
|
static_cast<InsetBibitem *>(insetlist.begin()->inset);
|
|
|
|
|
if (!oldkey.empty())
|
|
|
|
|
inset->setParam("key", oldkey);
|
|
|
|
|
inset->setParam("label", oldlabel);
|
|
|
|
|
return -erasedInsetPosition;
|
|
|
|
|
}
|
2007-05-28 22:27:45 +00:00
|
|
|
|
|
2007-05-19 19:29:50 +00:00
|
|
|
|
//There was no inset at the beginning, so we need to create one with
|
|
|
|
|
//the key and label of the one we erased.
|
2006-12-29 23:54:48 +00:00
|
|
|
|
InsetBibitem * inset(new InsetBibitem(InsetCommandParams("bibitem")));
|
2007-05-14 09:24:17 +00:00
|
|
|
|
// restore values of previously deleted item in this par.
|
|
|
|
|
if (!oldkey.empty())
|
|
|
|
|
inset->setParam("key", oldkey);
|
2007-05-19 19:29:50 +00:00
|
|
|
|
inset->setParam("label", oldlabel);
|
2007-04-29 13:39:47 +00:00
|
|
|
|
insertInset(0, static_cast<Inset *>(inset),
|
2007-05-14 09:24:17 +00:00
|
|
|
|
Change(track_changes ? Change::INSERTED : Change::UNCHANGED));
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-05-19 19:29:50 +00:00
|
|
|
|
return 1;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-09 20:52:34 +00:00
|
|
|
|
|
|
|
|
|
void Paragraph::checkAuthors(AuthorList const & authorList)
|
|
|
|
|
{
|
|
|
|
|
pimpl_->changes_.checkAuthors(authorList);
|
|
|
|
|
}
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
} // namespace lyx
|