#include <config.h>
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
#include "paragraph.h"
#include "paragraph_pimpl.h"
#include "lyxrc.h"
#include "encoding.h"
#include "ParameterStruct.h"
#include "gettext.h"
+#include "changes.h"
-#include "insets/insetinclude.h"
#include "insets/insetbib.h"
-#include "insets/insettext.h"
+#include "insets/insetoptarg.h"
#include "support/filetools.h"
#include "support/lstrings.h"
#include <algorithm>
#include <fstream>
#include <csignal>
+#include <ctime>
using std::ostream;
using std::endl;
using std::ios;
using std::lower_bound;
using std::upper_bound;
-using std::reverse;
using lyx::pos_type;
void Paragraph::write(Buffer const * buf, ostream & os,
BufferParams const & bparams,
- depth_type dth) const
+ depth_type & dth) const
{
// The beginning or end of a deeper (i.e. nested) area?
if (dth != params().depth()) {
}
// First write the layout
- os << "\n\\layout " << layout()->name() << "\n";
+ os << "\n\\layout " << layout()->name() << '\n';
// Maybe some vertical spaces.
if (params().spaceTop().kind() != VSpace::NONE)
os << "\\added_space_top "
- << params().spaceTop().asLyXCommand() << " ";
+ << params().spaceTop().asLyXCommand() << ' ';
if (params().spaceBottom().kind() != VSpace::NONE)
os << "\\added_space_bottom "
- << params().spaceBottom().asLyXCommand() << " ";
+ << params().spaceBottom().asLyXCommand() << ' ';
// Maybe the paragraph has special spacing
params().spacing().writeFile(os, true);
// Do we have a manual left indent?
if (!params().leftIndent().zero())
- os << "\\leftindent " << params().leftIndent().asString() << " ";
+ os << "\\leftindent " << params().leftIndent().asString()
+ << ' ';
// Alignment?
if (params().align() != LYX_ALIGN_LAYOUT) {
case LYX_ALIGN_CENTER: h = 3; break;
default: h = 0; break;
}
- os << "\\align " << string_align[h] << " ";
+ os << "\\align " << string_align[h] << ' ';
}
// bibitem ale970302
LyXFont font1(LyXFont::ALL_INHERIT, bparams.language);
+ Change running_change = Change(Change::UNCHANGED);
+ lyx::time_type const curtime(lyx::current_time());
+
int column = 0;
for (pos_type i = 0; i < size(); ++i) {
if (!i) {
- os << "\n";
+ os << '\n';
column = 0;
}
+ Change change = pimpl_->lookupChangeFull(i);
+ Changes::lyxMarkChange(os, column, curtime, running_change, change);
+ running_change = change;
+
// Write font changes
LyXFont font2 = getFontSettings(bparams, i);
if (font2 != font1) {
-#ifndef INHERIT_LANGUAGE
font2.lyxWriteChanges(font1, os);
-#else
- font2.lyxWriteChanges(font1, bparams.language, os);
-#endif
column = 0;
font1 = font2;
}
os << ".\n";
column = 0;
} else
- os << ".";
+ os << '.';
break;
default:
if ((column > 70 && c == ' ')
|| column > 79) {
- os << "\n";
+ os << '\n';
column = 0;
}
// this check is to amend a bug. LyX sometimes
break;
}
}
+
+ // to make reading work properly
+ if (!size()) {
+ running_change = pimpl_->lookupChange(0);
+ Changes::lyxMarkChange(os, column, curtime,
+ Change(Change::UNCHANGED), running_change);
+ }
+ Changes::lyxMarkChange(os, column, curtime,
+ running_change, Change(Change::UNCHANGED));
}
}
+bool Paragraph::erase(pos_type start, pos_type end)
+{
+ return pimpl_->erase(start, end);
+}
+
+
bool Paragraph::checkInsertChar(LyXFont & font)
{
if (pimpl_->inset_owner)
void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
- LyXFont const & font)
+ LyXFont const & font, Change change)
{
- pimpl_->insertChar(pos, c, font);
+ pimpl_->insertChar(pos, c, font, change);
}
}
-void Paragraph::insertInset(pos_type pos, Inset * inset, LyXFont const & font)
+void Paragraph::insertInset(pos_type pos, Inset * inset, LyXFont const & font, Change change)
{
- pimpl_->insertInset(pos, inset, font);
+ pimpl_->insertInset(pos, inset, font, change);
}
retfont = getFontSettings(bparams, pos - 1);
} else
retfont = LyXFont(LyXFont::ALL_INHERIT, getParLanguage(bparams));
-#ifdef INHERIT_LANGUAGE
- if (retfont.language() == inherit_language)
- retfont.setLanguage(bparams.language);
-#endif
return retfont;
}
LyXLayout_ptr const & lout = layout();
- pos_type main_body = 0;
- if (lout->labeltype == LABEL_MANUAL)
- main_body = beginningOfMainBody();
+ pos_type const main_body = beginningOfMainBody();
LyXFont layoutfont;
if (pos < main_body)
layoutfont = lout->font;
LyXFont tmpfont = getFontSettings(bparams, pos);
-#ifndef INHERIT_LANGUAGE
tmpfont.realize(layoutfont);
-#else
- tmpfont.realize(layoutfont, bparams.language);
-#endif
return pimpl_->realizeFont(tmpfont, bparams);
}
int i = 0;
while (!empty() && (isNewline(0) || isLineSeparator(0))) {
- erase(0);
+ pimpl_->eraseIntern(0);
++i;
}
}
-// Be carefull, this does not make any check at all.
-// This method has wrong name, it combined this par with the next par.
-// In that sense it is the reverse of break paragraph. (Lgb)
-void Paragraph::pasteParagraph(BufferParams const & bparams)
-{
- // copy the next paragraph to this one
- Paragraph * the_next = next();
-
- // first the DTP-stuff
- params().lineBottom(the_next->params().lineBottom());
- params().spaceBottom(the_next->params().spaceBottom());
- params().pagebreakBottom(the_next->params().pagebreakBottom());
-
- pos_type pos_end = the_next->pimpl_->size() - 1;
- pos_type pos_insert = size();
-
- // ok, now copy the paragraph
- for (pos_type i = 0, j = 0; i <= pos_end; ++i) {
- the_next->cutIntoMinibuffer(bparams, i);
- if (insertFromMinibuffer(pos_insert + j))
- ++j;
- }
-
- // delete the next paragraph
- Paragraph * ppar = the_next->previous_;
- Paragraph * npar = the_next->next_;
- delete the_next;
- ppar->next(npar);
-}
-
-
int Paragraph::getEndLabel() const
{
Paragraph const * par = this;
int Paragraph::beginningOfMainBody() const
{
+ if (layout()->labeltype != LABEL_MANUAL)
+ return 0;
+
// Unroll the first two cycles of the loop
// and remember the previous character to
// remove unnecessary GetChar() calls
return -1;
}
+namespace {
+
+InsetOptArg * optArgInset(Paragraph const & par)
+{
+ // Find the entry.
+ InsetList::iterator it = par.insetlist.begin();
+ InsetList::iterator end = par.insetlist.end();
+ for (; it != end; ++it) {
+ Inset * ins = it.getInset();
+ if (ins->lyxCode() == Inset::OPTARG_CODE) {
+ return static_cast<InsetOptArg *>(ins);
+ }
+ }
+ return 0;
+}
+
+} // end namespace
Paragraph * Paragraph::TeXOnePar(Buffer const * buf,
BufferParams const & bparams,
if (!params().spacing().isDefault()
&& (!previous() || !previous()->hasSameLayout(this))) {
- os << params().spacing().writeEnvirBegin() << "\n";
+ os << params().spacing().writeEnvirBegin() << '\n';
texrow.newline();
}
if (language->babel() != previous_language->babel()
// check if we already put language command in TeXEnvironment()
&& !(style->isEnvironment()
- && (!previous() || previous()->layout() != layout() ||
- previous()->params().depth() != params().depth())))
+ && (!previous() ||
+ (previous()->layout() != layout() &&
+ previous()->getDepth() <= getDepth())
+ || previous()->getDepth() < getDepth())))
{
if (!lyxrc.language_command_end.empty() &&
previous_language->babel() != doc_language->babel())
language->encoding() != previous_language->encoding()) {
os << "\\inputencoding{"
<< language->encoding()->LatexName()
- << "}" << endl;
+ << "}\n";
texrow.newline();
}
switch (style->latextype) {
case LATEX_COMMAND:
os << '\\'
- << style->latexname()
- << style->latexparam();
+ << style->latexname();
+
+ // Separate handling of optional argument inset.
+ if (style->optionalargs == 1) {
+ InsetOptArg * it = optArgInset(*this);
+ if (it != 0)
+ it->latexOptional(buf, os, false, false);
+ }
+ else
+ os << style->latexparam();
break;
case LATEX_ITEM_ENVIRONMENT:
if (bibkey) {
if (style->resfont.size() != font.size() && next_ && !is_command) {
if (!need_par)
- os << "{";
+ os << '{';
os << "\\" << font.latexSize() << " \\par}";
} else if (need_par) {
os << "\\par}";
} else if (is_command)
- os << "}";
+ os << '}';
switch (style->latextype) {
case LATEX_ITEM_ENVIRONMENT:
if (!params().spacing().isDefault()
&& (!next_ || !next_->hasSameLayout(this))) {
- os << params().spacing().writeEnvirEnd() << "\n";
+ os << params().spacing().writeEnvirEnd() << '\n';
texrow.newline();
}
}
// Maybe we have to create a optional argument.
pos_type main_body;
- if (style->labeltype != LABEL_MANUAL)
+
+ // FIXME: can we actually skip this check and just call
+ // beginningOfMainBody() ??
+ if (style->labeltype != LABEL_MANUAL) {
main_body = 0;
- else
+ } else {
main_body = beginningOfMainBody();
+ }
- int column = 0;
+ unsigned int column = 0;
if (main_body > 0) {
os << '[';
// Do we have an open font change?
bool open_font = false;
+ Change::Type running_change = Change::UNCHANGED;
+
texrow.start(this, 0);
// if the paragraph is empty, the loop will not be entered at all
running_font = font;
open_font = true;
}
-
+
+ Change::Type change = pimpl_->lookupChange(i);
+
+ column += Changes::latexMarkChange(os, running_change, change);
+ running_change = change;
+
if (c == Paragraph::META_NEWLINE) {
// newlines are handled differently here than
// the default in SimpleTeXSpecialChars().
running_font = basefont;
if (font.family() ==
LyXFont::TYPEWRITER_FAMILY) {
- os << "~";
+ os << '~';
}
if (moving_arg)
os << "\\protect ";
os, texrow, moving_arg,
font, running_font,
basefont, open_font,
+ running_change,
*style, i, column, c);
}
}
+ column += Changes::latexMarkChange(os,
+ running_change, Change::UNCHANGED);
+
// If we have an open font definition, we have to close it
if (open_font) {
#ifdef FIXED_LANGUAGE_END_DETECTION
Paragraph::getParLanguage(BufferParams const & bparams) const
{
if (!empty()) {
-#ifndef INHERIT_LANGUAGE
return getFirstFontSettings().language();
-#else
- Language const * lang = getFirstFontSettings().language();
-#ifdef WITH_WARNINGS
-#warning We should make this somewhat better, any ideas? (Jug)
-#endif
- if (lang == inherit_language || lang == ignore_language)
- lang = bparams.language;
- return lang;
-#endif
} else if (previous_)
return previous_->getParLanguage(bparams);
else
for (; cit != end; ++cit)
if (cit->font().language() != ignore_language &&
cit->font().language() != latex_language &&
-#ifdef INHERIT_LANGUAGE
- cit->font().language() != inherit_language &&
-#endif
cit->font().language() != doc_language)
return true;
return false;
// Convert the paragraph to a string.
// Used for building the table of contents
-string const Paragraph::asString(Buffer const * buffer, bool label)
+string const Paragraph::asString(Buffer const * buffer, bool label) const
{
- BufferParams const & bparams = buffer->params;
string s;
if (label && !params().labelString().empty())
s += params().labelString() + ' ';
- string::size_type const len = s.size();
for (pos_type i = 0; i < size(); ++i) {
value_type c = getChar(i);
getInset(i)->lyxCode() == Inset::MATH_CODE) {
ostringstream ost;
getInset(i)->ascii(buffer, ost);
- s += subst(ost.str().c_str(),'\n',' ');
+ s += subst(STRCONV(ost.str()),'\n',' ');
}
}
- if (isRightToLeftPar(bparams))
- reverse(s.begin() + len,s.end());
-
return s;
}
string const Paragraph::asString(Buffer const * buffer,
- pos_type beg, pos_type end, bool label)
+ pos_type beg, pos_type end, bool label) const
{
ostringstream ost;
}
}
- return ost.str().c_str();
+ return STRCONV(ost.str());
}
}
+void Paragraph::trackChanges(Change::Type type)
+{
+ pimpl_->trackChanges(type);
+}
+
+
+void Paragraph::untrackChanges()
+{
+ pimpl_->untrackChanges();
+}
+
+
+void Paragraph::cleanChanges()
+{
+ pimpl_->cleanChanges();
+}
+
+
+Change::Type Paragraph::lookupChange(lyx::pos_type pos) const
+{
+ lyx::Assert(!size() || pos < size());
+ return pimpl_->lookupChange(pos);
+}
+
+
+Change const Paragraph::lookupChangeFull(lyx::pos_type pos) const
+{
+ lyx::Assert(!size() || pos < size());
+ return pimpl_->lookupChangeFull(pos);
+}
+
+
+bool Paragraph::isChanged(pos_type start, pos_type end) const
+{
+ return pimpl_->isChanged(start, end);
+}
+
+
+bool Paragraph::isChangeEdited(pos_type start, pos_type end) const
+{
+ return pimpl_->isChangeEdited(start, end);
+}
+
+
+void Paragraph::markErased()
+{
+ pimpl_->markErased();
+}
+
+
+void Paragraph::acceptChange(pos_type start, pos_type end)
+{
+ return pimpl_->acceptChange(start, end);
+}
+
+
+void Paragraph::rejectChange(pos_type start, pos_type end)
+{
+ return pimpl_->rejectChange(start, end);
+}
+
+
lyx::pos_type Paragraph::size() const
{
return pimpl_->size();