The inset newline patch I sent plus the requisite fixes. I couldn't reproduce a problem.

JMarc, I haven't moved those latex bits into the ::latex method yet though.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6471 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
John Levon 2003-03-12 19:16:42 +00:00
parent a806376034
commit 47432f0259
23 changed files with 333 additions and 198 deletions

View File

@ -1,3 +1,18 @@
2003-03-12 John Levon <levon@movementarian.org>
* buffer.C:
* paragraph.h:
* paragraph.C:
* paragraph_funcs.C:
* paragraph_pimpl.C:
* sgml.C:
* tabular.C:
* text.C:
* text3.C: remove META_NEWLINE in favour of an inset
* rowpainter.h:
* rowpainter.C: remove paintNewline (done by inset)
2003-03-12 John Levon <levon@movementarian.org>
* paragraph_pimpl.C: complain about bad getChar()s

View File

@ -911,18 +911,6 @@ string const Buffer::asciiParagraph(Paragraph const & par,
}
break;
case Paragraph::META_NEWLINE:
if (linelen > 0) {
buffer << word << "\n";
word.erase();
pair<int, string> p = addDepth(depth,
ltype_depth);
buffer << p.second;
currlinelen = p.first;
}
break;
default:
if (c == ' ') {
if (linelen > 0 &&

View File

@ -1,3 +1,15 @@
2003-03-12 John Levon <levon@movementarian.org>
* Makefile.am:
* inset.h:
* inset.C:
* insetert.h:
* insetert.C:
* insetnewline.h:
* insetnewline.C:
* insetquotes.C:
* insettext.C: use new insetnewline
2003-03-12 John Levon <levon@movementarian.org>
* insettext.C: readToken became readParagraph

View File

@ -71,6 +71,8 @@ libinsets_la_SOURCES = \
insetmarginal.C \
insetminipage.C \
insetminipage.h \
insetnewline.C \
insetnewline.h \
insetnote.C \
insetnote.h \
insetoptarg.C \

View File

@ -125,7 +125,9 @@ public:
///
OPTARG_CODE,
///
HFILL_CODE
HFILL_CODE,
///
NEWLINE_CODE
};
///

View File

@ -208,11 +208,14 @@ void InsetERT::write(Buffer const * buf, ostream & os) const
Paragraph::value_type c = par->getChar(i);
switch (c) {
case Paragraph::META_INSET:
lyxerr << "Element is not allowed in insertERT"
<< endl;
case Paragraph::META_NEWLINE:
os << "\n\\newline \n";
if (par->getInset(i)->lyxCode() != Inset::NEWLINE_CODE) {
lyxerr << "Element is not allowed in insertERT"
<< endl;
} else {
par->getInset(i)->write(buf, os);
}
break;
case '\\':
os << "\n\\backslash \n";
break;
@ -353,15 +356,11 @@ int InsetERT::latex(Buffer const *, ostream & os, bool /*fragile*/,
if (isDeletedText(*par, i))
continue;
Paragraph::value_type c = par->getChar(i);
switch (c) {
case Paragraph::META_NEWLINE:
if (par->isNewline(i)) {
os << '\n';
++lines;
break;
default:
os << c;
break;
} else {
os << par->getChar(i);
}
}
par = par->next();
@ -388,15 +387,11 @@ int InsetERT::linuxdoc(Buffer const *, ostream & os) const
while (par) {
pos_type siz = par->size();
for (pos_type i = 0; i < siz; ++i) {
Paragraph::value_type c = par->getChar(i);
switch (c) {
case Paragraph::META_NEWLINE:
if (par->isNewline(i)) {
os << '\n';
++lines;
break;
default:
os << c;
break;
} else {
os << par->getChar(i);
}
}
par = par->next();
@ -417,15 +412,11 @@ int InsetERT::docbook(Buffer const *, ostream & os, bool) const
while (par) {
pos_type siz = par->size();
for (pos_type i = 0; i < siz; ++i) {
Paragraph::value_type c = par->getChar(i);
switch (c) {
case Paragraph::META_NEWLINE:
if (par->isNewline(i)) {
os << '\n';
++lines;
break;
default:
os << c;
break;
} else {
os << par->getChar(i);
}
}
par = par->next();

View File

@ -57,7 +57,7 @@ public:
///
bool insertInset(BufferView *, Inset *);
///
bool insetAllowed(Inset::Code) const { return false; }
bool insetAllowed(Inset::Code code) const { return code == Inset::NEWLINE_CODE; }
///
void setFont(BufferView *, LyXFont const &,
bool toggleall = false, bool selectall = false);

139
src/insets/insetnewline.C Normal file
View File

@ -0,0 +1,139 @@
/**
* \file insetnewline.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author John Levon
*
* Full author contact details are available in file CREDITS
*/
#include <config.h>
#include "BufferView.h"
#include "paragraph.h"
#include "lyxtext.h"
#include "insetnewline.h"
#include "support/LOstream.h"
#include "frontends/Painter.h"
#include "frontends/font_metrics.h"
#include "debug.h"
using std::ostream;
using std::endl;
InsetNewline::InsetNewline()
: Inset()
{}
void InsetNewline::read(Buffer const *, LyXLex &)
{
/* Nothing to read */
}
void InsetNewline::write(Buffer const *, ostream & os) const
{
os << "\n\\newline \n";
}
int InsetNewline::ascent(BufferView *, LyXFont const & font) const
{
return font_metrics::maxAscent(font);
}
int InsetNewline::descent(BufferView *, LyXFont const & font) const
{
return font_metrics::maxDescent(font);
}
int InsetNewline::width(BufferView *, LyXFont const & font) const
{
return font_metrics::width('n', font);
}
int InsetNewline::latex(Buffer const *, ostream &, bool, bool) const
{
lyxerr << "Eek, calling InsetNewline::latex !" << endl;
return 0;
}
int InsetNewline::ascii(Buffer const *, ostream & os, int) const
{
os << '\n';
return 0;
}
int InsetNewline::linuxdoc(Buffer const *, std::ostream &) const
{
/* FIXME */
return 0;
}
int InsetNewline::docbook(Buffer const *, std::ostream &, bool) const
{
/* FIXME */
return 0;
}
void InsetNewline::draw(BufferView * bv, LyXFont const & font,
int baseline, float & x, bool) const
{
Painter & pain(bv->painter());
int const wid = font_metrics::width('n', font);
int const asc = font_metrics::maxAscent(font);
int const y = baseline;
// hack, and highly dubious
lyx::pos_type pos = parOwner()->getPositionOfInset(this);
bool const ltr_pos = (bv->text->bidi_level(pos) % 2 == 0);
int xp[3];
int yp[3];
yp[0] = int(y - 0.875 * asc * 0.75);
yp[1] = int(y - 0.500 * asc * 0.75);
yp[2] = int(y - 0.125 * asc * 0.75);
if (ltr_pos) {
xp[0] = int(x + wid * 0.375);
xp[1] = int(x);
xp[2] = int(x + wid * 0.375);
} else {
xp[0] = int(x + wid * 0.625);
xp[1] = int(x + wid);
xp[2] = int(x + wid * 0.625);
}
pain.lines(xp, yp, 3, LColor::eolmarker);
yp[0] = int(y - 0.500 * asc * 0.75);
yp[1] = int(y - 0.500 * asc * 0.75);
yp[2] = int(y - asc * 0.75);
if (ltr_pos) {
xp[0] = int(x);
xp[1] = int(x + wid);
xp[2] = int(x + wid);
} else {
xp[0] = int(x + wid);
xp[1] = int(x);
xp[2] = int(x);
}
pain.lines(xp, yp, 3, LColor::eolmarker);
x += wid;
}

53
src/insets/insetnewline.h Normal file
View File

@ -0,0 +1,53 @@
// -*- C++ -*-
/**
* \file insetnewline.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author John Levon
*
* Full author contact details are available in file CREDITS
*/
#ifndef INSET_NEWLINE_H
#define INSET_NEWLINE_H
#include "inset.h"
class InsetNewline : public Inset {
public:
InsetNewline();
virtual Inset * clone(Buffer const &, bool = false) const {
return new InsetNewline;
}
Inset::Code lyxCode() const { return Inset::NEWLINE_CODE; }
virtual int ascent(BufferView *, LyXFont const &) const;
virtual int descent(BufferView *, LyXFont const &) const;
virtual int width(BufferView *, LyXFont const &) const;
virtual void draw(BufferView *, LyXFont const &,
int baseline, float & x, bool cleared) const;
virtual int latex(Buffer const *, std::ostream &, bool fragile, bool free_spc) const;
virtual int ascii(Buffer const *, std::ostream &, int linelen) const;
virtual int linuxdoc(Buffer const *, std::ostream &) const;
virtual int docbook(Buffer const *, std::ostream &, bool) const;
virtual void read(Buffer const *, LyXLex & lex);
virtual void write(Buffer const * buf, std::ostream & os) const;
/// We don't need \begin_inset and \end_inset
virtual bool directWrite() const { return true; }
};
#endif // INSET_NEWLINE_H

View File

@ -86,8 +86,9 @@ InsetQuotes::InsetQuotes(char c, BufferParams const & params)
// Decide whether left or right
switch (c) {
case ' ': case '(':
#warning eh ? I am lost here ...
//case Paragraph::META_HFILL:
case Paragraph::META_NEWLINE:
// case Paragraph::META_NEWLINE:
side_ = LeftQ; // left quote
break;
default:

View File

@ -37,6 +37,7 @@
#include "paragraph_funcs.h"
#include "sgml.h"
#include "rowpainter.h"
#include "insetnewline.h"
#include "frontends/Alert.h"
#include "frontends/Dialogs.h"
@ -1468,7 +1469,7 @@ Inset::RESULT InsetText::localDispatch(FuncRequest const & ev)
setUndo(bv, Undo::INSERT,
lt->cursor.par(), lt->cursor.par()->next());
#endif
lt->insertChar(bv, Paragraph::META_NEWLINE);
lt->insertInset(bv, new InsetNewline);
updwhat = CURSOR | CURSOR_PAR;
updflag = true;
}
@ -2442,7 +2443,7 @@ void InsetText::removeNewlines()
ParagraphList::iterator end = paragraphs.end();
for (; it != end; ++it) {
for (int i = 0; i < it->size(); ++i) {
if (it->getChar(i) == Paragraph::META_NEWLINE) {
if (it->isNewline(i)) {
changed = true;
it->erase(i);
}

View File

@ -209,10 +209,6 @@ void Paragraph::write(Buffer const * buf, ostream & os,
}
}
break;
case META_NEWLINE:
os << "\n\\newline \n";
column = 0;
break;
case '\\':
os << "\n\\backslash \n";
column = 0;
@ -787,19 +783,22 @@ int Paragraph::beginningOfBody() const
// and remember the previous character to
// remove unnecessary GetChar() calls
pos_type i = 0;
if (i < size() && getChar(i) != Paragraph::META_NEWLINE) {
if (i < size() && !isNewline(i)) {
++i;
char previous_char = 0;
char temp = 0;
if (i < size()
&& (previous_char = getChar(i)) != Paragraph::META_NEWLINE) {
// Yes, this ^ is supposed to be "= " not "=="
++i;
while (i < size()
&& previous_char != ' '
&& (temp = getChar(i)) != Paragraph::META_NEWLINE) {
if (i < size()) {
previous_char = getChar(i);
if (!isNewline(i)) {
++i;
previous_char = temp;
while (i < size() && previous_char != ' ') {
temp = getChar(i);
if (isNewline(i))
break;
++i;
previous_char = temp;
}
}
}
}
@ -1150,38 +1149,12 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf,
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().
if (!style->newline_allowed) {
os << '\n';
} else {
if (open_font) {
column += running_font.latexWriteEndChanges(os, basefont, basefont);
open_font = false;
}
basefont = getLayoutFont(bparams);
running_font = basefont;
if (font.family() ==
LyXFont::TYPEWRITER_FAMILY) {
os << '~';
}
if (moving_arg)
os << "\\protect ";
os << "\\\\\n";
}
texrow.newline();
texrow.start(this, i + 1);
column = 0;
} else {
pimpl_->simpleTeXSpecialChars(buf, bparams,
os, texrow, moving_arg,
font, running_font,
basefont, open_font,
running_change,
*style, i, column, c);
}
pimpl_->simpleTeXSpecialChars(buf, bparams,
os, texrow, moving_arg,
font, running_font,
basefont, open_font,
running_change,
*style, i, column, c);
}
column += Changes::latexMarkChange(os,
@ -1229,7 +1202,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const * buf,
bool Paragraph::isHfill(pos_type pos) const
{
return IsInsetChar(getChar(pos))
&& getInset(pos)->lyxCode() == Inset::HFILL_CODE;
&& getInset(pos)->lyxCode() == Inset::HFILL_CODE;
}
@ -1241,7 +1214,8 @@ bool Paragraph::isInset(pos_type pos) const
bool Paragraph::isNewline(pos_type pos) const
{
return pos >= 0 && IsNewlineChar(getChar(pos));
return IsInsetChar(getChar(pos))
&& getInset(pos)->lyxCode() == Inset::NEWLINE_CODE;
}
@ -1371,8 +1345,6 @@ string const Paragraph::asString(Buffer const * buffer,
value_type const c = getUChar(buffer->params, i);
if (IsPrintable(c))
os << c;
else if (c == META_NEWLINE)
os << '\n';
else if (c == META_INSET)
getInset(i)->ascii(buffer, os);
}

View File

@ -39,10 +39,12 @@ class Paragraph {
public:
///
enum META_KIND {
///
META_NEWLINE = 2,
///
META_INSET
/// Note that this is 1 right now to avoid
/// crashes where getChar() is called wrongly
/// (returning 0) - if this was 0, then we'd
/// try getInset() and crash. We should fix
/// all these places.
META_INSET = 1
};
///
typedef char value_type;

View File

@ -32,6 +32,7 @@
#include "insets/insettabular.h"
#include "insets/insethfill.h"
#include "insets/inseterror.h"
#include "insets/insetnewline.h"
extern string bibitemWidest(Buffer const *);
@ -916,9 +917,10 @@ int readParToken(Buffer & buf, Paragraph & par, LyXLex & lex, string const & tok
par.insertInset(par.size(), inset, font, change);
} else if (token == "\\backslash") {
par.insertChar(par.size(), '\\', font, change);
// do not delete this token, it is still needed!
} else if (token == "\\newline") {
par.insertChar(par.size(), Paragraph::META_NEWLINE, font, change);
Inset * inset = new InsetNewline;
inset->read(&buf, lex);
par.insertInset(par.size(), inset, font, change);
} else if (token == "\\LyXTable") {
Inset * inset = new InsetTabular(buf);
inset->read(&buf, lex);

View File

@ -517,6 +517,34 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const * buf,
if (!inset)
break;
// FIXME: move this to InsetNewline::latex
if (inset->lyxCode() == Inset::NEWLINE_CODE) {
// newlines are handled differently here than
// the default in simpleTeXSpecialChars().
if (!style.newline_allowed) {
os << '\n';
} else {
if (open_font) {
column += running_font.latexWriteEndChanges(os, basefont, basefont);
open_font = false;
}
basefont = owner_->getLayoutFont(bparams);
running_font = basefont;
if (font.family() == LyXFont::TYPEWRITER_FAMILY)
os << '~';
if (moving_arg)
os << "\\protect ";
os << "\\\\\n";
}
texrow.newline();
texrow.start(owner_, i + 1);
column = 0;
break;
}
if (inset->isTextInset()) {
column += Changes::latexMarkChange(os, running_change,
Change::UNCHANGED);
@ -569,17 +597,6 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const * buf,
}
break;
case Paragraph::META_NEWLINE:
if (open_font) {
column += running_font.latexWriteEndChanges(os,
basefont,
basefont);
open_font = false;
}
basefont = owner_->getLayoutFont(bparams);
running_font = basefont;
break;
default:
// And now for the special cases within each mode

View File

@ -105,53 +105,6 @@ int RowPainter::leftMargin() const
}
void RowPainter::paintNewline(pos_type const pos)
{
LyXFont const font = getFont(pos);
int const wid = font_metrics::width('n', font);
int const asc = font_metrics::maxAscent(font);
int const y = yo_ + row_.baseline();
// FIXME: rtl_pos, or ltr_pos ?
bool const rtl_pos = (text_.bidi_level(pos) % 2 == 0);
int xp[3];
int yp[3];
yp[0] = int(y - 0.875 * asc * 0.75);
yp[1] = int(y - 0.500 * asc * 0.75);
yp[2] = int(y - 0.125 * asc * 0.75);
if (rtl_pos) {
xp[0] = int(x_ + wid * 0.375);
xp[1] = int(x_);
xp[2] = int(x_ + wid * 0.375);
} else {
xp[0] = int(x_ + wid * 0.625);
xp[1] = int(x_ + wid);
xp[2] = int(x_ + wid * 0.625);
}
pain_.lines(xp, yp, 3, LColor::eolmarker);
yp[0] = int(y - 0.500 * asc * 0.75);
yp[1] = int(y - 0.500 * asc * 0.75);
yp[2] = int(y - asc * 0.75);
if (rtl_pos) {
xp[0] = int(x_);
xp[1] = int(x_ + wid);
xp[2] = int(x_ + wid);
} else {
xp[0] = int(x_ + wid);
xp[1] = int(x_);
xp[2] = int(x_);
}
pain_.lines(xp, yp, 3, LColor::eolmarker);
x_ += wid;
}
bool RowPainter::paintInset(pos_type const pos)
{
Inset * inset = const_cast<Inset*>(par_.getInset(pos));
@ -318,11 +271,7 @@ bool RowPainter::paintFromPos(pos_type & vpos)
char const c = par_.getChar(pos);
if (IsNewlineChar(c)) {
++vpos;
paintNewline(pos);
return true;
} else if (IsInsetChar(c)) {
if (IsInsetChar(c)) {
if (paintInset(pos))
return true;
++vpos;

View File

@ -45,7 +45,6 @@ private:
void paintChangeBar();
void paintFirst();
void paintLast();
void paintNewline(lyx::pos_type const pos);
void paintForeignMark(float const orig_x, LyXFont const & orig_font);
void paintHebrewComposeChar(lyx::pos_type & vpos);
void paintArabicComposeChar(lyx::pos_type & vpos);

View File

@ -26,9 +26,6 @@ pair<bool, string> escapeChar(char c)
string str;
switch (c) {
case Paragraph::META_NEWLINE:
str = '\n';
break;
case ' ':
return make_pair(true, string(" "));
break;

View File

@ -1,3 +1,7 @@
2003-03-12 John Levon <levon@movementarian.org>
* textutils.h: remove META_NEWLINE
2003-02-27 Ling Li <ling@caltech.edu>
* lyxalgo.h (eliminate_duplicates): re-written to avoid the initial

View File

@ -15,14 +15,6 @@
#ifndef TEXTUTILS_H
#define TEXTUTILS_H
/// return true if the char is a meta-character newline
inline
bool IsNewlineChar(char c)
{
return (c == Paragraph::META_NEWLINE);
}
/// return true if the char is a word separator
inline
bool IsSeparatorChar(char c)
@ -74,7 +66,6 @@ bool IsKommaChar(char c)
|| c == '^'
|| c == '/'
|| c == '\\'
|| c == Paragraph::META_NEWLINE
);
}

View File

@ -2766,7 +2766,7 @@ LyXTabular::BoxType LyXTabular::UseParbox(int cell) const
for (; cit != end; ++cit) {
for (int i = 0; i < cit->size(); ++i) {
if (cit->getChar(i) == Paragraph::META_NEWLINE)
if (cit->isNewline(i))
return BOX_PARBOX;
}
}

View File

@ -254,8 +254,6 @@ int LyXText::singleWidth(BufferView * bview, Paragraph * par,
if (IsSeparatorChar(c))
c = ' ';
else if (IsNewlineChar(c))
c = 'n';
return font_metrics::width(c, font);
}
@ -739,13 +737,13 @@ LyXText::rowBreakPoint(BufferView & bv, Row const & row) const
for (i = pos; i < last; ++i) {
char const c = par->getChar(i);
if (IsNewlineChar(c)) {
if (par->isNewline(i)) {
point = i;
break;
}
char const c = par->getChar(i);
int thiswidth = singleWidth(&bv, par, i, c);
// add the auto-hfill from label end to the body
@ -1594,21 +1592,8 @@ void LyXText::insertChar(BufferView * bview, char c)
charInserted();
return;
}
} else if (IsNewlineChar(c)) {
if (cursor.pos() <= cursor.par()->beginningOfBody()) {
charInserted();
return;
}
// No newline at first position of a paragraph or behind labels.
// TeX does not allow that
if (cursor.pos() < cursor.par()->size() &&
cursor.par()->isLineSeparator(cursor.pos()))
// newline always after a blank!
cursorRight(bview);
cursor.row()->fill(-1); // to force a new break
}
// the display inset stuff
if (cursor.row()->par()->isInset(cursor.row()->pos())) {
Inset * inset = cursor.row()->par()->getInset(cursor.row()->pos());
@ -1959,7 +1944,8 @@ void LyXText::cursorLeftOneWord(LyXCursor & cur) const
cur = cursor;
while (cur.pos()
&& (cur.par()->isSeparator(cur.pos() - 1)
|| cur.par()->isKomma(cur.pos() - 1))
|| cur.par()->isKomma(cur.pos() - 1)
|| cur.par()->isNewline(cur.pos() - 1))
&& !(cur.par()->isHfill(cur.pos() - 1)
|| cur.par()->isInset(cur.pos() - 1)))
cur.pos(cur.pos() - 1);
@ -1993,8 +1979,10 @@ void LyXText::getWord(LyXCursor & from, LyXCursor & to,
if (cursor.pos() == 0 || cursor.pos() == cursor.par()->size()
|| cursor.par()->isSeparator(cursor.pos())
|| cursor.par()->isKomma(cursor.pos())
|| cursor.par()->isNewline(cursor.pos())
|| cursor.par()->isSeparator(cursor.pos() - 1)
|| cursor.par()->isKomma(cursor.pos() - 1)) {
|| cursor.par()->isKomma(cursor.pos() - 1)
|| cursor.par()->isNewline(cursor.pos() - 1)) {
to = from;
return;
}
@ -2003,7 +1991,8 @@ void LyXText::getWord(LyXCursor & from, LyXCursor & to,
case WHOLE_WORD:
// Move cursor to the beginning, when not already there.
if (from.pos() && !from.par()->isSeparator(from.pos() - 1)
&& !from.par()->isKomma(from.pos() - 1))
&& !(from.par()->isKomma(from.pos() - 1)
|| from.par()->isNewline(from.pos() - 1)))
cursorLeftOneWord(from);
break;
case PREVIOUS_WORD:
@ -2020,6 +2009,7 @@ void LyXText::getWord(LyXCursor & from, LyXCursor & to,
while (to.pos() < to.par()->size()
&& !to.par()->isSeparator(to.pos())
&& !to.par()->isKomma(to.pos())
&& !to.par()->isNewline(to.pos())
&& !to.par()->isHfill(to.pos())
&& !to.par()->isInset(to.pos()))
{

View File

@ -33,6 +33,7 @@
#include "insets/insettext.h"
#include "insets/insetquotes.h"
#include "insets/insetcommand.h"
#include "insets/insetnewline.h"
#include "undo_funcs.h"
#include <ctime>
@ -716,13 +717,20 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
finishChange(bv, false);
break;
case LFUN_BREAKLINE:
case LFUN_BREAKLINE: {
lyx::pos_type body = cursor.par()->beginningOfBody();
// Not allowed by LaTeX (labels or empty par)
if (cursor.pos() <= body)
break;
bv->beforeChange(this);
insertChar(bv, Paragraph::META_NEWLINE);
insertInset(bv, new InsetNewline);
update(bv, true);
setCursor(bv, cursor.par(), cursor.pos());
moveCursorUpdate(bv, false);
break;
}
case LFUN_DELETE:
if (!selection.set()) {