X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fparagraph.C;h=01ea6b6331c54c94b561606724c9d208548011d8;hb=d4cd63f3423e4556bba2c42dd31b44d78004d7d5;hp=2bb18268d0fb1187cde76067c496d485f5ad9d1e;hpb=e656d12d0bd2c82dfb64454fcdd0732cca6565b4;p=lyx.git diff --git a/src/paragraph.C b/src/paragraph.C index 2bb18268d0..01ea6b6331 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -4,7 +4,7 @@ * LyX, The Document Processor * * Copyright 1995 Matthias Ettrich - * Copyright 1995-1999 The LyX Team. + * Copyright 1995-2000 The LyX Team. * * ====================================================== */ @@ -14,9 +14,8 @@ #pragma implementation "lyxparagraph.h" #endif +#include #include -using std::fstream; -using std::ios; #include "lyxparagraph.h" #include "support/textutils.h" @@ -29,21 +28,28 @@ using std::ios; #include "debug.h" #include "LaTeXFeatures.h" #include "insets/insetinclude.h" +#include "insets/insetbib.h" #include "support/filetools.h" #include "lyx_gui_misc.h" #include "texrow.h" +#include "support/lyxmanip.h" +using std::ostream; +using std::endl; +using std::fstream; +using std::ios; +using std::lower_bound; +using std::upper_bound; +using std::reverse; -extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923 int tex_code_break_column = 72; // needs non-zero initialization. set later. // this is a bad idea, but how can LyXParagraph find its buffer to get // parameters? (JMarc) extern BufferView * current_view; -extern LyXRC * lyxrc; // ale970405 -extern string bibitemWidthest(); +extern string bibitemWidthest(Painter &); // this is a minibuffer static char minibuffer_char; @@ -66,19 +72,15 @@ LyXParagraph::LyXParagraph() itemdepth = 0; next = 0; previous = 0; -#ifndef NEW_FONTTABLE // OK - fonttable = 0; -#endif -#ifndef NEW_INSETTABLE - insettable = 0; -#endif footnoteflag = LyXParagraph::NO_FOOTNOTE; - + footnotekind = LyXParagraph::FOOTNOTE; // should not be needed + align = LYX_ALIGN_BLOCK; /* table stuff -- begin*/ table = 0; /* table stuff -- end*/ + inset_owner = 0; id_ = paragraph_id++; bibkey = 0; // ale970302 Clear(); @@ -95,23 +97,20 @@ LyXParagraph::LyXParagraph(LyXParagraph * par) appendix = false; enumdepth = 0; itemdepth = 0; + // double linked list begin next = par->next; if (next) next->previous = this; previous = par; previous->next = this; -#ifndef NEW_FONTTABLE // OK - fonttable = 0; -#endif -#ifndef NEW_INSETTABLE - insettable = 0; -#endif + // end footnoteflag = LyXParagraph::NO_FOOTNOTE; footnotekind = LyXParagraph::FOOTNOTE; /* table stuff -- begin*/ table = 0; /* table stuff -- end*/ + inset_owner = 0; id_ = paragraph_id++; bibkey = 0; // ale970302 @@ -120,11 +119,10 @@ LyXParagraph::LyXParagraph(LyXParagraph * par) } -void LyXParagraph::writeFile(ostream & os, BufferParams & params, - char footflag, char dth) +void LyXParagraph::writeFile(ostream & os, BufferParams const & params, + char footflag, char dth) const { LyXFont font1, font2; - Inset * inset; int column = 0; int h = 0; char c = 0; @@ -140,8 +138,7 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, os << "\n\\begin_float " << string_footnotekinds[footnotekind] << " "; - } - else { + } else { os << "\n\\end_float "; } } @@ -151,13 +148,12 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, if (depth > dth) { while (depth > dth) { os << "\n\\begin_deeper "; - dth++; + ++dth; } - } - else { + } else { while (depth < dth) { os << "\n\\end_deeper "; - dth--; + --dth; } } } @@ -174,7 +170,10 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, if (added_space_bottom.kind() != VSpace::NONE) os << "\\added_space_bottom " << added_space_bottom.asLyXCommand() << " "; - + + // Maybe the paragraph has special spacing + spacing.writeFile(os, true); + // The labelwidth string used in lists. if (!labelwidthstring.empty()) os << "\\labelwidthstring " @@ -231,8 +230,7 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, } os << '\n'; } - } - else { + } else { // Dummy layout. This means that a footnote ended. os << "\n\\end_float "; footflag = LyXParagraph::NO_FOOTNOTE; @@ -248,11 +246,11 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, if (bibkey) bibkey->Write(os); - font1 = LyXFont(LyXFont::ALL_INHERIT); + font1 = LyXFont(LyXFont::ALL_INHERIT,params.language_info); column = 0; - for (size_type i = 0; i < size(); i++) { - if (!i){ + for (size_type i = 0; i < size(); ++i) { + if (!i) { os << "\n"; column = 0; } @@ -268,7 +266,8 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, c = GetChar(i); switch (c) { case META_INSET: - inset = GetInset(i); + { + Inset const * inset = GetInset(i); if (inset) if (inset->DirectWrite()) { // international char, let it write @@ -281,7 +280,8 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, os << "\n\\end_inset \n\n"; column = 0; } - break; + } + break; case META_NEWLINE: os << "\n\\newline \n"; column = 0; @@ -290,10 +290,6 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, os << "\n\\hfill \n"; column = 0; break; - case META_PROTECTED_SEPARATOR: - os << "\n\\protected_separator \n"; - column = 0; - break; case '\\': os << "\n\\backslash \n"; column = 0; @@ -307,7 +303,7 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, break; default: if ((column > 70 && c == ' ') - || column > 79){ + || column > 79) { os << "\n"; column = 0; } @@ -318,7 +314,7 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, else lyxerr << "ERROR (LyXParagraph::writeFile):" " NULL char in structure." << endl; - column++; + ++column; break; } } @@ -329,21 +325,27 @@ void LyXParagraph::writeFile(ostream & os, BufferParams & params, } -void LyXParagraph::validate(LaTeXFeatures & features) +void LyXParagraph::validate(LaTeXFeatures & features) const { + BufferParams const & params = features.bufferParams(); + // this will be useful later - LyXLayout const & layout = textclasslist.Style(current_view->buffer()->params.textclass, - GetLayout()); + LyXLayout const & layout = + textclasslist.Style(params.textclass, + GetLayout()); // check the params. if (line_top || line_bottom) features.lyxline = true; + if (!spacing.isDefault()) + features.setspace = true; // then the layouts features.layout[GetLayout()] = true; // then the fonts -#ifdef NEW_FONTTABLE // OK, but does not affect structure anyway + Language const * doc_language = params.language_info; + for (FontList::const_iterator cit = fontlist.begin(); cit != fontlist.end(); ++cit) { if ((*cit).font.noun() == LyXFont::ON) { @@ -356,9 +358,9 @@ void LyXParagraph::validate(LaTeXFeatures & features) << endl; } switch ((*cit).font.color()) { - case LyXFont::NONE: - case LyXFont::INHERIT_COLOR: - case LyXFont::IGNORE_COLOR: + case LColor::none: + case LColor::inherit: + case LColor::ignore: break; default: features.color = true; @@ -366,49 +368,30 @@ void LyXParagraph::validate(LaTeXFeatures & features) << (*cit).font.stateText() << endl; } - } -#else - FontTable * tmpfonttable = fonttable; - while (tmpfonttable) { - if (tmpfonttable->font.noun() == LyXFont::ON) { - lyxerr[Debug::LATEX] << "font.noun: " - << tmpfonttable->font.noun() - << endl; - features.noun = true; - lyxerr[Debug::LATEX] << "Noun enabled. Font: " - << tmpfonttable->font.stateText() - << endl; +#if 0 + Language const * language = (*cit).font.language(); + if (language != doc_language) { + features.UsedLanguages.insert(language); + lyxerr[Debug::LATEX] << "Found language " + << language->lang << endl; } - switch (tmpfonttable->font.color()) { - case LyXFont::NONE: - case LyXFont::INHERIT_COLOR: - case LyXFont::IGNORE_COLOR: - break; - default: - features.color = true; - lyxerr[Debug::LATEX] << "Color enabled. Font: " - << tmpfonttable->font.stateText() - << endl; - } - tmpfonttable = tmpfonttable->next; - } #endif + } + + // This is not efficient. I plan to use the code above, after I + // change the fontlist handling. + for (size_type i = 0; i < size(); ++i) { + Language const * language = GetFontSettings(i).language(); + if (language != doc_language) + features.UsedLanguages.insert(language); + } + // then the insets -#ifdef NEW_INSETTABLE for (InsetList::const_iterator cit = insetlist.begin(); cit != insetlist.end(); ++cit) { if ((*cit).inset) (*cit).inset->Validate(features); } -#else - InsetTable * tmpinsettable = insettable; - while (tmpinsettable) { - if (tmpinsettable->inset) { - tmpinsettable->inset->Validate(features); - } - tmpinsettable = tmpinsettable->next; - } -#endif if (table && table->IsLongTable()) features.longtable = true; @@ -419,8 +402,8 @@ void LyXParagraph::validate(LaTeXFeatures & features) if (layout.needprotect && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) features.NeedLyXFootnoteCode = true; - if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) && - (pextra_type == LyXParagraph::PEXTRA_MINIPAGE)) + if (params.paragraph_separation == BufferParams::PARSEP_INDENT + && pextra_type == LyXParagraph::PEXTRA_MINIPAGE) features.NeedLyXMinipageIndent = true; if (table && table->NeedRotating()) features.rotating = true; @@ -446,6 +429,7 @@ void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const } } + void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos) { minibuffer_char = GetChar(pos); @@ -458,24 +442,11 @@ void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos) // the inset, not just a clone. Otherwise // the inset would be deleted when calling Erase(pos) // find the entry -#ifdef NEW_INSETTABLE - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).pos == pos) { - (*it).inset = 0; - break; - } - - } -#else - InsetTable * tmpi = insettable; - while (tmpi && tmpi->pos != pos) { - tmpi= tmpi->next; - } - if (tmpi) { // This should always be true. - tmpi->inset = 0; - } -#endif + InsetList::iterator it = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + if (it != insetlist.end() && (*it).pos == pos) + (*it).inset = 0; } else { minibuffer_inset = 0; minibuffer_char = ' '; @@ -488,12 +459,16 @@ void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos) } -void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos) +bool LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos) { + if ((minibuffer_char == LyXParagraph::META_INSET) && + !InsertInsetAllowed(minibuffer_inset)) + return false; InsertChar(pos, minibuffer_char); SetFont(pos, minibuffer_font); if (minibuffer_char == LyXParagraph::META_INSET) InsertInset(pos, minibuffer_inset); + return true; } // end of minibuffer @@ -510,20 +485,21 @@ void LyXParagraph::Clear() added_space_top = VSpace(VSpace::NONE); added_space_bottom = VSpace(VSpace::NONE); - + spacing.set(Spacing::Default); + align = LYX_ALIGN_LAYOUT; depth = 0; noindent = false; pextra_type = PEXTRA_NONE; - pextra_width.clear(); - pextra_widthp.clear(); + pextra_width.erase(); + pextra_widthp.erase(); pextra_alignment = MINIPAGE_ALIGN_TOP; pextra_hfill = false; pextra_start_minipage = false; - labelstring.clear(); - labelwidthstring.clear(); + labelstring.erase(); + labelwidthstring.erase(); layout = 0; bibkey = 0; @@ -539,48 +515,20 @@ LyXParagraph::~LyXParagraph() if (next) next->previous = previous; -#ifdef NEW_INSETTABLE for (InsetList::iterator it = insetlist.begin(); it != insetlist.end(); ++it) { delete (*it).inset; } -#else - InsetTable * tmpinset; - while (insettable) { - tmpinset = insettable; - insettable = insettable->next; - if (tmpinset->inset) - delete tmpinset->inset; - delete tmpinset; - if (insettable && insettable->next == insettable) { - // somehow this recursion appears occasionally - // but I can't find where. This bandaid - // helps but isn't the best fix. (ARRae) - if (insettable->inset) { - delete insettable->inset; - } - delete insettable; - break; - } - } -#endif -#ifndef NEW_FONTTABLE // OK - FontTable * tmpfont; - while (fonttable) { - tmpfont = fonttable; - fonttable = fonttable->next; - delete tmpfont; - } -#endif /* table stuff -- begin*/ - if (table) - delete table; + delete table; /* table stuff -- end*/ // ale970302 - if (bibkey) - delete bibkey; + delete bibkey; + // + //lyxerr << "LyXParagraph::paragraph_id = " + // << LyXParagraph::paragraph_id << endl; } @@ -600,36 +548,16 @@ void LyXParagraph::Erase(LyXParagraph::size_type pos) // if it is an inset, delete the inset entry if (text[pos] == LyXParagraph::META_INSET) { // find the entry -#ifdef NEW_INSETTABLE - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).pos == pos) { - delete (*it).inset; - insetlist.erase(it); - break; - } - } -#else - InsetTable *tmpi = insettable; - InsetTable *tmpi2 = tmpi; - while (tmpi && tmpi->pos != pos) { - tmpi2 = tmpi; - tmpi = tmpi->next; + InsetList::iterator it = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + if (it != insetlist.end() && (*it).pos == pos) { + delete (*it).inset; + insetlist.erase(it); } - if (tmpi) { // this should always be true - if (tmpi->inset) // delete the inset if it exists - delete tmpi->inset; - if (tmpi == insettable) - insettable = tmpi->next; - else - tmpi2->next = tmpi->next; - delete tmpi; - } -#endif } text.erase(text.begin() + pos); // Erase entries in the tables. -#ifdef NEW_FONTTABLE // Seems OK for (FontList::iterator it = fontlist.begin(); it != fontlist.end(); ++it) { if (pos >= (*it).pos && pos <= (*it).pos_end) { @@ -651,57 +579,13 @@ void LyXParagraph::Erase(LyXParagraph::size_type pos) if ((*it).pos_end >= pos) (*it).pos_end--; } -#else - int found = 0; - FontTable * tmp = fonttable; - FontTable * prev = 0; - while (tmp && !found) { - if (pos >= tmp->pos && pos <= tmp->pos_end) - found = 1; - else { - prev = tmp; - tmp = tmp->next; - } - } - - if (found && tmp->pos == tmp->pos_end) { - // if it is a multi-character font entry, we just make - // it smaller (see update below), otherwise we should - // delete it - if (prev) - prev->next = tmp->next; - else - fonttable = tmp->next; - - delete tmp; - } - // Update all other entries. - - tmp = fonttable; - while (tmp) { - if (tmp->pos > pos) - tmp->pos--; - if (tmp->pos_end >= pos) - tmp->pos_end--; - tmp = tmp->next; - } -#endif // Update the inset table. -#ifdef NEW_INSETTABLE - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).pos > pos) - (*it).pos--; - } -#else - InsetTable * tmpi = insettable; - while (tmpi) { - if (tmpi->pos > pos) - tmpi->pos--; - tmpi= tmpi->next; - } -#endif + for (InsetList::iterator it = upper_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + it != insetlist.end(); ++it) + --(*it).pos; } else { lyxerr << "ERROR (LyXParagraph::Erase): " "can't erase non-existant char." << endl; @@ -725,7 +609,6 @@ void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c) } text.insert(text.begin() + pos, c); // Update the font table. -#ifdef NEW_FONTTABLE // Seems OK for (FontList::iterator it = fontlist.begin(); it != fontlist.end(); ++it) { if ((*it).pos >= pos) @@ -733,32 +616,13 @@ void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c) if ((*it).pos_end >= pos) (*it).pos_end++; } -#else - FontTable * tmp = fonttable; - while (tmp) { - if (tmp->pos >= pos) - tmp->pos++; - if (tmp->pos_end >= pos) - tmp->pos_end++; - tmp = tmp->next; - } -#endif // Update the inset table. -#ifdef NEW_INSETTABLE - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).pos >= pos) - (*it).pos++; - } -#else - InsetTable * tmpi = insettable; - while (tmpi) { - if (tmpi->pos >= pos) - tmpi->pos++; - tmpi= tmpi->next; - } -#endif + for (InsetList::iterator it = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + it != insetlist.end(); ++it) + ++(*it).pos; } @@ -785,20 +649,27 @@ void LyXParagraph::InsertInset(LyXParagraph::size_type pos, if (inset) { // Add a new entry in the inset table. -#ifdef NEW_INSETTABLE - InsetTable tmpi; - InsetList::iterator it = - insetlist.insert(insetlist.begin(), tmpi); - (*it).inset = inset; - (*it).pos = pos; -#else - InsetTable * tmpi = new InsetTable; - tmpi->pos = pos; - tmpi->inset = inset; - tmpi->next = insettable; - insettable = tmpi; -#endif + InsetList::iterator it = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + if (it != insetlist.end() && (*it).pos == pos) + lyxerr << "ERROR (LyXParagraph::InsertInset): " + "there is an inset in position: " << pos << endl; + else + insetlist.insert(it, InsetTable(pos,inset)); + if (inset_owner) + inset->setOwner(inset_owner); + } +} + + +bool LyXParagraph::InsertInsetAllowed(Inset * inset) +{ + if (inset_owner) { + lyxerr << "CODE: << " << inset->LyxCode() << endl; + return inset_owner->InsertInsetAllowed(inset); } + return true; } @@ -817,40 +688,20 @@ Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos) return 0; } // Find the inset. -#ifdef NEW_INSETTABLE - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).pos == pos) { - return (*it).inset; - } - } + InsetList::iterator it = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + if (it != insetlist.end() && (*it).pos == pos) + return (*it).inset; + lyxerr << "ERROR (LyXParagraph::GetInset): " "Inset does not exist: " << pos << endl; - text[pos] = ' '; // WHY!!! does this set the pos to ' '???? + // text[pos] = ' '; // WHY!!! does this set the pos to ' '???? // Did this commenting out introduce a bug? So far I have not // see any, please enlighten me. (Lgb) // My guess is that since the inset does not exist, we might // as well replace it with a space to prevent craches. (Asger) return 0; -#else - InsetTable * tmpi = insettable; - - while (tmpi && tmpi->pos != pos) - tmpi = tmpi->next; - - if (tmpi) - return tmpi->inset; - else { - lyxerr << "ERROR (LyXParagraph::GetInset): " - "Inset does not exist: " << pos << endl; - text[pos] = ' '; /// WHY!!! does this set the pos to ' '???? - // Did this commenting out introduce a bug? So far I have not - // seen any, please enlighten me. (Lgb) - // My guess is that since the inset does not exist, we might - // as well replace it with a space to prevent crashes. (Asger) - return 0; - } -#endif } @@ -869,13 +720,12 @@ Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const return 0; } // Find the inset. -#ifdef NEW_INSETTABLE - for (InsetList::const_iterator cit = insetlist.begin(); - cit != insetlist.end(); ++cit) { - if ((*cit).pos == pos) { - return (*cit).inset; - } - } + InsetList::const_iterator cit = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + if (cit != insetlist.end() && (*cit).pos == pos) + return (*cit).inset; + lyxerr << "ERROR (LyXParagraph::GetInset): " "Inset does not exist: " << pos << endl; //text[pos] = ' '; // WHY!!! does this set the pos to ' '???? @@ -884,26 +734,6 @@ Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const // My guess is that since the inset does not exist, we might // as well replace it with a space to prevent craches. (Asger) return 0; -#else - InsetTable * tmpi = insettable; - - while (tmpi && tmpi->pos != pos) - tmpi = tmpi->next; - - if (tmpi) - return tmpi->inset; - else { - lyxerr << "ERROR (LyXParagraph::GetInset): " - "Inset does not exist: " << pos << endl; - // in the const version we need to comment it out anyway... - //text[pos] = ' '; /// WHY!!! does this set the pos to ' '???? - // Did this commenting out introduce a bug? So far I have not - // seen any, please enlighten me. (Lgb) - // My guess is that since the inset does not exist, we might - // as well replace it with a space to prevent crashes. (Asger) - return 0; - } -#endif } @@ -912,19 +742,16 @@ Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const { if (pos < size()) { -#ifdef NEW_FONTTABLE // Seems OK +#ifdef SORTED_FONT_LIST for (FontList::const_iterator cit = fontlist.begin(); - cit != fontlist.end(); ++cit) { - if (pos >= (*cit).pos && pos <= (*cit).pos_end) + cit != fontlist.end() && pos <= (*cit).pos_end; ++cit) + if (pos >= (*cit).pos) return (*cit).font; - } #else - FontTable * tmp = fonttable; - while (tmp) { - if (pos >= tmp->pos && pos <= tmp->pos_end) - return tmp->font; - tmp = tmp->next; - } + for (FontList::const_iterator cit = fontlist.begin(); + cit != fontlist.end(); ++cit) + if (pos >= (*cit).pos && pos <= (*cit).pos_end) + return (*cit).font; #endif } // > because last is the next unused position, and you can @@ -937,20 +764,39 @@ LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const else { // Why is it an error to ask for the font of a // position that does not exist? Would it be - // enough for this to be anable on debug? + // enough for this to be enabled on debug? // We want strict error checking, but it's ok to only // have it when debugging. (Asger) lyxerr << "ERROR (LyXParagraph::GetFontSettings): " "position does not exist. " << pos << " (" << static_cast(pos) - << ")\n"; + << ")" << endl; } - } else if (pos) { + } else if (pos > 0) { return GetFontSettings(pos - 1); - } + } else // pos = size() = 0 + return LyXFont(LyXFont::ALL_INHERIT,getParLanguage()); + return LyXFont(LyXFont::ALL_INHERIT); } +// Gets uninstantiated font setting at position 0 +LyXFont LyXParagraph::GetFirstFontSettings() const +{ + if (size() > 0) { +#ifdef SORTED_FONT_LIST + if (!fontlist.empty() && fontlist.front().pos == 0) + return fontlist.front().font; +#else + for (FontList::const_iterator cit = fontlist.begin(); + cit != fontlist.end(); ++cit) + if (0 >= (*cit).pos && 0 <= (*cit).pos_end) + return (*cit).font; +#endif + } else if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) + return NextAfterFootnote()->GetFirstFontSettings(); + return LyXFont(LyXFont::ALL_INHERIT); +} // Gets the fully instantiated font at a given position in a paragraph // This is basically the same function as LyXText::GetFont() in text2.C. @@ -962,8 +808,9 @@ LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const { LyXFont tmpfont; - LyXLayout const & layout = textclasslist.Style(current_view->buffer()->params.textclass, - GetLayout()); + LyXLayout const & layout = + textclasslist.Style(current_view->buffer()->params.textclass, + GetLayout()); LyXParagraph::size_type main_body = 0; if (layout.labeltype == LABEL_MANUAL) main_body = BeginningOfMainBody(); @@ -982,6 +829,7 @@ LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const tmpfont = layout.font; else tmpfont = layout.labelfont; + tmpfont.setLanguage(getParLanguage()); } // check for environment font information @@ -997,7 +845,9 @@ LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const } } - tmpfont.realize(textclasslist.TextClass(current_view->buffer()->params.textclass).defaultfont()); + tmpfont.realize(textclasslist + .TextClass(current_view->buffer()->params.textclass) + .defaultfont()); return tmpfont; } @@ -1008,7 +858,6 @@ LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const { LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY; -#ifdef NEW_FONTTABLE // Seems OK for (FontList::const_iterator cit = fontlist.begin(); cit != fontlist.end(); ++cit) { if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) { @@ -1017,17 +866,6 @@ LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, maxsize = size; } } -#else - FontTable * tmp = fonttable; - while (tmp) { - if (startpos <= tmp->pos_end && endpos >= tmp->pos) { - LyXFont::FONT_SIZE size = tmp->font.size(); - if (size > maxsize && size<= LyXFont::SIZE_HUGER) - maxsize = size; - } - tmp = tmp->next; - } -#endif return maxsize; } @@ -1050,6 +888,8 @@ char LyXParagraph::GetChar(LyXParagraph::size_type pos) "position does not exist." << pos << " (" << static_cast(pos) << ")\n"; + // Assert(false); // This triggers sometimes... + // Why? } return '\0'; } else { @@ -1094,10 +934,11 @@ char LyXParagraph::GetChar(LyXParagraph::size_type pos) const return NextAfterFootnote() ->GetChar(pos - text.size() - 1); else { - lyxerr << "ERROR (LyXParagraph::GetChar): " + lyxerr << "ERROR (LyXParagraph::GetChar const): " "position does not exist." << pos << " (" << static_cast(pos) << ")\n"; + Assert(false); } return '\0'; } else { @@ -1133,10 +974,10 @@ string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const { Assert(lastpos>=0); - // the current word is defined as starting at the first character from - // the immediate left of lastpospos which meets the definition of IsLetter(), - // continuing to the last character to the right of this meeting - // IsLetter. + // the current word is defined as starting at the first character + // from the immediate left of lastpospos which meets the definition + // of IsLetter(), continuing to the last character to the right + // of this meeting IsLetter. string theword; @@ -1152,16 +993,16 @@ string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const int firstpos = lastpos; while ((firstpos >= 0) && !IsLetter(firstpos)) - firstpos--; + --firstpos; // now find the beginning by looking for a nonletter while ((firstpos>= 0) && IsLetter(firstpos)) - firstpos--; + --firstpos; // the above is now pointing to the preceeding non-letter - firstpos++; - lastpos= firstpos; + ++firstpos; + lastpos = firstpos; // so copy characters into theword until we get a nonletter // note that this can easily exceed lastpos, wich means @@ -1170,7 +1011,7 @@ string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const while (IsLetter(lastpos)) theword += GetChar(lastpos++); - return theword; + return theword; } @@ -1199,8 +1040,7 @@ LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos) lyxerr << "ERROR (LyXParagraph::ParFromPos): " "position does not exist." << endl; return this; - } - else + } else return this; } @@ -1231,7 +1071,8 @@ void LyXParagraph::SetFont(LyXParagraph::size_type pos, // > because last is the next unused position, and you can // use it if you want if (pos > size()) { - if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) { + if (next && + next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) { NextAfterFootnote()->SetFont(pos - text.size() - 1, font); } else { @@ -1248,7 +1089,6 @@ void LyXParagraph::SetFont(LyXParagraph::size_type pos, // No need to simplify this because it will disappear // in a new kernel. (Asger) // Next search font table -#ifdef NEW_FONTTABLE FontList::iterator tmp = fontlist.begin(); for (; tmp != fontlist.end(); ++tmp) { if (pos >= (*tmp).pos && pos <= (*tmp).pos_end) { @@ -1350,126 +1190,6 @@ void LyXParagraph::SetFont(LyXParagraph::size_type pos, } else { (*tmp).font = font; } - -#else - FontTable * tmp2; - - bool found = false; - FontTable * tmp = fonttable; - while (tmp && !found) { - if (pos >= tmp->pos && pos <= tmp->pos_end) - found = true; - else - tmp = tmp->next; - } - - if (!found) { - // if we did not find a font entry, but if the font at hand - // is the same as default, we just forget it - if (font == patternfont) - return; - - // ok, we did not find a font entry. But maybe there is exactly - // the needed font entry one position left - found = false; - tmp2 = fonttable; - while (tmp2 && !found) { - if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end) - found = true; - else - tmp2 = tmp2->next; - } - if (found) { - // ok there is one. maybe it is exactly - // the needed font - if (tmp2->font == font) { - // put the position under the font - tmp2->pos_end++; - return; - } - } - // Add a new entry in the - // fonttable for the position - tmp = new FontTable; - tmp->pos = pos; - tmp->pos_end = pos; - tmp->font = patternfont; // It seems that is actually totally - // wrong to use patternfont here, the correct should be font - // lockily at the end of this function we have - // tmp->font = font, so this one setting it to patternfont - // is negated. - tmp->next = fonttable; - fonttable = tmp; - } else { - // we found a font entry. maybe we have - // to split it and create a new one - - if (tmp->pos != tmp->pos_end) { // more than one character - if (pos == tmp->pos) { - // maybe we could enlarge the left fonttable - found = false; - tmp2 = fonttable; - while (tmp2 && !found) { - if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end) - found = true; - else - tmp2 = tmp2->next; - } - - // Is there is one, and is it exactly - // the needed font? - if (found && tmp2->font == font) { - // Put the position under the font - tmp2->pos_end++; - tmp->pos++; - return; - } - - // Add a new entry in the - // fonttable for the position - tmp2 = new FontTable; - tmp2->pos = pos + 1; - tmp2->pos_end = tmp->pos_end; - tmp2->font = tmp->font; - tmp->pos_end = pos; - tmp2->next = fonttable; - fonttable = tmp2; - } - else if (pos == tmp->pos_end) { - // Add a new entry in the - // fonttable for the position - tmp2 = new FontTable; - tmp2->pos = tmp->pos; - tmp2->pos_end = tmp->pos_end - 1; - tmp2->font = tmp->font; - tmp->pos = tmp->pos_end; - tmp2->next = fonttable; - fonttable = tmp2; - } - else { - // Add a new entry in the - // fonttable for the position - tmp2 = new FontTable; - tmp2->pos = tmp->pos; - tmp2->pos_end = pos - 1; - tmp2->font = tmp->font; - tmp2->next = fonttable; - fonttable = tmp2; - - tmp2 = new FontTable; - tmp2->pos = pos + 1; - tmp2->pos_end = tmp->pos_end; - tmp2->font = tmp->font; - tmp2->next = fonttable; - fonttable = tmp2; - - tmp->pos = pos; - tmp->pos_end = pos; - } - } - } - tmp->font = font; -#endif } @@ -1487,8 +1207,7 @@ LyXParagraph * LyXParagraph::Next() paragraph */ else return next; // This should never happen! - } - else + } else return next; } @@ -1504,8 +1223,7 @@ LyXParagraph * LyXParagraph::NextAfterFootnote() in a logical paragraph */ else return next; // This should never happen! - } - else + } else return next; } @@ -1521,8 +1239,7 @@ LyXParagraph const * LyXParagraph::NextAfterFootnote() const in a logical paragraph */ else return next; // This should never happen! - } - else + } else return next; } @@ -1531,7 +1248,7 @@ LyXParagraph * LyXParagraph::PreviousBeforeFootnote() { LyXParagraph * tmp; if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) { - tmp = next; + tmp = previous; while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE) tmp = tmp->previous; if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) @@ -1539,8 +1256,7 @@ LyXParagraph * LyXParagraph::PreviousBeforeFootnote() in a logical paragraph */ else return previous; // This should never happen! - } - else + } else return previous; } @@ -1556,9 +1272,20 @@ LyXParagraph * LyXParagraph::LastPhysicalPar() tmp = tmp->NextAfterFootnote(); return tmp; - } +LyXParagraph const * LyXParagraph::LastPhysicalPar() const +{ + if (footnoteflag != LyXParagraph::NO_FOOTNOTE) + return this; + + LyXParagraph const * tmp = this; + while (tmp->next + && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE) + tmp = tmp->NextAfterFootnote(); + + return tmp; +} LyXParagraph * LyXParagraph::FirstPhysicalPar() { @@ -1566,13 +1293,14 @@ LyXParagraph * LyXParagraph::FirstPhysicalPar() return this; LyXParagraph * tmppar = this; - while (tmppar && (tmppar->IsDummy() - || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE)) + while (tmppar && + (tmppar->IsDummy() + || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE)) tmppar = tmppar->previous; - if (!tmppar) - return this; // This should never happen! - else + if (!tmppar) { + return this; + } else return tmppar; } @@ -1583,13 +1311,14 @@ LyXParagraph const * LyXParagraph::FirstPhysicalPar() const return this; LyXParagraph const * tmppar = this; - while (tmppar && (tmppar->IsDummy() - || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE)) + while (tmppar && + (tmppar->IsDummy() + || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE)) tmppar = tmppar->previous; - if (!tmppar) - return this; // This should never happen! - else + if (!tmppar) { + return this; + } else return tmppar; } @@ -1612,8 +1341,7 @@ LyXParagraph * LyXParagraph::Previous() else return previous; - } - else + } else return previous; } @@ -1636,8 +1364,7 @@ LyXParagraph const * LyXParagraph::Previous() const else return previous; - } - else + } else return previous; } @@ -1645,18 +1372,18 @@ LyXParagraph const * LyXParagraph::Previous() const void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos, int flag) { - size_type i, pos_end, pos_first; + size_type i, j, pos_end, pos_first; // create a new paragraph LyXParagraph * par = ParFromPos(pos); LyXParagraph * firstpar = FirstPhysicalPar(); LyXParagraph * tmp = new LyXParagraph(par); - + tmp->footnoteflag = footnoteflag; tmp->footnotekind = footnotekind; // this is an idea for a more userfriendly layout handling, I will - // see what the users say */ + // see what the users say // layout stays the same with latex-environments if (flag) { @@ -1683,17 +1410,17 @@ void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos, // to the new paragraph pos_first = 0; while (ParFromPos(pos_first) != par) - pos_first++; + ++pos_first; pos_end = pos_first + par->text.size() - 1; - tmp->text.reserve(pos_end - pos); - for (i = pos; i <= pos_end; i++) { + for (i = j = pos; i <= pos_end; ++i) { par->CutIntoMinibuffer(i - pos_first); - tmp->InsertFromMinibuffer(i - pos); + if (tmp->InsertFromMinibuffer(j - pos)) + ++j; } - - for (i = pos_end; i >= pos; i--) + tmp->text.resize(tmp->text.size()); + for (i = pos_end; i >= pos; --i) par->Erase(i - pos_first); par->text.resize(par->text.size()); @@ -1734,6 +1461,8 @@ void LyXParagraph::MakeSameLayout(LyXParagraph const * par) pagebreak_top = par->pagebreak_top; added_space_top = par->added_space_top; + spacing = par->spacing; + pextra_type = par->pextra_type; pextra_width = par->pextra_width; pextra_widthp = par->pextra_widthp; @@ -1780,23 +1509,26 @@ LyXParagraph * LyXParagraph::Clone() const else result->table = 0; /* table stuff -- end*/ + + result->inset_owner = inset_owner; // ale970302 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0; // copy everything behind the break-position to the new paragraph - - for (size_type i = 0; i < size(); i++) { - CopyIntoMinibuffer(i); - result->InsertFromMinibuffer(i); - } - result->text.resize(result->text.size()); + + result->text = text; + result->fontlist = fontlist; + result->insetlist = insetlist; + for (InsetList::iterator it = result->insetlist.begin(); + it != result->insetlist.end(); ++it) + (*it).inset = (*it).inset->Clone(); return result; } -bool LyXParagraph::HasSameLayout(LyXParagraph const * par) +bool LyXParagraph::HasSameLayout(LyXParagraph const * par) const { par = par->FirstPhysicalPar(); @@ -1816,6 +1548,8 @@ bool LyXParagraph::HasSameLayout(LyXParagraph const * par) par->pagebreak_top == pagebreak_top && par->added_space_top == added_space_top && + par->spacing == spacing && + par->pextra_type == pextra_type && par->pextra_width == pextra_width && par->pextra_widthp == pextra_widthp && @@ -1832,35 +1566,31 @@ bool LyXParagraph::HasSameLayout(LyXParagraph const * par) void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos) { - size_type i, pos_end, pos_first; - // create a new paragraph LyXParagraph * par = ParFromPos(pos); LyXParagraph * tmp = new LyXParagraph(par); tmp->MakeSameLayout(par); - + + // When can pos < Last()? + // I guess pos == Last() is possible. if (Last() > pos) { // copy everything behind the break-position to the new // paragraph - pos_first = 0; + size_type pos_first = 0; while (ParFromPos(pos_first) != par) - pos_first++; - pos_end = pos_first + par->text.size() - 1; - // make shure there is enough memory for the now larger - // paragraph. This is not neccessary, because - // InsertFromMinibuffer will enlarge the memory (it uses - // InsertChar of course). But doing it by hand - // is MUCH faster! (only one time, not thousend times!!) - tmp->text.reserve(pos_end - pos); - - for (i = pos; i <= pos_end; i++) { - + ++pos_first; + size_type pos_end = pos_first + par->text.size() - 1; + + size_type i, j; + for (i = j = pos; i <= pos_end; ++i) { par->CutIntoMinibuffer(i - pos_first); - tmp->InsertFromMinibuffer(i - pos); + if (tmp->InsertFromMinibuffer(j - pos)) + ++j; } - for (i = pos_end; i >= pos; i--) + tmp->text.resize(tmp->text.size()); + for (size_type i = pos_end; i >= pos; --i) par->Erase(i - pos_first); par->text.resize(par->text.size()); @@ -1883,16 +1613,19 @@ void LyXParagraph::PasteParagraph() size_type pos_end = the_next->text.size() - 1; size_type pos_insert = Last(); - size_type i; // ok, now copy the paragraph - for (i = 0; i <= pos_end; i++) { + size_type i, j; + for (i = j = 0; i <= pos_end; ++i) { the_next->CutIntoMinibuffer(i); - InsertFromMinibuffer(pos_insert + i); + if (InsertFromMinibuffer(pos_insert + j)) + ++j; } // delete the next paragraph + LyXParagraph *prev = the_next->previous; delete the_next; + prev->next = 0; } @@ -1917,8 +1650,42 @@ void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos) } } +int LyXParagraph::GetEndLabel() const +{ + LyXParagraph const * par = this; + int par_depth = GetDepth(); + while (par) { + LyXTextClass::LayoutList::size_type layout = par->GetLayout(); + int endlabeltype = + textclasslist.Style(current_view->buffer()->params.textclass, + layout).endlabeltype; + if (endlabeltype != END_LABEL_NO_LABEL) { + LyXParagraph const * last = this; + if( footnoteflag == NO_FOOTNOTE) + last = LastPhysicalPar(); + else if (next->footnoteflag == NO_FOOTNOTE) + return endlabeltype; + + if (!last || !last->next) + return endlabeltype; + + int next_depth = last->next->GetDepth(); + if (par_depth > next_depth || + (par_depth == next_depth && layout != last->next->GetLayout() )) + return endlabeltype; + break; + } + if (par_depth == 0) + break; + par = par->DepthHook(par_depth - 1); + if (par) + par_depth = par->GetDepth(); + } + return END_LABEL_NO_LABEL; +} + -LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const +LyXTextClass::size_type LyXParagraph::GetLayout() const { return FirstPhysicalPar()->layout; } @@ -1936,7 +1703,7 @@ char LyXParagraph::GetAlign() const } -string LyXParagraph::GetLabestring() const +string LyXParagraph::GetLabelstring() const { return FirstPhysicalPar()->labelstring; } @@ -1966,7 +1733,7 @@ void LyXParagraph::SetLabelWidthString(string const & s) } -void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout) +void LyXParagraph::SetOnlyLayout(LyXTextClass::size_type new_layout) { LyXParagraph * par = FirstPhysicalPar(); LyXParagraph * ppar = 0; @@ -2011,7 +1778,7 @@ void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout) } -void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout) +void LyXParagraph::SetLayout(LyXTextClass::size_type new_layout) { LyXParagraph * par = FirstPhysicalPar(), @@ -2019,10 +1786,12 @@ void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout) * npar = 0; par->layout = new_layout; - par->labelwidthstring.clear(); + par->labelwidthstring.erase(); par->align = LYX_ALIGN_LAYOUT; par->added_space_top = VSpace(VSpace::NONE); par->added_space_bottom = VSpace(VSpace::NONE); + par->spacing.set(Spacing::Default); + /* table stuff -- begin*/ if (table) par->layout = 0; @@ -2078,9 +1847,10 @@ int LyXParagraph::BeginningOfMainBody() const // remove unnecessary GetChar() calls size_type i = 0; if (i < size() - && GetChar(i) != LyXParagraph::META_NEWLINE) { + && GetChar(i) != LyXParagraph::META_NEWLINE + ) { ++i; - char previous_char, temp; + char previous_char = 0, temp = 0; if (i < size() && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) { // Yes, this ^ is supposed to be "= " not "==" @@ -2097,7 +1867,7 @@ int LyXParagraph::BeginningOfMainBody() const if (i == 0 && i == size() && !(footnoteflag == LyXParagraph::NO_FOOTNOTE && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)) - i++; /* the cursor should not jump + ++i; /* the cursor should not jump * to the main body if there * is nothing in! */ return i; @@ -2148,76 +1918,27 @@ LyXParagraph const * LyXParagraph::DepthHook(int deth) const int LyXParagraph::AutoDeleteInsets() { -#ifdef NEW_INSETTABLE - vector tmpvec; - int i = 0; - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).inset && (*it).inset->AutoDelete()) { - tmpvec.push_back((*it).pos); - ++i; - } + int count = 0; + InsetList::size_type index = 0; + while (index < insetlist.size()) { + if (insetlist[index].inset && insetlist[index].inset->AutoDelete()) { + Erase(insetlist[index].pos); + // Erase() calls to insetlist.erase(&insetlist[index]) + // so index shouldn't be increased. + ++count; + } else + ++index; } - for (vector::const_iterator cit = tmpvec.begin(); - cit != tmpvec.end(); ++cit) { - Erase((*cit)); - } - return i; -#else - InsetTable * tmpi = insettable; - InsetTable * tmpi2 = tmpi; - int i = 0; - while (tmpi) { - tmpi2 = tmpi; - tmpi = tmpi->next; - if (tmpi2->inset) { - if (tmpi2->inset->AutoDelete()) { - i++; - Erase(tmpi2->pos); - } - } else { - lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): " - "cannot auto-delete insets" << endl; - } - } - return i; -#endif + return count; } -Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos) +LyXParagraph::inset_iterator LyXParagraph::InsetIterator(LyXParagraph::size_type pos) { -#ifdef NEW_INSETTABLE - InsetList::iterator it2 = insetlist.end(); - for (InsetList::iterator it = insetlist.begin(); - it != insetlist.end(); ++it) { - if ((*it).pos >= pos) { - if (it2 != insetlist.end() || (*it).pos < (*it2).pos) - it2 = it; - } - } - if (it2 != insetlist.end()) { - pos = (*it2).pos; - return (*it2).inset; - } - return 0; -#else - InsetTable * tmpi = insettable; - InsetTable * tmpi2 = 0; - while (tmpi){ - if (tmpi->pos >= pos) { - if (!tmpi2 || tmpi->pos < tmpi2->pos) - tmpi2 = tmpi; - } - tmpi= tmpi->next; - } - if (tmpi2){ - pos = tmpi2->pos; - return tmpi2->inset; - } - else - return 0; -#endif + InsetList::iterator it = lower_bound(insetlist.begin(), + insetlist.end(), + pos, matchIT()); + return inset_iterator(it); } @@ -2225,21 +1946,21 @@ Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos) int LyXParagraph::GetPositionOfInset(Inset * inset) const { // Find the entry. -#ifdef NEW_INSETTABLE + // We could use lower_bound here too, we just need to add + // the approp. operator() to matchIT (and change the name + // of that struct). Code would then be: + // InsetList::const_iterator cit = lower_bound(insetlist.begin(), + // insetlist.end(), + // inset, matchIT()); + // if ((*cit).inset == inset) { + // return (*cit).pos; + // } for (InsetList::const_iterator cit = insetlist.begin(); cit != insetlist.end(); ++cit) { if ((*cit).inset == inset) { return (*cit).pos; } } -#else - InsetTable * tmpi = insettable; - while (tmpi && tmpi->inset != inset) { - tmpi = tmpi->next; - } - if (tmpi && tmpi->inset) - return tmpi->pos; -#endif // Think about footnotes. if (footnoteflag == LyXParagraph::NO_FOOTNOTE && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) { @@ -2252,88 +1973,122 @@ int LyXParagraph::GetPositionOfInset(Inset * inset) const } -void LyXParagraph::readSimpleWholeFile(istream & is) -{ - is.seekg(0); - char c = 0; - while(!is.eof()) { - is.get(c); - InsertChar(text.size(), c); - }; -} - - -LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow, - string & foot, TexRow & foot_texrow, +LyXParagraph * LyXParagraph::TeXOnePar(ostream & os, TexRow & texrow, + bool moving_arg, + ostream & foot, + TexRow & foot_texrow, int & foot_count) { lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl; - LyXParagraph * par = next; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, - layout); + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + layout); bool further_blank_line = false; if (IsDummy()) lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl; if (start_of_appendix) { - file += "\\appendix\n"; + os << "\\appendix\n"; texrow.newline(); } + if (!spacing.isDefault() + && (!Previous() || !Previous()->HasSameLayout(this))) { + os << spacing.writeEnvirBegin() << "\n"; + texrow.newline(); + } + if (tex_code_break_column && style.isCommand()){ - file += '\n'; + os << '\n'; texrow.newline(); } if (pagebreak_top) { - file += "\\newpage"; + os << "\\newpage"; further_blank_line = true; } if (added_space_top.kind() != VSpace::NONE) { - file += added_space_top.asLatexCommand(); + os << added_space_top.asLatexCommand(current_view->buffer()->params); further_blank_line = true; } if (line_top) { - file += "\\lyxline{\\" + getFont(0).latexSize() + '}'; - file += "\\vspace{-1\\parskip}"; + os << "\\lyxline{\\" << getFont(0).latexSize() << '}' + << "\\vspace{-1\\parskip}"; further_blank_line = true; } if (further_blank_line){ - file += '\n'; + os << '\n'; texrow.newline(); } + Language const * language = getParLanguage(); + Language const * doc_language = current_view->buffer()->params.language_info; + if (language != doc_language) { + os << subst(lyxrc.language_command_begin, "$$lang", + language->lang) + << endl; + texrow.newline(); + } + switch (style.latextype) { case LATEX_COMMAND: - file += '\\'; - file += style.latexname(); - file += style.latexparam(); + os << '\\' + << style.latexname() + << style.latexparam(); break; case LATEX_ITEM_ENVIRONMENT: - if (bibkey) - bibkey->Latex(file, false); - else - file += "\\item "; + if (bibkey) { + bibkey->Latex(os, false, false); + } else + os << "\\item "; break; case LATEX_LIST_ENVIRONMENT: - file += "\\item "; + os << "\\item "; break; default: break; } - bool need_par = SimpleTeXOnePar(file, texrow); + bool need_par = SimpleTeXOnePar(os, texrow, moving_arg); // Spit out footnotes - while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE - && par->footnoteflag != footnoteflag) { - par = par->TeXFootnote(file, texrow, - foot, foot_texrow, foot_count); - par->SimpleTeXOnePar(file, texrow); - par = par->next; + LyXParagraph * par = next; + if (lyxrc.rtl_support) { + if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE + && next->footnoteflag != footnoteflag) { + LyXParagraph * p = 0; + bool is_rtl = GetFontSettings(size()-1).isRightToLeft(); + if ( (p = NextAfterFootnote()) != 0 && + p->GetFontSettings(0).isRightToLeft() != is_rtl) + is_rtl = GetFontSettings(0).isRightToLeft(); + while (par && + par->footnoteflag != LyXParagraph::NO_FOOTNOTE && + par->footnoteflag != footnoteflag) { + par = par->TeXFootnote(os, texrow, foot, + foot_texrow, foot_count, + is_rtl); + par->SimpleTeXOnePar(os, texrow, moving_arg); + is_rtl = par->GetFontSettings(par->size()-1).isRightToLeft(); + if (par->next && + par->next->footnoteflag != LyXParagraph::NO_FOOTNOTE && + (p = par->NextAfterFootnote()) != 0 && + p->GetFontSettings(0).isRightToLeft() != is_rtl) + is_rtl = GetFontSettings(0).isRightToLeft(); + par = par->next; + } + } + } else { + while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE + && par->footnoteflag != footnoteflag) { + par = par->TeXFootnote(os, texrow, + foot, foot_texrow, foot_count, + false); + par->SimpleTeXOnePar(os, texrow, moving_arg); + par = par->next; + } } // Make sure that \\par is done with the font of the last @@ -2341,31 +2096,37 @@ LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow, // This is necessary because LaTeX (and LyX on the screen) // calculates the space between the baselines according // to this font. (Matthias) - LyXFont font = getFont(Last()-1); + LyXFont font = getFont(Last() - 1); if (need_par) { if (style.resfont.size() != font.size()) { - file += '\\'; - file += font.latexSize(); - file += ' '; + os << '\\' + << font.latexSize() + << ' '; } - file += "\\par}"; + os << "\\par}"; } else if (textclasslist.Style(current_view->buffer()->params.textclass, GetLayout()).isCommand()){ if (style.resfont.size() != font.size()) { - file += '\\'; - file += font.latexSize(); - file += ' '; + os << '\\' + << font.latexSize() + << ' '; } - file += '}'; + os << '}'; } else if (style.resfont.size() != font.size()){ - file += "{\\" + font.latexSize() + " \\par}"; + os << "{\\" << font.latexSize() << " \\par}"; + } + + if (language != doc_language) { + os << endl + << subst(lyxrc.language_command_end, "$$lang", + doc_language->lang); } switch (style.latextype) { case LATEX_ITEM_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: if (par && (depth < par->depth)) { - file += '\n'; + os << '\n'; texrow.newline(); } break; @@ -2378,7 +2139,8 @@ LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow, || par->pextra_type != pextra_type)) break; default: - if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE + // we don't need it for the last paragraph!!! + if (next && !(footnoteflag != LyXParagraph::NO_FOOTNOTE && footnotekind != LyXParagraph::FOOTNOTE && footnotekind != LyXParagraph::MARGIN && (table @@ -2388,35 +2150,42 @@ LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow, // before or after a table in a float. This // little trick is needed in order to allow // use of tables in \subfigures or \subtables. - file += '\n'; + os << '\n'; texrow.newline(); } } further_blank_line = false; if (line_bottom) { - file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}'; + os << "\\lyxline{\\" << getFont(Last() - 1).latexSize() << '}'; further_blank_line = true; } if (added_space_bottom.kind() != VSpace::NONE) { - file += added_space_bottom.asLatexCommand(); + os << added_space_bottom.asLatexCommand(current_view->buffer()->params); further_blank_line = true; } if (pagebreak_bottom) { - file += "\\newpage"; + os << "\\newpage"; further_blank_line = true; } if (further_blank_line){ - file += '\n'; + os << '\n'; texrow.newline(); } - if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par && + if (!spacing.isDefault() + && (!par || !par->HasSameLayout(this))) { + os << spacing.writeEnvirEnd() << "\n"; + texrow.newline(); + } + + // we don't need it for the last paragraph!!! + if (next && !(footnoteflag != LyXParagraph::NO_FOOTNOTE && par && par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) { - file += '\n'; + os << '\n'; texrow.newline(); } @@ -2426,29 +2195,30 @@ LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow, // This one spits out the text of the paragraph -bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) +bool LyXParagraph::SimpleTeXOnePar(ostream & os, TexRow & texrow, + bool moving_arg) { lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl; if (table) - return SimpleTeXOneTablePar(file, texrow); + return SimpleTeXOneTablePar(os, texrow); - char c; - size_type main_body; - bool return_value = false; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, GetLayout()); - LyXFont basefont; + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + GetLayout()); + LyXFont basefont, last_font; // Maybe we have to create a optional argument. + size_type main_body; if (style.labeltype != LABEL_MANUAL) main_body = 0; else main_body = BeginningOfMainBody(); if (main_body > 0) { - file += '['; + os << '['; basefont = getFont(-2); // Get label font } else { basefont = getFont(-1); // Get layout font @@ -2460,73 +2230,93 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) && !text.size() && !IsDummy()) { if (style.isCommand()) { - file += '{'; - column++; + os << '{'; + ++column; } else if (align != LYX_ALIGN_LAYOUT) { - file += '{'; - column++; + os << '{'; + ++column; return_value = true; } } + + moving_arg |= style.needprotect; // Which font is currently active? - LyXFont running_font = basefont; + LyXFont running_font(basefont); // Do we have an open font change? bool open_font = false; texrow.start(this, 0); for (size_type i = 0; i < size(); ++i) { - column++; + ++column; // First char in paragraph or after label? if (i == main_body && !IsDummy()) { if (main_body > 0) { if (open_font) { - column += running_font.latexWriteEndChanges(file, basefont); + column += running_font.latexWriteEndChanges(os, basefont, basefont); open_font = false; } basefont = getFont(-1); // Now use the layout font running_font = basefont; - file += ']'; - column++; + os << ']'; + ++column; } if (style.isCommand()) { - file += '{'; - column++; + os << '{'; + ++column; } else if (align != LYX_ALIGN_LAYOUT) { - file += "{\\par"; + os << "{\\par"; column += 4; return_value = true; } if (noindent) { - file += "\\noindent "; + os << "\\noindent "; column += 10; } switch (align) { case LYX_ALIGN_NONE: case LYX_ALIGN_BLOCK: case LYX_ALIGN_LAYOUT: - case LYX_ALIGN_SPECIAL: break; + case LYX_ALIGN_SPECIAL: + break; case LYX_ALIGN_LEFT: - file += "\\raggedright "; - column+= 13; + if (getParLanguage()->lang != "hebrew") { + os << "\\raggedright "; + column+= 13; + } else { + os << "\\raggedleft "; + column+= 12; + } break; case LYX_ALIGN_RIGHT: - file += "\\raggedleft "; - column+= 12; + if (getParLanguage()->lang != "hebrew") { + os << "\\raggedleft "; + column+= 12; + } else { + os << "\\raggedright "; + column+= 13; + } break; case LYX_ALIGN_CENTER: - file += "\\centering "; + os << "\\centering "; column+= 11; break; } } - c = GetChar(i); + int c = GetChar(i); // Fully instantiated font LyXFont font = getFont(i); + LyXParagraph * p = 0; + if (i == 0 && previous && + previous->footnoteflag != LyXParagraph::NO_FOOTNOTE && + (p = PreviousBeforeFootnote()) != 0) + last_font = p->getFont(p->size()-1); + else + last_font = running_font; // Spaces at end of font change are simulated to be // outside font change, i.e. we write "\textXX{text} " @@ -2534,12 +2324,13 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) if (open_font && c == ' ' && i <= size() - 2 && !getFont(i+1).equalExceptLatex(running_font) && !getFont(i+1).equalExceptLatex(font)) { - font = getFont(i+1); + font = getFont(i + 1); } // We end font definition before blanks if (!font.equalExceptLatex(running_font) && open_font) { - column += running_font.latexWriteEndChanges(file, - basefont); + column += running_font.latexWriteEndChanges(os, + basefont, + (i == main_body-1) ? basefont : font); running_font = basefont; open_font = false; } @@ -2548,7 +2339,7 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) if (c == ' '){ // Do not print the separation of the optional argument if (i != main_body - 1) { - SimpleTeXBlanks(file, texrow, i, + SimpleTeXBlanks(os, texrow, i, column, font, style); } } @@ -2556,7 +2347,8 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) // Do we need to change font? if (!font.equalExceptLatex(running_font) && i != main_body-1) { - column += font.latexWriteStartChanges(file, basefont); + column += font.latexWriteStartChanges(os, basefont, + last_font); running_font = font; open_font = true; } @@ -2566,25 +2358,27 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) // the default in SimpleTeXSpecialChars(). if (!style.newline_allowed || font.latex() == LyXFont::ON) { - file += '\n'; + os << '\n'; } else { if (open_font) { - column += running_font.latexWriteEndChanges(file, basefont); + column += running_font.latexWriteEndChanges(os, basefont, basefont); open_font = false; } basefont = getFont(-1); running_font = basefont; if (font.family() == LyXFont::TYPEWRITER_FAMILY) { - file += "~"; + os << "~"; } - file += "\\\\\n"; + if (moving_arg) + os << "\\protect "; + os << "\\\\\n"; } texrow.newline(); - texrow.start(this, i+1); + texrow.start(this, i + 1); column = 0; } else { - SimpleTeXSpecialChars(file, texrow, + SimpleTeXSpecialChars(os, texrow, moving_arg, font, running_font, basefont, open_font, style, i, column, c); } @@ -2592,12 +2386,18 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) // If we have an open font definition, we have to close it if (open_font) { - running_font.latexWriteEndChanges(file, basefont); + LyXParagraph * p = 0; + if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE + && (p = NextAfterFootnote()) != 0) + running_font.latexWriteEndChanges(os, basefont, + p->getFont(0)); + else + running_font.latexWriteEndChanges(os, basefont, basefont); } // Needed if there is an optional argument but no contents. if (main_body > 0 && main_body == size()) { - file += "]~"; + os << "]~"; return_value = false; } @@ -2607,35 +2407,28 @@ bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow) // This one spits out the text of a table paragraph -bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow) +bool LyXParagraph::SimpleTeXOneTablePar(ostream & os, TexRow & texrow) { lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl; - char c; - int tmp; bool return_value = false; - int current_cell_number = -1; LyXLayout const & style = - textclasslist.Style(current_view->buffer()->params.textclass, GetLayout()); - LyXFont basefont = getFont(-1); // Get layout font - // Which font is currently active? - LyXFont running_font = basefont; - // Do we have an open font change? - bool open_font = false; + textclasslist.Style(current_view->buffer()->params.textclass, + GetLayout()); int column = 0; if (!IsDummy()) { // it is dummy if it is in a float!!! if (style.isCommand()) { - file += '{'; - column++; + os << '{'; + ++column; } else if (align != LYX_ALIGN_LAYOUT) { - file += '{'; - column++; + os << '{'; + ++column; return_value = true; } if (noindent) { - file += "\\noindent "; + os << "\\noindent "; column += 10; } switch (align) { @@ -2644,61 +2437,81 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow) case LYX_ALIGN_LAYOUT: case LYX_ALIGN_SPECIAL: break; case LYX_ALIGN_LEFT: - file += "\\raggedright "; + os << "\\raggedright "; column+= 13; break; case LYX_ALIGN_RIGHT: - file += "\\raggedleft "; + os << "\\raggedleft "; column+= 12; break; case LYX_ALIGN_CENTER: - file += "\\centering "; + os << "\\centering "; column+= 11; break; } } - current_cell_number = -1; - tmp = table->TexEndOfCell(file, current_cell_number); + + LyXFont basefont = getFont(-1); // Get layout font + // Which font is currently active? + LyXFont running_font = basefont; + LyXFont last_font; + // Do we have an open font change? + bool open_font = false; + int current_cell_number = -1; + int tmp = table->TexEndOfCell(os, current_cell_number); for (; tmp > 0 ; --tmp) texrow.newline(); texrow.start(this, 0); + bool is_rtl = getParLanguage()->RightToLeft; + bool first_in_cell = true; + for (size_type i = 0; i < size(); ++i) { - c = GetChar(i); - if (table->IsContRow(current_cell_number+1)) { + char c = GetChar(i); + if (table->IsContRow(current_cell_number + 1)) { if (c == LyXParagraph::META_NEWLINE) - current_cell_number++; + ++current_cell_number; continue; } ++column; - + + if (first_in_cell && is_rtl) { + os << "\\R{"; + column += 3; + first_in_cell = false; + } + // Fully instantiated font LyXFont font = getFont(i); + last_font = running_font; // Spaces at end of font change are simulated to be // outside font change. // i.e. we write "\textXX{text} " rather than // "\textXX{text }". (Asger) if (open_font && c == ' ' && i <= size() - 2 - && getFont(i+1) != running_font && getFont(i+1) != font) { - font = getFont(i+1); + && getFont(i + 1) != running_font + && getFont(i + 1) != font) { + font = getFont(i + 1); } // We end font definition before blanks if (font != running_font && open_font) { - column += running_font.latexWriteEndChanges(file, - basefont); + column += running_font.latexWriteEndChanges(os, + basefont, + font); running_font = basefont; open_font = false; } // Blanks are printed before start of fontswitch if (c == ' '){ - SimpleTeXBlanks(file, texrow, i, column, font, style); + SimpleTeXBlanks(os, texrow, i, column, font, style); } // Do we need to change font? if (font != running_font) { - column += font.latexWriteStartChanges(file, basefont); + column += font.latexWriteStartChanges(os, basefont, + last_font); running_font = font; open_font = true; } @@ -2706,7 +2519,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow) if (font.latex() != running_font.latex()) { if (font.latex() == LyXFont::ON && style.needprotect) { - file += "\\protect "; + os << "\\protect "; column += 9; } } @@ -2716,37 +2529,43 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow) // SimpleTeXSpecialChars() if (open_font) { column += running_font - .latexWriteEndChanges(file, basefont); + .latexWriteEndChanges(os, basefont, + basefont); open_font = false; } basefont = getFont(-1); running_font = basefont; - current_cell_number++; + ++current_cell_number; if (table->CellHasContRow(current_cell_number) >= 0) { - TeXContTableRows(file, i+1, + TeXContTableRows(os, i + 1, current_cell_number, column, texrow); } + if (is_rtl && !first_in_cell) { + os << "}"; + first_in_cell = true; + } + // if this cell follow only ContRows till end don't // put the EndOfCell because it is put after the // for(...) if (table->ShouldBeVeryLastCell(current_cell_number)) { - current_cell_number--; + --current_cell_number; break; } - int tmp = table->TexEndOfCell(file, + int tmp = table->TexEndOfCell(os, current_cell_number); - if (tmp>0) { + if (tmp > 0) { column = 0; } else if (tmp < 0) { tmp = -tmp; } - for (;tmp--;) { + for (; tmp--;) { texrow.newline(); } - texrow.start(this, i+1); + texrow.start(this, i + 1); } else { - SimpleTeXSpecialChars(file, texrow, + SimpleTeXSpecialChars(os, texrow, false, font, running_font, basefont, open_font, style, i, column, c); } @@ -2754,10 +2573,12 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow) // If we have an open font definition, we have to close it if (open_font) { - running_font.latexWriteEndChanges(file, basefont); + running_font.latexWriteEndChanges(os, basefont, basefont); } - current_cell_number++; - tmp = table->TexEndOfCell(file, current_cell_number); + ++current_cell_number; + if (is_rtl && !first_in_cell) + os << "}"; + tmp = table->TexEndOfCell(os, current_cell_number); for (; tmp > 0; --tmp) texrow.newline(); lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl; @@ -2766,7 +2587,7 @@ bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow) // This one spits out the text off ContRows in tables -bool LyXParagraph::TeXContTableRows(string & file, +bool LyXParagraph::TeXContTableRows(ostream & os, LyXParagraph::size_type i, int current_cell_number, int & column, TexRow & texrow) @@ -2778,11 +2599,11 @@ bool LyXParagraph::TeXContTableRows(string & file, char c; bool return_value = false; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, - GetLayout()); - LyXFont basefont; - - basefont = getFont(-1); // Get layout font + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + GetLayout()); + LyXFont basefont = getFont(-1); // Get layout font + LyXFont last_font; // Which font is currently active? LyXFont running_font = basefont; // Do we have an open font change? @@ -2797,16 +2618,16 @@ bool LyXParagraph::TeXContTableRows(string & file, for (; (i < size()) && (current_cell_numberLinebreaks(table->FirstVirtualCell(cell))) { - file += " \\\\\n"; + os << " \\\\\n"; texrow.newline(); column = 0; } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) { - file += ' '; + os << ' '; } for (; i < size() @@ -2816,6 +2637,7 @@ bool LyXParagraph::TeXContTableRows(string & file, // Fully instantiated font LyXFont font = getFont(i); + last_font = running_font; // Spaces at end of font change are simulated to // be outside font change. i.e. we write @@ -2829,39 +2651,40 @@ bool LyXParagraph::TeXContTableRows(string & file, // We end font definition before blanks if (font != running_font && open_font) { - column += running_font.latexWriteEndChanges(file, basefont); + column += running_font.latexWriteEndChanges(os, basefont, font); running_font = basefont; open_font = false; } // Blanks are printed before start of fontswitch if (c == ' '){ - SimpleTeXBlanks(file, texrow, i, + SimpleTeXBlanks(os, texrow, i, column, font, style); } // Do we need to change font? if (font != running_font) { column += - font.latexWriteStartChanges(file, - basefont); + font.latexWriteStartChanges(os, + basefont, + last_font); running_font = font; open_font = true; } // Do we need to turn on LaTeX mode? if (font.latex() != running_font.latex()) { if (font.latex() == LyXFont::ON - && style.needprotect) - { - file += "\\protect "; - column += 9; - } + && style.needprotect) { + os << "\\protect "; + column += 9; + } } - SimpleTeXSpecialChars(file, texrow, font, + SimpleTeXSpecialChars(os, texrow, false, font, running_font, basefont, open_font, style, i, column, c); } // If we have an open font definition, we have to close it if (open_font) { - running_font.latexWriteEndChanges(file, basefont); + running_font.latexWriteEndChanges(os, basefont, + basefont); open_font = false; } basefont = getFont(-1); @@ -2878,10 +2701,7 @@ bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string) bool retval = false; switch (c) { case LyXParagraph::META_HFILL: - sgml_string.clear(); - break; - case LyXParagraph::META_PROTECTED_SEPARATOR: - sgml_string = ' '; + sgml_string.erase(); break; case LyXParagraph::META_NEWLINE: sgml_string = '\n'; @@ -2930,7 +2750,7 @@ bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string) sgml_string = ' '; break; case '\0': // Ignore :-) - sgml_string.clear(); + sgml_string.erase(); break; default: sgml_string = c; @@ -2940,21 +2760,21 @@ bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string) } -void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, +void LyXParagraph::SimpleDocBookOneTablePar(ostream & os, string & extra, int & desc_on, int depth) { if (!table) return; lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl; - int column; + int column = 0; LyXFont font1, font2; char c; Inset * inset; size_type main_body; - string emph = "emphasis"; bool emph_flag = false; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, - GetLayout()); + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + GetLayout()); if (style.labeltype != LABEL_MANUAL) main_body = 0; @@ -2968,13 +2788,13 @@ void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, font1 = style.font; int char_line_count = depth; - addNewlineAndDepth(file, depth); + os << newlineAndDepth(depth); if (footnoteflag == LyXParagraph::NO_FOOTNOTE) { - file += ""; - addNewlineAndDepth(file, ++depth); + os << "" + << newlineAndDepth(++depth); } int current_cell_number = -1; - int tmp = table->DocBookEndOfCell(file, current_cell_number, depth); + int tmp = table->DocBookEndOfCell(os, current_cell_number, depth); // Parsing main loop. for (size_type i = 0; i < size(); ++i) { @@ -2992,23 +2812,23 @@ void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, // Handle tag. if (font1.emph() != font2.emph() && i) { if (font2.emph() == LyXFont::ON) { - file += ""; + os << ""; emph_flag= true; } else if (emph_flag) { - file += ""; + os << ""; emph_flag= false; } } if (c == LyXParagraph::META_NEWLINE) { // We have only to control for emphasis open here! if (emph_flag) { - file += ""; + os << ""; emph_flag= false; } font1 = font2 = getFont(-1); - current_cell_number++; + ++current_cell_number; if (table->CellHasContRow(current_cell_number) >= 0) { - DocBookContTableRows(file, extra, desc_on, i+1, + DocBookContTableRows(os, extra, desc_on, i + 1, current_cell_number, column); } @@ -3016,18 +2836,29 @@ void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, // put the EndOfCell because it is put after the // for(...) if (table->ShouldBeVeryLastCell(current_cell_number)) { - current_cell_number--; + --current_cell_number; break; } - tmp= table->DocBookEndOfCell(file, current_cell_number, - depth); + tmp = table->DocBookEndOfCell(os, + current_cell_number, + depth); if (tmp > 0) column = 0; } else if (c == LyXParagraph::META_INSET) { inset = GetInset(i); - string tmp_out; - inset->DocBook(tmp_out); +#ifdef HAVE_SSTREAM + std::ostringstream ost; + inset->DocBook(ost); + string tmp_out = ost.str().c_str(); +#else + ostrstream ost; + inset->DocBook(ost); + ost << '\0'; + char * ctmp = ost.str(); + string tmp_out(ctmp); + delete [] ctmp; +#endif // // This code needs some explanation: // Two insets are treated specially @@ -3047,16 +2878,16 @@ void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, extra += frontStrip(tmp_out, '@'); else - file += frontStrip(tmp_out, - '@'); + os << frontStrip(tmp_out, + '@'); } else - file += tmp_out; + os << tmp_out; } } else if (font2.latex() == LyXFont::ON) { // "TeX"-Mode on == > SGML-Mode on. if (c != '\0') - file += c; - char_line_count++; + os << c; + ++char_line_count; } else { string sgml_string; if (linuxDocConvertChar(c, sgml_string) @@ -3065,15 +2896,15 @@ void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, // non-breaking characters // char is ' ' if (desc_on == 1) { - char_line_count++; - file += '\n'; - file += ""; + ++char_line_count; + os << '\n' + << ""; desc_on = 2; } else { - file += c; + os << c; } } else { - file += sgml_string; + os << sgml_string; } } font1 = font2; @@ -3085,27 +2916,27 @@ void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra, } if (emph_flag) { - file += ""; + os << ""; } - current_cell_number++; - tmp = table->DocBookEndOfCell(file, current_cell_number, depth); + ++current_cell_number; + tmp = table->DocBookEndOfCell(os, current_cell_number, depth); // Resets description flag correctly. switch(desc_on){ case 1: // not closed... - file += ""; + os << ""; break; } if (footnoteflag == LyXParagraph::NO_FOOTNOTE) - file += ""; - file += '\n'; + os << ""; + os << '\n'; lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done " << this << endl; } -void LyXParagraph::DocBookContTableRows(string & file, string & extra, +void LyXParagraph::DocBookContTableRows(ostream & os, string & extra, int & desc_on, LyXParagraph::size_type i, int current_cell_number, int &column) @@ -3115,32 +2946,32 @@ void LyXParagraph::DocBookContTableRows(string & file, string & extra, lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl; - int cell; - LyXFont font1, font2; + LyXFont font2; char c; Inset * inset; - size_type main_body; - size_type lastpos; - string emph= "emphasis"; - bool emph_flag= false; - int char_line_count= 0; + //string emph = "emphasis"; + bool emph_flag = false; + int char_line_count = 0; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, - GetLayout()); + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + GetLayout()); + size_type main_body; if (style.labeltype != LABEL_MANUAL) main_body = 0; else main_body = BeginningOfMainBody(); // Gets paragraph main font. + LyXFont font1; if (main_body > 0) font1 = style.labelfont; else font1 = style.font; - lastpos = i; - cell = table->CellHasContRow(current_cell_number); + size_type lastpos = i; + int cell = table->CellHasContRow(current_cell_number); ++current_cell_number; while(cell >= 0) { // first find the right position @@ -3148,7 +2979,7 @@ void LyXParagraph::DocBookContTableRows(string & file, string & extra, for (; i < size() && current_cell_number < cell; ++i) { c = GetChar(i); if (c == LyXParagraph::META_NEWLINE) - current_cell_number++; + ++current_cell_number; } lastpos = i; c = GetChar(i); @@ -3159,7 +2990,7 @@ void LyXParagraph::DocBookContTableRows(string & file, string & extra, // column = 0; // } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) { - file += ' '; + os << ' '; } for (; i < size() @@ -3173,25 +3004,37 @@ void LyXParagraph::DocBookContTableRows(string & file, string & extra, // Handle tag. if (font1.emph() != font2.emph() && i) { if (font2.emph() == LyXFont::ON) { - file += ""; + os << ""; emph_flag= true; } else if (emph_flag) { - file += ""; + os << ""; emph_flag= false; } } if (c == LyXParagraph::META_INSET) { inset = GetInset(i); - string tmp_out; - inset->DocBook(tmp_out); +#ifdef HAVE_SSTREAM + std::ostringstream ost; + inset->DocBook(ost); + string tmp_out = ost.str().c_str(); +#else + ostrstream ost; + inset->DocBook(ost); + ost << '\0'; + char * ctmp = ost.str(); + string tmp_out(ctmp); + delete [] ctmp; +#endif // // This code needs some explanation: // Two insets are treated specially - // label if it is the first element in a command paragraph + // label if it is the first element in a + // command paragraph // desc_on == 3 - // graphics inside tables or figure floats can't go on - // title (the equivalente in latex for this case is caption - // and title should come first + // graphics inside tables or figure floats + // can't go on title (the equivalente in + // latex for this case is caption and title + // should come first // desc_on == 4 // if(desc_on != 3 || i != 0) { @@ -3199,38 +3042,38 @@ void LyXParagraph::DocBookContTableRows(string & file, string & extra, if(desc_on == 4) extra += frontStrip(tmp_out, '@'); else - file += frontStrip(tmp_out, '@'); + os << frontStrip(tmp_out, '@'); } else - file += tmp_out; + os << tmp_out; } } else if (font2.latex() == LyXFont::ON) { // "TeX"-Mode on == > SGML-Mode on. if (c!= '\0') - file += c; - char_line_count++; + os << c; + ++char_line_count; } else { string sgml_string; if (linuxDocConvertChar(c, sgml_string) && !style.free_spacing) { - // in freespacing mode, spaces are - // non-breaking characters - // char is ' ' + // in freespacing mode, spaces are + // non-breaking characters + // char is ' ' if (desc_on == 1) { - char_line_count++; - file += '\n'; - file += ""; + ++char_line_count; + os << '\n' + << ""; desc_on = 2; } else { - file += c; + os << c; } } else { - file += sgml_string; + os << sgml_string; } } } // we have only to control for emphasis open here! if (emph_flag) { - file += ""; + os << ""; emph_flag= false; } font1 = font2 = getFont(-1); @@ -3240,7 +3083,7 @@ void LyXParagraph::DocBookContTableRows(string & file, string & extra, } -void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow, +void LyXParagraph::SimpleTeXBlanks(ostream & os, TexRow & texrow, LyXParagraph::size_type const i, int & column, LyXFont const & font, LyXLayout const & style) @@ -3265,24 +3108,25 @@ void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow, if (tex_code_break_column == 0) { // in batchmode we need LaTeX to still // see it as a space not as an extra '\n' - file += " %\n"; + os << " %\n"; } else { - file += '\n'; + os << '\n'; } texrow.newline(); - texrow.start(this, i+1); + texrow.start(this, i + 1); column = 0; } else if (font.latex() == LyXFont::OFF) { if (style.free_spacing) { - file += '~'; + os << '~'; } else { - file += ' '; + os << ' '; } } } -void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, +void LyXParagraph::SimpleTeXSpecialChars(ostream & os, TexRow & texrow, + bool moving_arg, LyXFont & font, LyXFont & running_font, LyXFont & basefont, @@ -3298,15 +3142,28 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, case LyXParagraph::META_INSET: { Inset * inset = GetInset(i); if (inset) { - int len = file.length(); - int tmp = inset->Latex(file, style.isCommand()); - + bool close = false; + int len = os.tellp(); + if ((inset->LyxCode() == Inset::GRAPHICS_CODE + || inset->LyxCode() == Inset::MATH_CODE + || inset->LyxCode() == Inset::URL_CODE) + && running_font.isRightToLeft()) { + os << "\\L{"; + close = true; + } + + int tmp = inset->Latex(os, moving_arg, + style.free_spacing); + + if (close) + os << "}"; + if (tmp) { column = 0; } else { - column += file.length() - len; + column += os.tellp() - len; } - for (;tmp--;) { + for (; tmp--;) { texrow.newline(); } } @@ -3315,7 +3172,8 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, case LyXParagraph::META_NEWLINE: if (open_font) { - column += running_font.latexWriteEndChanges(file, + column += running_font.latexWriteEndChanges(os, + basefont, basefont); open_font = false; } @@ -3324,7 +3182,7 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, break; case LyXParagraph::META_HFILL: - file += "\\hfill{}"; + os << "\\hfill{}"; column += 7; break; @@ -3336,10 +3194,6 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, // but I'll leave it as a switch statement // so its simpler to extend. (ARRae) switch (c) { - case LyXParagraph::META_PROTECTED_SEPARATOR: - file += ' '; - break; - default: // make sure that we will not print // error generating chars to the tex @@ -3347,19 +3201,15 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, // if it were done in the buffer // itself. if (c != '\0') { - file += c; + os << c; } break; } } else { // Plain mode (i.e. not LaTeX) switch (c) { - case LyXParagraph::META_PROTECTED_SEPARATOR: - file += '~'; - break; - case '\\': - file += "\\textbackslash{}"; + os << "\\textbackslash{}"; column += 15; break; @@ -3367,46 +3217,46 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, case '×': case '÷': case '¹': case 'ª': case 'º': case '¬': case 'µ': if (current_view->buffer()->params.inputenc == "latin1") { - file += "\\ensuremath{"; - file += c; - file += '}'; + os << "\\ensuremath{" + << c + << '}'; column += 13; } else { - file += c; + os << c; } break; case '|': case '<': case '>': // In T1 encoding, these characters exist - if (lyxrc->fontenc == "T1") { - file += c; + if (lyxrc.fontenc == "T1") { + os << c; //... but we should avoid ligatures if ((c == '>' || c == '<') && i <= size() - 2 - && GetChar(i+1) == c){ - file += "\\textcompwordmark{}"; + && GetChar(i + 1) == c){ + os << "\\textcompwordmark{}"; column += 19; } break; } // Typewriter font also has them if (font.family() == LyXFont::TYPEWRITER_FAMILY) { - file += c; + os << c; break; } // Otherwise, we use what LaTeX // provides us. switch(c) { case '<': - file += "\\textless{}"; + os << "\\textless{}"; column += 10; break; case '>': - file += "\\textgreater{}"; + os << "\\textgreater{}"; column += 13; break; case '|': - file += "\\textbar{}"; + os << "\\textbar{}"; column += 9; break; } @@ -3416,50 +3266,47 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, if (i <= size() - 2 && GetChar(i + 1) == '-' && font.family() == LyXFont::TYPEWRITER_FAMILY) { - file += "-{}"; + os << "-{}"; column += 2; } else { - file += '-'; + os << '-'; } break; case '\"': - file += "\\char`\\\"{}"; + os << "\\char`\\\"{}"; column += 9; break; case '£': if (current_view->buffer()->params.inputenc == "default") { - file += "\\pounds{}"; + os << "\\pounds{}"; column += 8; } else { - file += c; + os << c; } break; case '$': case '&': case '%': case '#': case '{': case '}': case '_': - file += '\\'; - file += c; + os << '\\' << c; column += 1; break; case '~': - file += "\\textasciitilde{}"; + os << "\\textasciitilde{}"; column += 16; break; case '^': - file += "\\textasciicircum{}"; + os << "\\textasciicircum{}"; column += 17; break; case '*': case '[': case ']': // avoid being mistaken for optional arguments - file += '{'; - file += c; - file += '}'; + os << '{' << c << '}'; column += 2; break; @@ -3479,7 +3326,7 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, && font.family() != LyXFont::TYPEWRITER_FAMILY && GetChar(i + 1) == 'y' && GetChar(i + 2) == 'X') { - file += "\\LyX{}"; + os << "\\LyX{}"; i += 2; column += 5; } @@ -3489,7 +3336,7 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, && font.family() != LyXFont::TYPEWRITER_FAMILY && GetChar(i + 1) == 'e' && GetChar(i + 2) == 'X') { - file += "\\TeX{}"; + os << "\\TeX{}"; i += 2; column += 5; } @@ -3503,7 +3350,7 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, && GetChar(i + 4) == 'X' && GetChar(i + 5) == '2' && GetChar(i + 6) == 'e') { - file += "\\LaTeXe{}"; + os << "\\LaTeXe{}"; i += 6; column += 8; } @@ -3515,12 +3362,12 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, && GetChar(i + 2) == 'T' && GetChar(i + 3) == 'e' && GetChar(i + 4) == 'X') { - file += "\\LaTeX{}"; + os << "\\LaTeX{}"; i += 4; column += 7; /* idea for labels --- end*/ } else if (c != '\0') { - file += c; + os << c; } break; } @@ -3529,6 +3376,7 @@ void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow, } +#if 0 bool LyXParagraph::RoffContTableRows(ostream & os, LyXParagraph::size_type i, int actcell) @@ -3536,7 +3384,7 @@ bool LyXParagraph::RoffContTableRows(ostream & os, if (!table) return false; - LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT); + LyXFont font1(LyXFont::ALL_INHERIT); LyXFont font2; Inset * inset; char c; @@ -3569,33 +3417,38 @@ bool LyXParagraph::RoffContTableRows(ostream & os, switch (c) { case LyXParagraph::META_INSET: if ((inset = GetInset(i))) { - fstream fs(fname2.c_str(), - ios::in|ios::out); - if (!fs) { - WriteAlert(_("LYX_ERROR:"), - _("Cannot open temporary file:"), - fname2); - return false; +#ifdef HAVE_SSTREAM + stringstream ss(ios::in | ios::out); + inset->Ascii(ss); + ss.seekp(0); + ss.get(c); + while (!ss) { + if (c == '\\') + os << "\\\\"; + else + os << c; + ss.get(c); } - inset->Latex(fs, -1); - fs.seekp(0); - fs.get(c); - while (!fs) { +#else + strstream ss; + inset->Ascii(ss); + ss.seekp(0); + ss.get(c); + while (!ss) { if (c == '\\') os << "\\\\"; else os << c; - fs.get(c); + ss.get(c); } - fs.close(); + delete [] ss.str(); +#endif } break; case LyXParagraph::META_NEWLINE: break; case LyXParagraph::META_HFILL: break; - case LyXParagraph::META_PROTECTED_SEPARATOR: - break; case '\\': os << "\\\\"; break; @@ -3613,30 +3466,33 @@ bool LyXParagraph::RoffContTableRows(ostream & os, } return true; } +#endif -LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow, - string & foot, TexRow & foot_texrow, +LyXParagraph * LyXParagraph::TeXDeeper(ostream & os, TexRow & texrow, + ostream & foot, + TexRow & foot_texrow, int & foot_count) { lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl; LyXParagraph * par = this; - while (par && par->depth == depth) { + while (par && + (par->depth == depth) && + (par->footnoteflag == footnoteflag)) { if (par->IsDummy()) lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl; if (textclasslist.Style(current_view->buffer()->params.textclass, par->layout).isEnvironment() - || par->pextra_type != PEXTRA_NONE) - { - par = par->TeXEnvironment(file, texrow, - foot, foot_texrow, - foot_count); - } else { - par = par->TeXOnePar(file, texrow, - foot, foot_texrow, - foot_count); - } + || par->pextra_type != PEXTRA_NONE) { + par = par->TeXEnvironment(os, texrow, + foot, foot_texrow, + foot_count); + } else { + par = par->TeXOnePar(os, texrow, false, + foot, foot_texrow, + foot_count); + } } lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl; @@ -3644,8 +3500,9 @@ LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow, } -LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, - string & foot, TexRow & foot_texrow, +LyXParagraph * LyXParagraph::TeXEnvironment(ostream & os, TexRow & texrow, + ostream & foot, + TexRow & foot_texrow, int & foot_count) { bool eindent_open = false; @@ -3659,32 +3516,33 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, if (IsDummy()) lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, - layout); + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + layout); if (pextra_type == PEXTRA_INDENT) { if (!pextra_width.empty()) { - file += "\\begin{LyXParagraphIndent}{" - + pextra_width + "}\n"; + os << "\\begin{LyXParagraphIndent}{" + << pextra_width << "}\n"; } else { //float ib = atof(pextra_widthp.c_str())/100; // string can't handle floats at present (971109) // so I'll do a conversion by hand knowing that // the limits are 0.0 to 1.0. ARRae. - file += "\\begin{LyXParagraphIndent}{"; + os << "\\begin{LyXParagraphIndent}{"; switch (pextra_widthp.length()) { case 3: - file += "1.00"; + os << "1.00"; break; case 2: - file += "0."; - file += pextra_widthp; + os << "0." + << pextra_widthp; break; case 1: - file += "0.0"; - file += pextra_widthp; + os << "0.0" + << pextra_widthp; } - file += "\\columnwidth}\n"; + os << "\\columnwidth}\n"; } texrow.newline(); eindent_open = true; @@ -3692,51 +3550,50 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) { if (pextra_hfill && Previous() && (Previous()->pextra_type == PEXTRA_MINIPAGE)) { - file += "\\hfill{}\n"; + os << "\\hfill{}\n"; texrow.newline(); } if (par_sep == BufferParams::PARSEP_INDENT) { - file += "{\\setlength\\parindent{0pt}\n"; + os << "{\\setlength\\parindent{0pt}\n"; texrow.newline(); } - file += "\\begin{minipage}"; + os << "\\begin{minipage}"; switch(pextra_alignment) { case MINIPAGE_ALIGN_TOP: - file += "[t]"; + os << "[t]"; break; case MINIPAGE_ALIGN_MIDDLE: - file += "[m]"; + os << "[m]"; break; case MINIPAGE_ALIGN_BOTTOM: - file += "[b]"; + os << "[b]"; break; } if (!pextra_width.empty()) { - file += '{'; - file += pextra_width + "}\n"; + os << '{' << pextra_width << "}\n"; } else { //float ib = atof(par->pextra_width.c_str())/100; // string can't handle floats at present // so I'll do a conversion by hand knowing that // the limits are 0.0 to 1.0. ARRae. - file += '{'; + os << '{'; switch (pextra_widthp.length()) { case 3: - file += "1.00"; + os << "1.00"; break; case 2: - file += "0."; - file += pextra_widthp; + os << "0." + << pextra_widthp; break; case 1: - file += "0.0"; - file += pextra_widthp; + os << "0.0" + << pextra_widthp; } - file += "\\columnwidth}\n"; + os << "\\columnwidth}\n"; } texrow.newline(); if (par_sep == BufferParams::PARSEP_INDENT) { - file += "\\setlength\\parindent{\\LyXMinipageIndent}\n"; + os << "\\setlength\\parindent{\\LyXMinipageIndent}\n"; texrow.newline(); } minipage_open = true; @@ -3758,12 +3615,13 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, foot_this_level = true; } #endif - file += "\\begin{" + style.latexname() + "}{" - + labelwidthstring + "}\n"; + os << "\\begin{" << style.latexname() << "}{" + << labelwidthstring << "}\n"; } else if (style.labeltype == LABEL_BIBLIO) { // ale970405 - file += "\\begin{" + style.latexname() + "}{" - + bibitemWidthest() + "}\n"; + os << "\\begin{" << style.latexname() << "}{" + << bibitemWidthest(current_view->painter()) + << "}\n"; } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) { #ifdef FANCY_FOOTNOTE_CODE if (foot_count < 0) { @@ -3773,25 +3631,25 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, foot_this_level = true; } #endif - file += "\\begin{" + style.latexname() + '}' - + style.latexparam() + '\n'; + os << "\\begin{" << style.latexname() << '}' + << style.latexparam() << '\n'; } else - file += "\\begin{" + style.latexname() + '}' - + style.latexparam() + '\n'; + os << "\\begin{" << style.latexname() << '}' + << style.latexparam() << '\n'; texrow.newline(); } LyXParagraph * par = this; do { - par = par->TeXOnePar(file, texrow, + par = par->TeXOnePar(os, texrow, false, foot, foot_texrow, foot_count); if (minipage_open && par && !style.isEnvironment() && (par->pextra_type == PEXTRA_MINIPAGE) && par->pextra_start_minipage) { - file += "\\end{minipage}\n"; + os << "\\end{minipage}\n"; texrow.newline(); if (par_sep == BufferParams::PARSEP_INDENT) { - file += "}\n"; + os << "}\n"; texrow.newline(); } minipage_open = false; @@ -3800,69 +3658,72 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, if (textclasslist.Style(current_view->buffer()->params.textclass, par->layout).isParagraph() && !par->table - && !suffixIs(file, "\n\n")) { + // Thinko! + // How to handle this? (Lgb) + //&& !suffixIs(os, "\n\n") + ) { // There should be at least one '\n' already // but we need there to be two for Standard // paragraphs that are depth-increment'ed to be // output correctly. However, tables can // also be paragraphs so don't adjust them. // ARRae - file += '\n'; + // Thinkee: + // Will it ever harm to have one '\n' too + // many? i.e. that we sometimes will have + // three in a row. (Lgb) + os << '\n'; texrow.newline(); } - par = par->TeXDeeper(file, texrow, + par = par->TeXDeeper(os, texrow, foot, foot_texrow, foot_count); } if (par && par->layout == layout && par->depth == depth && (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) { if (par->pextra_hfill && par->Previous() && (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){ - file += "\\hfill{}\n"; + os << "\\hfill{}\n"; texrow.newline(); } if (par_sep == BufferParams::PARSEP_INDENT) { - file += "{\\setlength\\parindent{0pt}\n"; + os << "{\\setlength\\parindent{0pt}\n"; texrow.newline(); } - file += "\\begin{minipage}"; + os << "\\begin{minipage}"; switch(par->pextra_alignment) { case MINIPAGE_ALIGN_TOP: - file += "[t]"; + os << "[t]"; break; case MINIPAGE_ALIGN_MIDDLE: - file += "[m]"; + os << "[m]"; break; case MINIPAGE_ALIGN_BOTTOM: - file += "[b]"; + os << "[b]"; break; } if (!par->pextra_width.empty()) { - file += '{'; - file += par->pextra_width; - file += "}\n"; + os << '{' << par->pextra_width << "}\n"; } else { //float ib = atof(par->pextra_widthp.c_str())/100; // string can't handle floats at present // so I'll do a conversion by hand knowing that // the limits are 0.0 to 1.0. ARRae. - file += '{'; + os << '{'; switch (par->pextra_widthp.length()) { case 3: - file += "1.00"; + os << "1.00"; break; case 2: - file += "0."; - file += par->pextra_widthp; + os << "0." << par->pextra_widthp; break; case 1: - file += "0.0"; - file += par->pextra_widthp; + os << "0.0" << par->pextra_widthp; } - file += "\\columnwidth}\n"; + os << "\\columnwidth}\n"; } texrow.newline(); if (par_sep == BufferParams::PARSEP_INDENT) { - file += "\\setlength\\parindent{\\LyXMinipageIndent}\n"; + os << "\\setlength\\parindent{\\LyXMinipageIndent}\n"; texrow.newline(); } minipage_open = true; @@ -3871,19 +3732,20 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, } while (par && par->layout == layout && par->depth == depth - && par->pextra_type == pextra_type); + && par->pextra_type == pextra_type + && par->footnoteflag == footnoteflag); if (style.isEnvironment()) { - file += "\\end{" + style.latexname() + '}'; + os << "\\end{" << style.latexname() << '}'; // maybe this should go after the minipage closes? if (foot_this_level) { if (foot_count >= 1) { if (foot_count > 1) { - file += "\\addtocounter{footnote}{-"; - file += tostr(foot_count - 1); - file += '}'; + os << "\\addtocounter{footnote}{-" + << foot_count - 1 + << '}'; } - file += foot; + os << foot; texrow += foot_texrow; foot.clear(); foot_texrow.reset(); @@ -3894,26 +3756,26 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, if (minipage_open && (minipage_open_depth == depth) && (!par || par->pextra_start_minipage || par->pextra_type != PEXTRA_MINIPAGE)) { - file += "\\end{minipage}\n"; + os << "\\end{minipage}\n"; texrow.newline(); if (par_sep == BufferParams::PARSEP_INDENT) { - file += "}\n"; + os << "}\n"; texrow.newline(); } if (par && par->pextra_type != PEXTRA_MINIPAGE) { - file += "\\medskip\n\n"; + os << "\\medskip\n\n"; texrow.newline(); texrow.newline(); } minipage_open = false; } if (eindent_open) { - file += "\\end{LyXParagraphIndent}\n"; + os << "\\end{LyXParagraphIndent}\n"; texrow.newline(); } if (!(par && (par->pextra_type == PEXTRA_MINIPAGE) && par->pextra_hfill)) { - file += '\n'; + os << '\n'; texrow.newline(); } lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl; @@ -3921,9 +3783,10 @@ LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow, } -LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, - string & foot, TexRow & foot_texrow, - int & foot_count) +LyXParagraph * LyXParagraph::TeXFootnote(ostream & os, TexRow & texrow, + ostream & foot, TexRow & foot_texrow, + int & foot_count, + bool parent_is_rtl) { lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl; if (footnoteflag == LyXParagraph::NO_FOOTNOTE) @@ -3931,8 +3794,9 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, "No footnote!" << endl; LyXParagraph * par = this; - LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, - previous->GetLayout()); + LyXLayout const & style = + textclasslist.Style(current_view->buffer()->params.textclass, + previous->GetLayout()); if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){ lyxerr << "ERROR (LyXParagraph::TeXFootnote): " @@ -3942,38 +3806,57 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, if (footnotekind != LyXParagraph::FOOTNOTE && footnotekind != LyXParagraph::MARGIN - && file.length() - && !suffixIs(file, '\n')) { + && os.tellp() + // Thinko + // How to solve this? + //&& !suffixIs(file, '\n') + ) { // we need to ensure that real floats like tables and figures // have their \begin{} on a new line otherwise we can get // incorrect results when using the endfloat.sty package // especially if two floats follow one another. ARRae 981022 // NOTE: if the file is length 0 it must have just been // written out so we assume it ended with a '\n' - file += '\n'; + // Thinkee: + // As far as I can see there is never any harm in writing + // a '\n' too much. Please tell me if I am wrong. (Lgb) + os << '\n'; texrow.newline(); } + + bool moving_arg = false; + bool need_closing = false; + bool is_rtl = isRightToLeftPar(); + + if (is_rtl != parent_is_rtl) { + if (is_rtl) + os << "\\R{"; + else + os << "\\L{"; + need_closing = true; + } BufferParams * params = ¤t_view->buffer()->params; bool footer_in_body = true; switch (footnotekind) { case LyXParagraph::FOOTNOTE: if (style.intitle) { - file += "\\thanks{\n"; + os << "\\thanks{\n"; footer_in_body = false; + moving_arg = true; } else { if (foot_count == -1) { // we're at depth 0 so we can use: - file += "\\footnote{%\n"; + os << "\\footnote{%\n"; footer_in_body = false; } else { - file += "\\footnotemark{}%\n"; + os << "\\footnotemark{}%\n"; if (foot_count) { // we only need this when there are // multiple footnotes - foot += "\\stepcounter{footnote}"; + os << "\\stepcounter{footnote}"; } - foot += "\\footnotetext{%\n"; + os << "\\footnotetext{%\n"; foot_texrow.start(this, 0); foot_texrow.newline(); ++foot_count; @@ -3981,75 +3864,67 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, } break; case LyXParagraph::MARGIN: - file += "\\marginpar{\n"; + os << "\\marginpar{\n"; break; case LyXParagraph::FIG: if (pextra_type == PEXTRA_FLOATFLT && (!pextra_width.empty() || !pextra_widthp.empty())) { - char bufr[80]; if (!pextra_width.empty()) - sprintf(bufr, "\\begin{floatingfigure}{%s}\n", - pextra_width.c_str()); + os << "\\begin{floatingfigure}{" + << pextra_width << "}\n"; else - sprintf(bufr, - "\\begin{floatingfigure}{%f\\textwidth}\n", - atoi(pextra_widthp.c_str())/100.0); - file += bufr; + os << "\\begin{floatingfigure}{" + << atoi(pextra_widthp.c_str())/100.0 + << "\\textwidth}\n"; } else { - file += "\\begin{figure}"; + os << "\\begin{figure}"; if (!params->float_placement.empty()) { - file += '['; - file += params->float_placement; - file += "]\n"; + os << '[' << params->float_placement << "]\n"; } else { - file += '\n'; + os << '\n'; } } break; case LyXParagraph::TAB: - file += "\\begin{table}"; + os << "\\begin{table}"; if (!params->float_placement.empty()) { - file += '['; - file += params->float_placement; - file += "]\n"; + os << '[' << params->float_placement << "]\n"; } else { - file += '\n'; + os << '\n'; } break; case LyXParagraph::WIDE_FIG: - file += "\\begin{figure*}"; + os << "\\begin{figure*}"; if (!params->float_placement.empty()) { - file += '['; - file += params->float_placement; - file += "]\n"; + os << '[' << params->float_placement << "]\n"; } else { - file += '\n'; + os << '\n'; } break; case LyXParagraph::WIDE_TAB: - file += "\\begin{table*}"; + os << "\\begin{table*}"; if (!params->float_placement.empty()) { - file += '['; - file += params->float_placement; - file += "]\n"; + os << '[' << params->float_placement << "]\n"; } else { - file += '\n'; + os << '\n'; } break; case LyXParagraph::ALGORITHM: - file += "\\begin{algorithm}\n"; + os << "\\begin{algorithm}\n"; break; } texrow.newline(); - if (footnotekind != LyXParagraph::FOOTNOTE + if (footnotekind != LyXParagraph::FOOTNOTE || !footer_in_body) { // Process text for all floats except footnotes in body do { LyXLayout const & style = - textclasslist.Style(current_view->buffer()->params.textclass, - par->layout); + textclasslist + .Style(current_view->buffer()->params + .textclass, + par->layout); if (par->IsDummy()) lyxerr << "ERROR (LyXParagraph::TeXFootnote)" << endl; @@ -4059,17 +3934,17 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, // environments. Shouldn't be circular because // we don't support footnotes inside // floats (yet). ARRae - par = par->TeXEnvironment(file, texrow, + par = par->TeXEnvironment(os, texrow, foot, foot_texrow, foot_count); } else { - par = par->TeXOnePar(file, texrow, + par = par->TeXOnePar(os, texrow, moving_arg, foot, foot_texrow, foot_count); } if (par && !par->IsDummy() && par->depth > depth) { - par = par->TeXDeeper(file, texrow, + par = par->TeXDeeper(os, texrow, foot, foot_texrow, foot_count); } @@ -4078,13 +3953,19 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, // process footnotes > depth 0 or in environments separately // NOTE: Currently don't support footnotes within footnotes // even though that is possible using the \footnotemark - string dummy; +#ifdef HAVE_SSTREAM + std::ostringstream dummy; +#else + ostrstream dummy; +#endif TexRow dummy_texrow; int dummy_count = 0; do { LyXLayout const & style = - textclasslist.Style(current_view->buffer()->params.textclass, - par->layout); + textclasslist + .Style(current_view->buffer()->params + .textclass, + par->layout); if (par->IsDummy()) lyxerr << "ERROR (LyXParagraph::TeXFootnote)" << endl; @@ -4099,6 +3980,7 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, dummy_count); } else { par = par->TeXOnePar(foot, foot_texrow, + moving_arg, dummy, dummy_texrow, dummy_count); } @@ -4115,6 +3997,9 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, "Footnote in a Footnote -- not supported" << endl; } +#ifndef HAVE_OSTREAM + delete [] dummy.str(); +#endif } switch (footnotekind) { @@ -4122,43 +4007,46 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, if (footer_in_body) { // This helps tell which of the multiple // footnotetexts an error was in. - foot += "}%\n"; + foot << "}%\n"; foot_texrow.newline(); } else { - file += '}'; + os << '}'; } break; case LyXParagraph::MARGIN: - file += '}'; + os << '}'; break; case LyXParagraph::FIG: if (pextra_type == PEXTRA_FLOATFLT && (!pextra_width.empty() || !pextra_widthp.empty())) - file += "\\end{floatingfigure}"; + os << "\\end{floatingfigure}"; else - file += "\\end{figure}"; + os << "\\end{figure}"; break; case LyXParagraph::TAB: - file += "\\end{table}"; + os << "\\end{table}"; break; case LyXParagraph::WIDE_FIG: - file += "\\end{figure*}"; + os << "\\end{figure*}"; break; case LyXParagraph::WIDE_TAB: - file += "\\end{table*}"; + os << "\\end{table*}"; break; case LyXParagraph::ALGORITHM: - file += "\\end{algorithm}"; + os << "\\end{algorithm}"; break; } + if (need_closing) + os << "}"; + if (footnotekind != LyXParagraph::FOOTNOTE && footnotekind != LyXParagraph::MARGIN) { // we need to ensure that real floats like tables and figures // have their \end{} on a line of their own otherwise we can // get incorrect results when using the endfloat.sty package. - file += "\n"; + os << "\n"; texrow.newline(); } @@ -4167,6 +4055,13 @@ LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow, } +bool LyXParagraph::IsDummy() const +{ + return (footnoteflag == LyXParagraph::NO_FOOTNOTE && previous + && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE); +} + + void LyXParagraph::SetPExtraType(int type, char const * width, char const * widthp) { @@ -4214,8 +4109,8 @@ void LyXParagraph::UnsetPExtraType() return; pextra_type = PEXTRA_NONE; - pextra_width.clear(); - pextra_widthp.clear(); + pextra_width.erase(); + pextra_widthp.erase(); if (textclasslist.Style(current_view->buffer()->params.textclass, layout).isEnvironment()) { @@ -4239,8 +4134,8 @@ void LyXParagraph::UnsetPExtraType() while (par && (par->layout == layout) && (par->depth == depth)) { par->pextra_type = PEXTRA_NONE; - par->pextra_width.clear(); - par->pextra_widthp.clear(); + par->pextra_width.erase(); + par->pextra_widthp.erase(); par = par->NextAfterFootnote(); if (par && (par->depth > depth)) par->UnsetPExtraType(); @@ -4271,10 +4166,7 @@ bool LyXParagraph::IsFloat(size_type pos) const bool LyXParagraph::IsNewline(size_type pos) const { - bool tmp = false; - if (pos >= 0) - tmp = IsNewlineChar(GetChar(pos)); - return tmp; + return pos >= 0 && IsNewlineChar(GetChar(pos)); } @@ -4306,7 +4198,7 @@ bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const if( c == '\0') return false; // We want to pass the ' and escape chars to ispell - string extra = lyxrc->isp_esc_chars + '\''; + string extra = lyxrc.isp_esc_chars + '\''; char ch[2]; ch[0] = c; ch[1] = 0; @@ -4318,3 +4210,124 @@ bool LyXParagraph::IsWord(size_type pos ) const { return IsWordChar(GetChar(pos)) ; } + + +Language const * LyXParagraph::getParLanguage() const +{ + if (size() > 0) + if (!table) + return FirstPhysicalPar()->GetFirstFontSettings() + .language(); + else { + for (size_type pos = 0; pos < size(); ++pos) + if (IsNewline(pos)) + return GetFontSettings(pos).language(); + return GetFirstFontSettings().language(); + } + else if (previous) + return previous->getParLanguage(); + else + return current_view->buffer()->params.language_info; +} + + +bool LyXParagraph::isRightToLeftPar() const +{ + return lyxrc.rtl_support && !table && getParLanguage()->RightToLeft; +} + + +void LyXParagraph::ChangeLanguage(Language const * from, Language const * to) +{ + for(size_type i = 0; i < size(); ++i) { + LyXFont font = GetFontSettings(i); + if (font.language() == from) { + font.setLanguage(to); + SetFont(i, font); + } + } +} + + +bool LyXParagraph::isMultiLingual() +{ + Language const * doc_language = + current_view->buffer()->params.language_info; + for(size_type i = 0; i < size(); ++i) { + LyXFont font = GetFontSettings(i); + if (font.language() != doc_language) + return true; + } + return false; +} + + +// Convert the paragraph to a string. +// Used for building the table of contents +string LyXParagraph::String(bool label) +{ + string s; + if (label && !IsDummy()) + s += labelstring + ' '; + string::size_type len = s.size(); + + for (LyXParagraph::size_type i = 0; i < size(); ++i) { + unsigned char c = GetChar(i); + if (IsPrintable(c)) + s += c; + else if (c == META_INSET && + GetInset(i)->LyxCode() == Inset::MATH_CODE) { +#ifdef HAVE_SSTREAM + std::ostringstream ost; + GetInset(i)->Ascii(ost); +#else + ostrstream ost; + GetInset(i)->Ascii(ost); + ost << '\0'; +#endif + s += subst(ost.str(),'\n',' '); + } + } + + if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) + s += NextAfterFootnote()->String(false); + + if (!IsDummy()) { + if (isRightToLeftPar()) + reverse(s.begin() + len,s.end()); + } + return s; +} + + +string LyXParagraph::String(LyXParagraph::size_type beg, + LyXParagraph::size_type end) +{ + string s; + + for (LyXParagraph::size_type i = beg; i < end; ++i) { + unsigned char c = GetChar(i); + if (IsPrintable(c)) + s += c; + else if (c == META_INSET) { +#ifdef HAVE_SSTREAM + std::ostringstream ost; + GetInset(i)->Ascii(ost); +#else + ostrstream ost; + GetInset(i)->Ascii(ost); + ost << '\0'; +#endif + s += subst(ost.str(),'\n',' '); + } + } + + if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) + s += NextAfterFootnote()->String(false); + + if (!IsDummy()) { + if (isRightToLeftPar()) + reverse(s.begin(), s.end()); + } + return s; +}