1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
14 #pragma implementation "lyxparagraph.h"
21 #include "lyxparagraph.h"
22 #include "support/textutils.h"
25 #include "tex-strings.h"
26 #include "bufferparams.h"
27 #include "support/FileInfo.h"
28 #include "support/LAssert.h"
30 #include "LaTeXFeatures.h"
31 #include "insets/insetinclude.h"
32 #include "support/filetools.h"
33 #include "lyx_gui_misc.h"
37 extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
38 extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
39 int tex_code_break_column = 72; // needs non-zero initialization. set later.
40 // this is a bad idea, but how can LyXParagraph find its buffer to get
41 // parameters? (JMarc)
42 extern BufferView * current_view;
47 extern string bibitemWidthest();
49 /* this is a minibuffer */
50 static char minibuffer_char;
51 static LyXFont minibuffer_font;
52 static Inset * minibuffer_inset;
55 // Initialization of the counter for the paragraph id's,
56 // declared in lyxparagraph.h
57 unsigned int LyXParagraph::paragraph_id = 0;
60 LyXParagraph::LyXParagraph()
62 text.reserve(500); // is this number too big?
64 for (int i = 0; i < 10; ++i) setCounter(i , 0);
74 footnoteflag = LyXParagraph::NO_FOOTNOTE;
76 align = LYX_ALIGN_BLOCK;
78 /* table stuff -- begin*/
80 /* table stuff -- end*/
82 bibkey = 0; // ale970302
87 /* this konstruktor inserts the new paragraph in a list */
88 LyXParagraph::LyXParagraph(LyXParagraph * par)
91 par->text.resize(par->text.size());
93 for (int i = 0; i < 10; ++i) setCounter(i, 0);
99 next->previous = this;
101 previous->next = this;
106 footnoteflag = LyXParagraph::NO_FOOTNOTE;
107 footnotekind = LyXParagraph::FOOTNOTE;
109 /* table stuff -- begin*/
111 /* table stuff -- end*/
112 id_ = paragraph_id++;
114 bibkey = 0; // ale970302
120 void LyXParagraph::writeFile(ostream & os, BufferParams & params,
121 char footflag, char dth)
123 LyXFont font1, font2;
129 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
131 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
133 /* The beginning or the end of a footnote environment? */
134 if (footflag != footnoteflag) {
135 footflag = footnoteflag;
137 os << "\n\\begin_float "
138 << string_footnotekinds[footnotekind]
142 os << "\n\\end_float ";
146 /* The beginning or end of a deeper (i.e. nested) area? */
149 while (depth > dth) {
150 os << "\n\\begin_deeper ";
155 while (depth < dth) {
156 os << "\n\\end_deeper ";
162 /* First write the layout */
164 << textclasslist.NameOfLayout(params.textclass, layout)
167 /* maybe some vertical spaces */
168 if (added_space_top.kind() != VSpace::NONE)
169 os << "\\added_space_top "
170 << added_space_top.asLyXCommand() << " ";
171 if (added_space_bottom.kind() != VSpace::NONE)
172 os << "\\added_space_bottom "
173 << added_space_bottom.asLyXCommand() << " ";
175 /* The labelwidth string used in lists */
176 if (!labelwidthstring.empty())
177 os << "\\labelwidthstring "
178 << labelwidthstring << '\n';
180 /* Lines above or below? */
184 os << "\\line_bottom ";
186 /* Pagebreaks above or below? */
188 os << "\\pagebreak_top ";
189 if (pagebreak_bottom)
190 os << "\\pagebreak_bottom ";
192 /* Start of appendix? */
193 if (start_of_appendix)
194 os << "\\start_of_appendix ";
201 if (align != LYX_ALIGN_LAYOUT) {
203 case LYX_ALIGN_LEFT: h = 1; break;
204 case LYX_ALIGN_RIGHT: h = 2; break;
205 case LYX_ALIGN_CENTER: h = 3; break;
206 default: h = 0; break;
208 os << "\\align " << string_align[h] << " ";
210 if (pextra_type != PEXTRA_NONE) {
211 os << "\\pextra_type " << pextra_type;
212 if (pextra_type == PEXTRA_MINIPAGE) {
213 os << " \\pextra_alignment "
216 os << " \\pextra_hfill "
218 if (pextra_start_minipage)
219 os << " \\pextra_start_minipage "
220 << pextra_start_minipage;
222 if (!pextra_width.empty()) {
223 os << " \\pextra_width "
224 << VSpace(pextra_width).asLyXCommand();
225 } else if (!pextra_widthp.empty()) {
226 os << " \\pextra_widthp "
233 /* Dummy layout. This means that a footnote ended */
234 os << "\n\\end_float ";
235 footflag = LyXParagraph::NO_FOOTNOTE;
238 /* It might be a table */
240 os << "\\LyXTable\n";
248 font1 = LyXFont(LyXFont::ALL_INHERIT);
251 for (size_type i = 0; i < size(); i++) {
257 // Write font changes
258 font2 = GetFontSettings(i);
259 if (font2 != font1) {
260 font2.lyxWriteChanges(font1, os);
270 if (inset->DirectWrite()) {
271 // international char, let it write
272 // code directly so it's shorter in
276 os << "\n\\begin_inset ";
278 os << "\n\\end_inset \n\n";
283 os << "\n\\newline \n";
287 os << "\n\\hfill \n";
290 case META_PROTECTED_SEPARATOR:
291 os << "\n\\protected_separator \n";
295 os << "\n\\backslash \n";
299 if (i + 1 < size() && GetChar(i + 1) == ' ') {
306 if ((column > 70 && c == ' ')
311 // this check is to amend a bug. LyX sometimes
312 // inserts '\0' this could cause problems.
316 lyxerr << "ERROR (LyXParagraph::writeFile):"
317 " NULL char in structure." << endl;
323 // now write the next paragraph
325 next->writeFile(os, params, footflag, dth);
329 void LyXParagraph::validate(LaTeXFeatures & features)
331 // this will be useful later
332 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
336 if (line_top || line_bottom)
337 features.lyxline = true;
340 features.layout[GetLayout()] = true;
343 for (FontList::const_iterator cit = fontlist.begin();
344 cit != fontlist.end(); ++cit) {
345 if ((*cit).font.noun() == LyXFont::ON) {
346 lyxerr[Debug::LATEX] << "font.noun: "
347 << (*cit).font.noun()
349 features.noun = true;
350 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
351 << (*cit).font.stateText()
354 switch ((*cit).font.color()) {
356 case LyXFont::INHERIT_COLOR:
357 case LyXFont::IGNORE_COLOR: break;
359 features.color = true;
360 lyxerr[Debug::LATEX] << "Color enabled. Font: "
361 << (*cit).font.stateText()
367 FontTable * tmpfonttable = fonttable;
368 while (tmpfonttable) {
369 if (tmpfonttable->font.noun() == LyXFont::ON) {
370 lyxerr[Debug::LATEX] << "font.noun: "
371 << tmpfonttable->font.noun()
373 features.noun = true;
374 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
375 << tmpfonttable->font.stateText()
378 switch (tmpfonttable->font.color()) {
380 case LyXFont::INHERIT_COLOR:
381 case LyXFont::IGNORE_COLOR:
384 features.color = true;
385 lyxerr[Debug::LATEX] << "Color enabled. Font: "
386 << tmpfonttable->font.stateText()
389 tmpfonttable = tmpfonttable->next;
393 for (InsetList::const_iterator cit = insetlist.begin();
394 cit != insetlist.end(); ++cit) {
395 (*cit).inset->Validate(features);
399 InsetTable * tmpinsettable = insettable;
400 while (tmpinsettable) {
401 if (tmpinsettable->inset) {
402 tmpinsettable->inset->Validate(features);
404 tmpinsettable = tmpinsettable->next;
407 if (table && table->IsLongTable())
408 features.longtable = true;
409 if (pextra_type == PEXTRA_INDENT)
410 features.LyXParagraphIndent = true;
411 if (pextra_type == PEXTRA_FLOATFLT)
412 features.floatflt = true;
413 if (layout.needprotect
414 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
415 features.NeedLyXFootnoteCode = true;
416 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
417 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
418 features.NeedLyXMinipageIndent = true;
419 if (table && table->NeedRotating())
420 features.rotating = true;
421 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
422 features.algorithm = true;
426 /* first few functions needed for cut and paste and paragraph breaking */
427 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const
429 minibuffer_char = GetChar(pos);
430 minibuffer_font = GetFontSettings(pos);
431 minibuffer_inset = 0;
432 if (minibuffer_char == LyXParagraph::META_INSET) {
434 minibuffer_inset = GetInset(pos)->Clone();
436 minibuffer_inset = 0;
437 minibuffer_char = ' ';
438 // This reflects what GetInset() does (ARRae)
443 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
445 minibuffer_char = GetChar(pos);
446 minibuffer_font = GetFontSettings(pos);
447 minibuffer_inset = 0;
448 if (minibuffer_char == LyXParagraph::META_INSET) {
450 minibuffer_inset = GetInset(pos);
451 // This is a little hack since I want exactly
452 // the inset, not just a clone. Otherwise
453 // the inset would be deleted when calling Erase(pos)
455 for (InsetList::iterator it = insetlist.begin();
456 it != insetlist.end(); ++it) {
457 if ((*it).pos == pos) {
464 InsetTable * tmpi = insettable;
465 while (tmpi && tmpi->pos != pos) {
468 if (tmpi) { /* This should always be true */
473 minibuffer_inset = 0;
474 minibuffer_char = ' ';
475 // This reflects what GetInset() does (ARRae)
480 /* Erase(pos); now the caller is responsible for that*/
484 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
486 InsertChar(pos, minibuffer_char);
487 SetFont(pos, minibuffer_font);
488 if (minibuffer_char == LyXParagraph::META_INSET)
489 InsertInset(pos, minibuffer_inset);
492 /* end of minibuffer */
496 void LyXParagraph::Clear()
501 pagebreak_top = false;
502 pagebreak_bottom = false;
504 added_space_top = VSpace(VSpace::NONE);
505 added_space_bottom = VSpace(VSpace::NONE);
507 align = LYX_ALIGN_LAYOUT;
511 pextra_type = PEXTRA_NONE;
512 pextra_width.clear();
513 pextra_widthp.clear();
514 pextra_alignment = MINIPAGE_ALIGN_TOP;
515 pextra_hfill = false;
516 pextra_start_minipage = false;
519 labelwidthstring.clear();
523 start_of_appendix = false;
527 /* the destructor removes the new paragraph from the list */
528 LyXParagraph::~LyXParagraph()
531 previous->next = next;
533 next->previous = previous;
536 InsetTable * tmpinset;
538 tmpinset = insettable;
539 insettable = insettable->next;
541 delete tmpinset->inset;
543 if (insettable && insettable->next == insettable) {
544 // somehow this recursion appears occasionally
545 // but I can't find where. This bandaid
546 // helps but isn't the best fix. (ARRae)
547 if (insettable->inset) {
548 delete insettable->inset;
558 fonttable = fonttable->next;
563 /* table stuff -- begin*/
566 /* table stuff -- end*/
574 void LyXParagraph::Erase(LyXParagraph::size_type pos)
576 /* > because last is the next unused position, and you can
577 * use it if you want */
579 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
580 NextAfterFootnote()->Erase(pos - text.size() - 1);
582 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
583 "position does not exist." << endl;
586 if (pos < size()) { // last is free for insertation, but should be empty
588 /* if it is an inset, delete the inset entry */
589 if (text[pos] == LyXParagraph::META_INSET) {
591 for(InsetList::iterator it = insetlist.begin();
592 it != insetlist.end(); ++it) {
593 if ((*it).pos == pos) {
601 /* if it is an inset, delete the inset entry */
602 if (text[pos] == LyXParagraph::META_INSET) {
604 InsetTable *tmpi = insettable;
605 InsetTable *tmpi2 = tmpi;
606 while (tmpi && tmpi->pos != pos) {
610 if (tmpi) { // this should always be true
611 if (tmpi->inset) // delete the inset if it exists
613 if (tmpi == insettable)
614 insettable = tmpi->next;
616 tmpi2->next = tmpi->next;
621 text.erase(text.begin() + pos);
623 /* erase entries in the tables */
624 for(FontList::iterator it = fontlist.begin();
625 it != fontlist.end(); ++it) {
626 if (pos >= (*it).pos && pos <= (*it).pos_end) {
627 if ((*it).pos == (*it).pos_end) {
634 /* update all other entries */
635 for(FontList::iterator it = fontlist.begin();
636 it != fontlist.end(); ++it) {
639 if ((*it).pos_end >= pos)
643 /* update the inset table */
644 for(InsetList::iterator it = insetlist.begin();
645 it != insetlist.end(); ++it) {
650 /* erase entries in the tables */
652 FontTable * tmp = fonttable;
653 FontTable * prev = 0;
654 while (tmp && !found) {
655 if (pos >= tmp->pos && pos <= tmp->pos_end)
663 if (found && tmp->pos == tmp->pos_end) {
664 /* if it is a multi-character font entry, we just make
665 * it smaller (see update below), otherwise we should
668 prev->next = tmp->next;
670 fonttable = tmp->next;
675 /* update all other entries */
681 if (tmp->pos_end >= pos)
686 /* update the inset table */
687 InsetTable * tmpi = insettable;
695 lyxerr << "ERROR (LyXParagraph::Erase): "
696 "can't erase non-existant char." << endl;
701 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
703 /* > because last is the next unused position, and you can
704 * use it if you want */
707 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
708 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
711 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
712 "position does not exist." << endl;
715 text.insert(text.begin() + pos, c);
717 // update the font table
718 for(FontList::iterator it = fontlist.begin();
719 it != fontlist.end(); ++it) {
720 if ((*it).pos >= pos)
722 if ((*it).pos_end >= pos)
725 // update the inset table
726 for(InsetList::iterator it = insetlist.begin();
727 it != insetlist.end(); ++it) {
728 if ((*it).pos >= pos)
732 /* update the font table */
733 FontTable * tmp = fonttable;
737 if (tmp->pos_end >= pos)
742 /* update the inset table */
743 InsetTable * tmpi = insettable;
745 if (tmpi->pos >= pos)
753 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
756 /* > because last is the next unused position, and you can
757 * use it if you want */
760 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
762 ->InsertInset(pos - text.size() - 1, inset);
764 lyxerr << "ERROR (LyXParagraph::InsertInset): "
765 "position does not exist: " << pos << endl;
768 if (text[pos] != LyXParagraph::META_INSET) {
769 lyxerr << "ERROR (LyXParagraph::InsertInset): "
770 "there is no LyXParagraph::META_INSET" << endl;
779 insetlist.push_back(tmp);
784 /* add a new entry in the inset table */
785 InsetTable * tmpi = new InsetTable;
788 tmpi->next = insettable;
795 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
799 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
800 return NextAfterFootnote()
801 ->GetInset(pos - text.size() - 1);
803 lyxerr << "ERROR (LyXParagraph::GetInset): "
804 "position does not exist: "
811 for(InsetList::iterator it = insetlist.begin();
812 it != insetlist.end(); ++it) {
813 if ((*it).pos == pos) {
817 lyxerr << "ERROR (LyXParagraph::GetInset): "
818 "Inset does not exist: " << pos << endl;
819 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
820 // Did this commenting out introduce a bug? So far I have not
821 // seen any, please enlighten me. (Lgb)
822 // My guess is that since the inset does not exist, we might
823 // as well replace it with a space to prevent crashes. (Asger)
827 InsetTable * tmpi = insettable;
829 while (tmpi && tmpi->pos != pos)
835 lyxerr << "ERROR (LyXParagraph::GetInset): "
836 "Inset does not exist: " << pos << endl;
837 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
838 // Did this commenting out introduce a bug? So far I have not
839 // seen any, please enlighten me. (Lgb)
840 // My guess is that since the inset does not exist, we might
841 // as well replace it with a space to prevent crashes. (Asger)
848 Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const
852 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
853 return NextAfterFootnote()
854 ->GetInset(pos - text.size() - 1);
856 lyxerr << "ERROR (LyXParagraph::GetInset): "
857 "position does not exist: "
864 for(InsetList::const_iterator cit = insetlist.begin();
865 cit != insetlist.end(); ++cit) {
866 if ((*cit).pos == pos) {
870 lyxerr << "ERROR (LyXParagraph::GetInset): "
871 "Inset does not exist: " << pos << endl;
872 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
873 // Did this commenting out introduce a bug? So far I have not
874 // seen any, please enlighten me. (Lgb)
875 // My guess is that since the inset does not exist, we might
876 // as well replace it with a space to prevent crashes. (Asger)
880 InsetTable * tmpi = insettable;
882 while (tmpi && tmpi->pos != pos)
888 lyxerr << "ERROR (LyXParagraph::GetInset): "
889 "Inset does not exist: " << pos << endl;
890 // in the const version we need to comment it out anyway...
891 //text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
892 // Did this commenting out introduce a bug? So far I have not
893 // seen any, please enlighten me. (Lgb)
894 // My guess is that since the inset does not exist, we might
895 // as well replace it with a space to prevent crashes. (Asger)
902 // Gets uninstantiated font setting at position.
903 // Optimized after profiling. (Asger)
904 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const
908 for(FontList::iterator it = fontlist.begin();
909 it != fontlist.end(); ++it) {
910 if (pos >= (*it).pos && pos <= (*it).pos_end)
914 FontTable * tmp = fonttable;
916 if (pos >= tmp->pos && pos <= tmp->pos_end)
922 /* > because last is the next unused position, and you can
923 * use it if you want */
924 else if (pos > size()) {
926 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
927 return NextAfterFootnote()
928 ->GetFontSettings(pos - text.size() - 1);
930 // Why is it an error to ask for the font of a
931 // position that does not exist? Would it be
932 // enough for this to be anable on debug?
933 // We want strict error checking, but it's ok to only
934 // have it when debugging. (Asger)
935 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
936 "position does not exist. "
937 << pos << " (" << static_cast<int>(pos)
941 return GetFontSettings(pos - 1);
943 return LyXFont(LyXFont::ALL_INHERIT);
947 // Gets the fully instantiated font at a given position in a paragraph
948 // This is basically the same function as LyXText::GetFont() in text2.C.
949 // The difference is that this one is used for generating the LaTeX file,
950 // and thus cosmetic "improvements" are disallowed: This has to deliver
951 // the true picture of the buffer. (Asger)
952 // If position is -1, we get the layout font of the paragraph.
953 // If position is -2, we get the font of the manual label of the paragraph.
954 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
957 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
959 LyXParagraph::size_type main_body = 0;
960 if (layout.labeltype == LABEL_MANUAL)
961 main_body = BeginningOfMainBody();
966 layoutfont = layout.labelfont;
968 layoutfont = layout.font;
969 tmpfont = GetFontSettings(pos);
970 tmpfont.realize(layoutfont);
972 // process layoutfont for pos == -1 and labelfont for pos < -1
974 tmpfont = layout.font;
976 tmpfont = layout.labelfont;
979 // check for environment font information
980 char par_depth = GetDepth();
981 LyXParagraph const * par = this;
982 while (par && par_depth && !tmpfont.resolved()) {
983 par = par->DepthHook(par_depth - 1);
985 tmpfont.realize(textclasslist.
986 Style(GetCurrentTextClass(),
987 par->GetLayout()).font);
988 par_depth = par->GetDepth();
992 tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
997 /// Returns the height of the highest font in range
998 LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
1000 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
1002 for(FontList::const_iterator cit = fontlist.begin();
1003 cit != fontlist.end(); ++cit) {
1004 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
1005 LyXFont::FONT_SIZE size = (*cit).font.size();
1006 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
1011 FontTable * tmp = fonttable;
1013 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
1014 LyXFont::FONT_SIZE size = tmp->font.size();
1015 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
1025 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
1032 /* > because last is the next unused position, and you can
1033 * use it if you want */
1034 else if (pos > size()) {
1035 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1036 return NextAfterFootnote()
1037 ->GetChar(pos - text.size() - 1);
1039 lyxerr << "ERROR (LyXParagraph::GetChar): "
1040 "position does not exist."
1041 << pos << " (" << static_cast<int>(pos)
1046 /* we should have a footnote environment */
1047 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1048 // Notice that LyX does request the
1049 // last char from time to time. (Asger)
1050 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1051 // "expected footnote." << endl;
1054 switch (next->footnotekind) {
1055 case LyXParagraph::FOOTNOTE:
1056 return LyXParagraph::META_FOOTNOTE;
1057 case LyXParagraph::MARGIN:
1058 return LyXParagraph::META_MARGIN;
1059 case LyXParagraph::FIG:
1060 case LyXParagraph::WIDE_FIG:
1061 return LyXParagraph::META_FIG;
1062 case LyXParagraph::TAB:
1063 case LyXParagraph::WIDE_TAB:
1064 return LyXParagraph::META_TAB;
1065 case LyXParagraph::ALGORITHM:
1066 return LyXParagraph::META_ALGORITHM;
1068 return '\0'; // to shut up gcc
1073 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1080 /* > because last is the next unused position, and you can
1081 * use it if you want */
1082 else if (pos > size()) {
1083 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1084 return NextAfterFootnote()
1085 ->GetChar(pos - text.size() - 1);
1087 lyxerr << "ERROR (LyXParagraph::GetChar): "
1088 "position does not exist."
1089 << pos << " (" << static_cast<int>(pos)
1094 /* we should have a footnote environment */
1095 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1096 // Notice that LyX does request the
1097 // last char from time to time. (Asger)
1098 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1099 // "expected footnote." << endl;
1102 switch (next->footnotekind) {
1103 case LyXParagraph::FOOTNOTE:
1104 return LyXParagraph::META_FOOTNOTE;
1105 case LyXParagraph::MARGIN:
1106 return LyXParagraph::META_MARGIN;
1107 case LyXParagraph::FIG:
1108 case LyXParagraph::WIDE_FIG:
1109 return LyXParagraph::META_FIG;
1110 case LyXParagraph::TAB:
1111 case LyXParagraph::WIDE_TAB:
1112 return LyXParagraph::META_TAB;
1113 case LyXParagraph::ALGORITHM:
1114 return LyXParagraph::META_ALGORITHM;
1116 return '\0'; // to shut up gcc
1121 // return an string of the current word, and the end of the word in lastpos.
1122 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1126 // the current word is defined as starting at the first character from
1127 // the immediate left of lastpospos which meets the definition of IsLetter(),
1128 // continuing to the last character to the right of this meeting
1135 // move back until we have a letter
1137 //there's no real reason to have firstpos & lastpos as
1138 //separate variables as this is written, but maybe someon
1139 // will want to return firstpos in the future.
1141 //since someone might have typed a punctuation first
1142 int firstpos = lastpos;
1144 while ((firstpos >= 0) && !IsLetter(firstpos))
1147 // now find the beginning by looking for a nonletter
1149 while ((firstpos>= 0) && IsLetter(firstpos))
1152 // the above is now pointing to the preceeding non-letter
1156 // so copy characters into theword until we get a nonletter
1157 // note that this can easily exceed lastpos, wich means
1158 // that if used in the middle of a word, the whole word
1161 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1168 LyXParagraph::size_type LyXParagraph::Last() const
1170 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1171 return text.size() + NextAfterFootnote()->Last() + 1;
1172 /* the 1 is the symbol
1179 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1181 /* > because last is the next unused position, and you can
1182 * use it if you want */
1185 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1186 return NextAfterFootnote()
1187 ->ParFromPos(pos - text.size() - 1);
1189 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1190 "position does not exist." << endl;
1198 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1200 /* > because last is the next unused position, and you can
1201 * use it if you want */
1204 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1205 return NextAfterFootnote()
1206 ->PositionInParFromPos(pos - text.size() - 1);
1209 "ERROR (LyXParagraph::PositionInParFromPos): "
1210 "position does not exist." << endl;
1218 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1219 LyXFont const & font)
1221 /* > because last is the next unused position, and you can
1222 * use it if you want */
1224 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1225 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1228 lyxerr << "ERROR (LyXParagraph::SetFont): "
1229 "position does not exist." << endl;
1233 LyXFont patternfont(LyXFont::ALL_INHERIT);
1235 // First, reduce font against layout/label font
1236 // Update: The SetCharFont() routine in text2.C already reduces font, so
1237 // we don't need to do that here. (Asger)
1238 // No need to simplify this because it will disappear in a new kernel. (Asger)
1240 // Next search font table
1241 for(FontList::iterator it = fontlist.begin();
1242 it != fontlist.end(); ++it) {
1243 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1245 // we found a font entry. maybe we have to
1246 // split it and create a new one
1248 if ((*it).pos != (*it).pos_end) {
1249 // more than one character
1250 if (pos == (*it).pos) {
1251 // maybe we could enlarge
1252 // the left fonttable
1253 for(FontList::iterator fit = fontlist.begin();
1254 fit != fontlist.end(); ++fit) {
1255 if (pos - 1 >= (*fit).pos
1256 && pos - 1 <= (*fit).pos_end
1257 && (*fit).font == font) {
1265 // Add a new entry in the
1266 // fonttable for the position
1269 tmp.pos_end = (*it).pos_end;
1270 tmp.font = (*it).font;
1271 (*it).pos_end = pos;
1272 fontlist.push_back(tmp);
1273 } else if (pos == (*it).pos_end) {
1274 // Add a new entry in the
1275 // fonttable for the position
1277 tmp.pos = (*it).pos;
1278 tmp.pos_end = (*it).pos_end - 1;
1279 tmp.font = (*it).font;
1280 (*it).pos = (*it).pos_end;
1281 fontlist.push_back(tmp);
1283 // Add a new entry in the
1284 // fonttable for the position
1286 tmp.pos = (*it).pos;
1287 tmp.pos_end = pos - 1;
1288 tmp.font = (*it).font;
1289 fontlist.push_back(tmp);
1292 tmp.pos_end = (*it).pos_end;
1293 tmp.font = (*it).font;
1294 fontlist.push_back(tmp);
1297 (*it).pos_end = pos;
1305 // if we did not find a font entry, but if the font at hand
1306 // is the same as default, we just forget it
1307 if (font == patternfont) return;
1309 // ok, we did not find a font entry. But maybe there is exactly
1310 // the needed font entry one position left
1311 for(FontList::iterator it = fontlist.begin();
1312 it != fontlist.end(); ++it) {
1313 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1314 && (*it).font == font) {
1319 // Add a new entry in the
1320 // fonttable for the position
1324 tmp.font = patternfont;
1325 fontlist.push_back(tmp);
1327 // Next search font table
1331 FontTable * tmp = fonttable;
1332 while (tmp && !found) {
1333 if (pos >= tmp->pos && pos <= tmp->pos_end)
1340 /* if we did not find a font entry, but if the font at hand
1341 * is the same as default, we just forget it */
1342 if (font == patternfont)
1345 /* ok, we did not find a font entry. But maybe there is exactly
1346 * the needed font entry one position left */
1349 while (tmp2 && !found) {
1350 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1356 /* ok there is one. maybe it is exactly the needed font */
1357 if (tmp2->font == font) {
1358 /* put the position under the font */
1363 /* Add a new entry in the
1364 * fonttable for the position */
1365 tmp = new FontTable;
1368 tmp->font = patternfont;
1369 tmp->next = fonttable;
1372 /* we found a font entry. maybe we have to split it and create
1375 if (tmp->pos != tmp->pos_end) { /* more than one character */
1377 if (pos == tmp->pos) {
1378 /* maybe we could enlarge the left fonttable */
1382 while (tmp2 && !found) {
1383 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1389 /* Is there is one, and is it exactly the needed font? */
1390 if (found && tmp2->font == font) {
1391 /* put the position under the font */
1397 /* Add a new entry in the
1398 * fonttable for the position */
1399 tmp2 = new FontTable;
1400 tmp2->pos = pos + 1;
1401 tmp2->pos_end = tmp->pos_end;
1402 tmp2->font = tmp->font;
1404 tmp2->next = fonttable;
1407 else if (pos == tmp->pos_end) {
1408 /* Add a new entry in the
1409 * fonttable for the position */
1410 tmp2 = new FontTable;
1411 tmp2->pos = tmp->pos;
1412 tmp2->pos_end = tmp->pos_end - 1;
1413 tmp2->font = tmp->font;
1414 tmp->pos = tmp->pos_end;
1415 tmp2->next = fonttable;
1419 /* Add a new entry in the
1420 * fonttable for the position */
1421 tmp2 = new FontTable;
1422 tmp2->pos = tmp->pos;
1423 tmp2->pos_end = pos - 1;
1424 tmp2->font = tmp->font;
1425 tmp2->next = fonttable;
1428 tmp2 = new FontTable;
1429 tmp2->pos = pos + 1;
1430 tmp2->pos_end = tmp->pos_end;
1431 tmp2->font = tmp->font;
1432 tmp2->next = fonttable;
1445 /* this function is able to hide closed footnotes */
1446 LyXParagraph * LyXParagraph::Next()
1448 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1449 LyXParagraph * tmp = next;
1451 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1453 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1454 return tmp->Next(); /* there can be more than one
1455 footnote in a logical
1458 return next; /* this should never happen! */
1465 LyXParagraph * LyXParagraph::NextAfterFootnote()
1467 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1468 LyXParagraph * tmp = next;
1469 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1471 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1472 return tmp; /* there can be more than one footnote
1473 in a logical paragraph */
1475 return next; /* this should never happen! */
1482 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1484 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1485 LyXParagraph * tmp = next;
1486 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1488 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1489 return tmp; /* there can be more than one footnote
1490 in a logical paragraph */
1492 return next; /* this should never happen! */
1499 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1502 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1504 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1505 tmp = tmp->previous;
1506 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1507 return tmp; /* there can be more than one footnote
1508 in a logical paragraph */
1510 return previous; /* this should never happen! */
1517 LyXParagraph * LyXParagraph::LastPhysicalPar()
1519 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1522 LyXParagraph * tmp = this;
1524 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1525 tmp = tmp->NextAfterFootnote();
1532 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1536 LyXParagraph * tmppar = this;
1538 while (tmppar && (tmppar->IsDummy()
1539 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1540 tmppar = tmppar->previous;
1543 return this; /* this should never happen! */
1549 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1553 LyXParagraph const * tmppar = this;
1555 while (tmppar && (tmppar->IsDummy()
1556 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1557 tmppar = tmppar->previous;
1560 return this; /* this should never happen! */
1566 /* this function is able to hide closed footnotes */
1567 LyXParagraph * LyXParagraph::Previous()
1569 LyXParagraph * tmp = previous;
1574 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1575 tmp = tmp->previous;
1577 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1578 tmp = tmp->previous;
1579 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1580 return tmp->next->Previous();
1590 /* this function is able to hide closed footnotes */
1591 LyXParagraph const * LyXParagraph::Previous() const
1593 LyXParagraph * tmp = previous;
1598 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1599 tmp = tmp->previous;
1601 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1602 tmp = tmp->previous;
1603 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1604 return tmp->next->Previous();
1614 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1617 size_type i, pos_end, pos_first;
1618 /* create a new paragraph */
1619 LyXParagraph * par = ParFromPos(pos);
1620 LyXParagraph * firstpar = FirstPhysicalPar();
1622 LyXParagraph * tmp = new LyXParagraph(par);
1624 tmp->footnoteflag = footnoteflag;
1625 tmp->footnotekind = footnotekind;
1627 /* this is an idea for a more userfriendly layout handling, I will
1628 * see what the users say */
1630 /* layout stays the same with latex-environments */
1632 tmp->SetOnlyLayout(firstpar->layout);
1633 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1636 if (Last() > pos || !Last() || flag == 2) {
1637 tmp->SetOnlyLayout(firstpar->layout);
1638 tmp->align = firstpar->align;
1639 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1641 tmp->line_bottom = firstpar->line_bottom;
1642 firstpar->line_bottom = false;
1643 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1644 firstpar->pagebreak_bottom = false;
1645 tmp->added_space_bottom = firstpar->added_space_bottom;
1646 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1648 tmp->depth = firstpar->depth;
1649 tmp->noindent = firstpar->noindent;
1651 /* copy everything behind the break-position
1652 to the new paragraph
1655 while (ParFromPos(pos_first) != par)
1658 pos_end = pos_first + par->text.size() - 1;
1659 tmp->text.reserve(pos_end - pos);
1661 for (i = pos; i <= pos_end; i++) {
1662 par->CutIntoMinibuffer(i - pos_first);
1663 tmp->InsertFromMinibuffer(i - pos);
1666 for (i = pos_end; i >= pos; i--)
1667 par->Erase(i - pos_first);
1669 par->text.resize(par->text.size());
1672 /* just an idea of me */
1674 tmp->line_top = firstpar->line_top;
1675 tmp->pagebreak_top = firstpar->pagebreak_top;
1676 tmp->added_space_top = firstpar->added_space_top;
1677 tmp->bibkey = firstpar->bibkey;
1679 /* layout stays the same with latex-environments */
1681 firstpar->SetOnlyLayout(tmp->layout);
1682 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1683 firstpar->depth = tmp->depth;
1689 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1691 par = par->FirstPhysicalPar();
1692 footnoteflag = par->footnoteflag;
1693 footnotekind = par->footnotekind;
1695 layout = par->layout;
1696 align = par-> align;
1697 SetLabelWidthString(par->labelwidthstring);
1699 line_bottom = par->line_bottom;
1700 pagebreak_bottom = par->pagebreak_bottom;
1701 added_space_bottom = par->added_space_bottom;
1703 line_top = par->line_top;
1704 pagebreak_top = par->pagebreak_top;
1705 added_space_top = par->added_space_top;
1707 pextra_type = par->pextra_type;
1708 pextra_width = par->pextra_width;
1709 pextra_widthp = par->pextra_widthp;
1710 pextra_alignment = par->pextra_alignment;
1711 pextra_hfill = par->pextra_hfill;
1712 pextra_start_minipage = par->pextra_start_minipage;
1714 noindent = par->noindent;
1719 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1721 LyXParagraph * tmppar = this;
1724 && tmppar->previous->footnoteflag ==
1725 LyXParagraph::CLOSED_FOOTNOTE)
1726 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1727 tmppar = tmppar->previous;
1730 return this; /* this should never happen! */
1736 LyXParagraph * LyXParagraph::Clone() const
1738 /* create a new paragraph */
1739 LyXParagraph * result = new LyXParagraph;
1741 result->MakeSameLayout(this);
1743 /* this is because of the dummy layout of the paragraphs that
1745 result->layout = layout;
1747 /* table stuff -- begin*/
1749 result->table = table->Clone();
1752 /* table stuff -- end*/
1755 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1758 /* copy everything behind the break-position to the new paragraph */
1760 for (size_type i = 0; i < size(); i++) {
1761 CopyIntoMinibuffer(i);
1762 result->InsertFromMinibuffer(i);
1764 result->text.resize(result->text.size());
1769 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1771 par = par->FirstPhysicalPar();
1774 par->footnoteflag == footnoteflag &&
1775 par->footnotekind == footnotekind &&
1777 par->layout == layout &&
1779 par->align == align &&
1781 par->line_bottom == line_bottom &&
1782 par->pagebreak_bottom == pagebreak_bottom &&
1783 par->added_space_bottom == added_space_bottom &&
1785 par->line_top == line_top &&
1786 par->pagebreak_top == pagebreak_top &&
1787 par->added_space_top == added_space_top &&
1789 par->pextra_type == pextra_type &&
1790 par->pextra_width == pextra_width &&
1791 par->pextra_widthp == pextra_widthp &&
1792 par->pextra_alignment == pextra_alignment &&
1793 par->pextra_hfill == pextra_hfill &&
1794 par->pextra_start_minipage == pextra_start_minipage &&
1796 par->table == table && // what means: NO TABLE AT ALL
1798 par->noindent == noindent &&
1799 par->depth == depth);
1803 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1805 size_type i, pos_end, pos_first;
1807 /* create a new paragraph */
1808 LyXParagraph * par = ParFromPos(pos);
1810 LyXParagraph * tmp = new LyXParagraph(par);
1812 tmp->MakeSameLayout(par);
1815 /* copy everything behind the break-position to the new
1818 while (ParFromPos(pos_first) != par)
1820 pos_end = pos_first + par->text.size() - 1;
1821 /* make shure there is enough memory for the now larger
1822 paragraph. This is not neccessary, because
1823 InsertFromMinibuffer will enlarge the memory (it uses
1824 InsertChar of course). But doing it by hand
1825 is MUCH faster! (only one time, not thousend times!!) */
1826 tmp->text.reserve(pos_end - pos);
1828 for (i = pos; i <= pos_end; i++) {
1830 par->CutIntoMinibuffer(i - pos_first);
1831 tmp->InsertFromMinibuffer(i - pos);
1833 for (i = pos_end; i >= pos; i--)
1834 par->Erase(i - pos_first);
1836 par->text.resize(par->text.size());
1841 /* be carefull, this does not make any check at all */
1842 void LyXParagraph::PasteParagraph()
1844 /* copy the next paragraph to this one */
1845 LyXParagraph * the_next = Next();
1847 LyXParagraph * firstpar = FirstPhysicalPar();
1849 /* first the DTP-stuff */
1850 firstpar->line_bottom = the_next->line_bottom;
1851 firstpar->added_space_bottom = the_next->added_space_bottom;
1852 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1854 size_type pos_end = the_next->text.size() - 1;
1855 size_type pos_insert = Last();
1858 /* ok, now copy the paragraph */
1859 for (i = 0; i <= pos_end; i++) {
1860 the_next->CutIntoMinibuffer(i);
1861 InsertFromMinibuffer(pos_insert + i);
1864 /* delete the next paragraph */
1869 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1871 LyXParagraph * par = ParFromPos(pos);
1873 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1874 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1880 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1882 LyXParagraph * par = ParFromPos(pos);
1884 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1885 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1891 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1893 return FirstPhysicalPar()->layout;
1897 char LyXParagraph::GetDepth() const
1899 return FirstPhysicalPar()->depth;
1903 char LyXParagraph::GetAlign() const
1905 return FirstPhysicalPar()->align;
1909 string LyXParagraph::GetLabestring() const
1911 return FirstPhysicalPar()->labelstring;
1915 int LyXParagraph::GetFirstCounter(int i) const
1917 return FirstPhysicalPar()->counter_[i];
1921 /* the next two functions are for the manual labels */
1922 string LyXParagraph::GetLabelWidthString() const
1924 if (!FirstPhysicalPar()->labelwidthstring.empty())
1925 return FirstPhysicalPar()->labelwidthstring;
1927 return _("Senseless with this layout!");
1931 void LyXParagraph::SetLabelWidthString(string const & s)
1933 LyXParagraph * par = FirstPhysicalPar();
1935 par->labelwidthstring = s;
1939 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1941 LyXParagraph * par = FirstPhysicalPar();
1942 LyXParagraph * ppar = 0;
1943 LyXParagraph * npar = 0;
1945 par->layout = new_layout;
1946 /* table stuff -- begin*/
1949 /* table stuff -- end*/
1950 if (par->pextra_type == PEXTRA_NONE) {
1951 if (par->Previous()) {
1952 ppar = par->Previous()->FirstPhysicalPar();
1955 && (ppar->depth > par->depth))
1956 ppar = ppar->Previous()->FirstPhysicalPar();
1959 npar = par->Next()->NextAfterFootnote();
1962 && (npar->depth > par->depth))
1963 npar = npar->Next()->NextAfterFootnote();
1965 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1967 p1 = ppar->pextra_width,
1968 p2 = ppar->pextra_widthp;
1969 ppar->SetPExtraType(ppar->pextra_type,
1970 p1.c_str(), p2.c_str());
1972 if ((par->pextra_type == PEXTRA_NONE) &&
1973 npar && (npar->pextra_type != PEXTRA_NONE)) {
1975 p1 = npar->pextra_width,
1976 p2 = npar->pextra_widthp;
1977 npar->SetPExtraType(npar->pextra_type,
1978 p1.c_str(), p2.c_str());
1984 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
1987 * par = FirstPhysicalPar(),
1991 par->layout = new_layout;
1992 par->labelwidthstring.clear();
1993 par->align = LYX_ALIGN_LAYOUT;
1994 par->added_space_top = VSpace(VSpace::NONE);
1995 par->added_space_bottom = VSpace(VSpace::NONE);
1996 /* table stuff -- begin*/
1999 /* table stuff -- end*/
2000 if (par->pextra_type == PEXTRA_NONE) {
2001 if (par->Previous()) {
2002 ppar = par->Previous()->FirstPhysicalPar();
2005 && (ppar->depth > par->depth))
2006 ppar = ppar->Previous()->FirstPhysicalPar();
2009 npar = par->Next()->NextAfterFootnote();
2012 && (npar->depth > par->depth))
2013 npar = npar->Next()->NextAfterFootnote();
2015 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2017 p1 = ppar->pextra_width,
2018 p2 = ppar->pextra_widthp;
2019 ppar->SetPExtraType(ppar->pextra_type,
2020 p1.c_str(), p2.c_str());
2022 if ((par->pextra_type == PEXTRA_NONE) &&
2023 npar && (npar->pextra_type != PEXTRA_NONE)) {
2025 p1 = npar->pextra_width,
2026 p2 = npar->pextra_widthp;
2027 npar->SetPExtraType(npar->pextra_type,
2028 p1.c_str(), p2.c_str());
2034 /* if the layout of a paragraph contains a manual label, the beginning of the
2035 * main body is the beginning of the second word. This is what the par-
2036 * function returns. If the layout does not contain a label, the main
2037 * body always starts with position 0. This differentiation is necessary,
2038 * because there cannot be a newline or a blank <= the beginning of the
2039 * main body in TeX. */
2041 int LyXParagraph::BeginningOfMainBody() const
2043 if (FirstPhysicalPar() != this)
2046 // Unroll the first two cycles of the loop
2047 // and remember the previous character to
2048 // remove unnecessary GetChar() calls
2051 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2053 char previous_char, temp;
2055 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2056 // Yes, this ^ is supposed to be "= " not "=="
2059 && previous_char != ' '
2060 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2062 previous_char = temp;
2067 if (i == 0 && i == size() &&
2068 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2069 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2070 i++; /* the cursor should not jump
2071 * to the main body if there
2077 LyXParagraph * LyXParagraph::DepthHook(int deth)
2079 LyXParagraph * newpar = this;
2084 newpar = newpar->FirstPhysicalPar()->Previous();
2085 } while (newpar && newpar->GetDepth() > deth
2086 && newpar->footnoteflag == footnoteflag);
2089 if (Previous() || GetDepth())
2090 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2094 return newpar->FirstPhysicalPar();
2098 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2100 LyXParagraph const * newpar = this;
2105 newpar = newpar->FirstPhysicalPar()->Previous();
2106 } while (newpar && newpar->GetDepth() > deth
2107 && newpar->footnoteflag == footnoteflag);
2110 if (Previous() || GetDepth())
2111 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2115 return newpar->FirstPhysicalPar();
2119 int LyXParagraph::AutoDeleteInsets()
2123 for (InsetList::iterator it = insetlist.begin();
2124 it != insetlist.end(); ++it) {
2125 if ((*it).inset->AutoDelete()) {
2132 InsetTable * tmpi = insettable;
2133 InsetTable * tmpi2 = tmpi;
2139 if (tmpi2->inset->AutoDelete()) {
2144 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2145 "cannot auto-delete insets" << endl;
2152 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2155 InsetTable * tmp = 0;
2156 for (InsetList::iterator it = insetlist.begin();
2157 it != insetlist.end(); ++it) {
2158 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2169 InsetTable * tmpi = insettable;
2170 InsetTable * tmpi2 = 0;
2172 if (tmpi->pos >= pos) {
2173 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2180 return tmpi2->inset;
2188 /* returns -1 if inset not found */
2189 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2192 for (InsetList::iterator it = insetlist.begin();
2193 it != insetlist.end(); ++it) {
2194 if ((*it).inset == inset) {
2198 // Think about footnotes
2199 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2200 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2201 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2203 return size() + 1 + further;
2207 /* find the entry */
2208 InsetTable * tmpi = insettable;
2209 while (tmpi && tmpi->inset != inset) {
2212 if (tmpi && tmpi->inset)
2215 /* think about footnotes */
2216 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2217 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2219 NextAfterFootnote()->GetPositionOfInset(inset);
2221 return text.size() + 1 + further;
2229 void LyXParagraph::readSimpleWholeFile(istream & is)
2235 InsertChar(text.size(), c);
2240 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2241 string & foot, TexRow & foot_texrow,
2244 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2245 LyXParagraph * par = next;
2246 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2249 bool further_blank_line = false;
2251 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2253 if (start_of_appendix) {
2254 file += "\\appendix\n";
2258 if (tex_code_break_column && style.isCommand()){
2263 if (pagebreak_top) {
2264 file += "\\newpage";
2265 further_blank_line = true;
2267 if (added_space_top.kind() != VSpace::NONE) {
2268 file += added_space_top.asLatexCommand();
2269 further_blank_line = true;
2273 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2274 file += "\\vspace{-1\\parskip}";
2275 further_blank_line = true;
2278 if (further_blank_line){
2283 switch (style.latextype) {
2286 file += style.latexname();
2287 file += style.latexparam();
2289 case LATEX_ITEM_ENVIRONMENT:
2291 bibkey->Latex(file, false);
2295 case LATEX_LIST_ENVIRONMENT:
2302 bool need_par = SimpleTeXOnePar(file, texrow);
2304 // Spit out footnotes
2305 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2306 && par->footnoteflag != footnoteflag) {
2307 par = par->TeXFootnote(file, texrow,
2308 foot, foot_texrow, foot_count);
2309 par->SimpleTeXOnePar(file, texrow);
2313 // Make sure that \\par is done with the font of the last
2314 // character if this has another size as the default.
2315 // This is necessary because LaTeX (and LyX on the screen)
2316 // calculates the space between the baselines according
2317 // to this font. (Matthias)
2318 LyXFont font = getFont(Last()-1);
2320 if (style.resfont.size() != font.size()) {
2322 file += font.latexSize();
2326 } else if (textclasslist.Style(GetCurrentTextClass(),
2327 GetLayout()).isCommand()){
2328 if (style.resfont.size() != font.size()) {
2330 file += font.latexSize();
2334 } else if (style.resfont.size() != font.size()){
2335 file += "{\\" + font.latexSize() + " \\par}";
2338 switch (style.latextype) {
2339 case LATEX_ITEM_ENVIRONMENT:
2340 case LATEX_LIST_ENVIRONMENT:
2341 if (par && (depth < par->depth)) {
2346 case LATEX_ENVIRONMENT:
2347 // if its the last paragraph of the current environment
2348 // skip it otherwise fall through
2350 && (par->layout != layout
2351 || par->depth != depth
2352 || par->pextra_type != pextra_type))
2355 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2356 && footnotekind != LyXParagraph::FOOTNOTE
2357 && footnotekind != LyXParagraph::MARGIN
2361 // don't insert this if we would be adding it
2362 // before or after a table in a float. This
2363 // little trick is needed in order to allow
2364 // use of tables in \subfigures or \subtables.
2370 further_blank_line = false;
2372 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2373 further_blank_line = true;
2376 if (added_space_bottom.kind() != VSpace::NONE) {
2377 file += added_space_bottom.asLatexCommand();
2378 further_blank_line = true;
2381 if (pagebreak_bottom) {
2382 file += "\\newpage";
2383 further_blank_line = true;
2386 if (further_blank_line){
2391 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2392 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2397 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2402 // This one spits out the text of the paragraph
2403 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2405 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2408 return SimpleTeXOneTablePar(file, texrow);
2411 size_type main_body;
2413 bool return_value = false;
2415 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2418 /* maybe we have to create a optional argument */
2419 if (style.labeltype != LABEL_MANUAL)
2422 main_body = BeginningOfMainBody();
2424 if (main_body > 0) {
2426 basefont = getFont(-2); // Get label font
2428 basefont = getFont(-1); // Get layout font
2436 if (style.isCommand()) {
2439 } else if (align != LYX_ALIGN_LAYOUT) {
2442 return_value = true;
2446 // Which font is currently active?
2447 LyXFont running_font = basefont;
2448 // Do we have an open font change?
2449 bool open_font = false;
2451 texrow.start(this, 0);
2453 for (size_type i = 0; i < size(); ++i) {
2455 // First char in paragraph or after label?
2456 if (i == main_body && !IsDummy()) {
2457 if (main_body > 0) {
2459 column += running_font.latexWriteEndChanges(file, basefont);
2462 basefont = getFont(-1); // Now use the layout font
2463 running_font = basefont;
2467 if (style.isCommand()) {
2470 } else if (align != LYX_ALIGN_LAYOUT) {
2473 return_value = true;
2477 file += "\\noindent ";
2481 case LYX_ALIGN_NONE:
2482 case LYX_ALIGN_BLOCK:
2483 case LYX_ALIGN_LAYOUT:
2484 case LYX_ALIGN_SPECIAL: break;
2485 case LYX_ALIGN_LEFT:
2486 file += "\\raggedright ";
2489 case LYX_ALIGN_RIGHT:
2490 file += "\\raggedleft ";
2493 case LYX_ALIGN_CENTER:
2494 file += "\\centering ";
2502 // Fully instantiated font
2503 LyXFont font = getFont(i);
2505 // Spaces at end of font change are simulated to be
2506 // outside font change, i.e. we write "\textXX{text} "
2507 // rather than "\textXX{text }". (Asger)
2508 if (open_font && c == ' ' && i <= size() - 2
2509 && !getFont(i+1).equalExceptLatex(running_font)
2510 && !getFont(i+1).equalExceptLatex(font)) {
2511 font = getFont(i+1);
2513 // We end font definition before blanks
2514 if (!font.equalExceptLatex(running_font) && open_font) {
2515 column += running_font.latexWriteEndChanges(file,
2517 running_font = basefont;
2521 // Blanks are printed before start of fontswitch
2523 // Do not print the separation of the optional argument
2524 if (i != main_body - 1) {
2525 SimpleTeXBlanks(file, texrow, i,
2526 column, font, style);
2530 // Do we need to change font?
2531 if (!font.equalExceptLatex(running_font)
2532 && i != main_body-1) {
2533 column += font.latexWriteStartChanges(file, basefont);
2534 running_font = font;
2538 if (c == LyXParagraph::META_NEWLINE) {
2539 // newlines are handled differently here than
2540 // the default in SimpleTeXSpecialChars().
2541 if (!style.newline_allowed
2542 || font.latex() == LyXFont::ON) {
2546 column += running_font.latexWriteEndChanges(file, basefont);
2549 basefont = getFont(-1);
2550 running_font = basefont;
2551 if (font.family() ==
2552 LyXFont::TYPEWRITER_FAMILY) {
2558 texrow.start(this, i+1);
2561 SimpleTeXSpecialChars(file, texrow,
2562 font, running_font, basefont,
2563 open_font, style, i, column, c);
2567 // If we have an open font definition, we have to close it
2569 running_font.latexWriteEndChanges(file, basefont);
2572 /* needed if there is an optional argument but no contents */
2573 if (main_body > 0 && main_body == size()) {
2575 return_value = false;
2578 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2579 return return_value;
2583 // This one spits out the text of a table paragraph
2584 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2586 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2590 bool return_value = false;
2591 int current_cell_number = -1;
2593 LyXLayout const & style =
2594 textclasslist.Style(GetCurrentTextClass(), GetLayout());
2595 LyXFont basefont = getFont(-1); // Get layout font
2596 // Which font is currently active?
2597 LyXFont running_font = basefont;
2598 // Do we have an open font change?
2599 bool open_font = false;
2602 if (!IsDummy()) { // it is dummy if it is in a float!!!
2603 if (style.isCommand()) {
2606 } else if (align != LYX_ALIGN_LAYOUT) {
2609 return_value = true;
2612 file += "\\noindent ";
2616 case LYX_ALIGN_NONE:
2617 case LYX_ALIGN_BLOCK:
2618 case LYX_ALIGN_LAYOUT:
2619 case LYX_ALIGN_SPECIAL: break;
2620 case LYX_ALIGN_LEFT:
2621 file += "\\raggedright ";
2624 case LYX_ALIGN_RIGHT:
2625 file += "\\raggedleft ";
2628 case LYX_ALIGN_CENTER:
2629 file += "\\centering ";
2634 current_cell_number = -1;
2635 tmp = table->TexEndOfCell(file, current_cell_number);
2636 for (; tmp > 0 ; --tmp)
2639 texrow.start(this, 0);
2641 for (size_type i = 0; i < size(); ++i) {
2643 if (table->IsContRow(current_cell_number+1)) {
2644 if (c == LyXParagraph::META_NEWLINE)
2645 current_cell_number++;
2650 // Fully instantiated font
2651 LyXFont font = getFont(i);
2653 // Spaces at end of font change are simulated to be
2654 // outside font change.
2655 // i.e. we write "\textXX{text} " rather than
2656 // "\textXX{text }". (Asger)
2657 if (open_font && c == ' ' && i <= size() - 2
2658 && getFont(i+1) != running_font && getFont(i+1) != font) {
2659 font = getFont(i+1);
2662 // We end font definition before blanks
2663 if (font != running_font && open_font) {
2664 column += running_font.latexWriteEndChanges(file,
2666 running_font = basefont;
2669 // Blanks are printed before start of fontswitch
2671 SimpleTeXBlanks(file, texrow, i, column, font, style);
2673 // Do we need to change font?
2674 if (font != running_font) {
2675 column += font.latexWriteStartChanges(file, basefont);
2676 running_font = font;
2679 // Do we need to turn on LaTeX mode?
2680 if (font.latex() != running_font.latex()) {
2681 if (font.latex() == LyXFont::ON
2682 && style.needprotect) {
2683 file += "\\protect ";
2687 if (c == LyXParagraph::META_NEWLINE) {
2688 // special case for inside a table
2689 // different from default case in
2690 // SimpleTeXSpecialChars()
2692 column += running_font
2693 .latexWriteEndChanges(file, basefont);
2696 basefont = getFont(-1);
2697 running_font = basefont;
2698 current_cell_number++;
2699 if (table->CellHasContRow(current_cell_number) >= 0) {
2700 TeXContTableRows(file, i+1,
2701 current_cell_number,
2704 // if this cell follow only ContRows till end don't
2705 // put the EndOfCell because it is put after the
2707 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2708 current_cell_number--;
2711 int tmp = table->TexEndOfCell(file,
2712 current_cell_number);
2715 } else if (tmp < 0) {
2721 texrow.start(this, i+1);
2723 SimpleTeXSpecialChars(file, texrow,
2724 font, running_font, basefont,
2725 open_font, style, i, column, c);
2729 // If we have an open font definition, we have to close it
2731 running_font.latexWriteEndChanges(file, basefont);
2733 current_cell_number++;
2734 tmp = table->TexEndOfCell(file, current_cell_number);
2735 for (; tmp > 0; --tmp)
2737 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2738 return return_value;
2742 // This one spits out the text off ContRows in tables
2743 bool LyXParagraph::TeXContTableRows(string & file,
2744 LyXParagraph::size_type i,
2745 int current_cell_number,
2746 int & column, TexRow & texrow)
2748 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2754 bool return_value = false;
2755 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2759 basefont = getFont(-1); // Get layout font
2760 // Which font is currently active?
2761 LyXFont running_font = basefont;
2762 // Do we have an open font change?
2763 bool open_font = false;
2765 size_type lastpos = i;
2766 int cell = table->CellHasContRow(current_cell_number);
2767 ++current_cell_number;
2769 // first find the right position
2771 for (; (i < size()) && (current_cell_number<cell); ++i) {
2773 if (c == LyXParagraph::META_NEWLINE)
2774 current_cell_number++;
2778 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2782 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2787 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2791 // Fully instantiated font
2792 LyXFont font = getFont(i);
2794 // Spaces at end of font change are simulated to
2795 // be outside font change. i.e. we write
2796 // "\textXX{text} " rather than "\textXX{text }".
2798 if (open_font && c == ' ' && i <= size() - 2
2799 && getFont(i + 1) != running_font
2800 && getFont(i + 1) != font) {
2801 font = getFont(i + 1);
2804 // We end font definition before blanks
2805 if (font != running_font && open_font) {
2806 column += running_font.latexWriteEndChanges(file, basefont);
2807 running_font = basefont;
2810 // Blanks are printed before start of fontswitch
2812 SimpleTeXBlanks(file, texrow, i,
2813 column, font, style);
2815 // Do we need to change font?
2816 if (font != running_font) {
2818 font.latexWriteStartChanges(file,
2820 running_font = font;
2823 // Do we need to turn on LaTeX mode?
2824 if (font.latex() != running_font.latex()) {
2825 if (font.latex() == LyXFont::ON
2826 && style.needprotect)
2828 file += "\\protect ";
2832 SimpleTeXSpecialChars(file, texrow, font,
2833 running_font, basefont,
2834 open_font, style, i, column, c);
2836 // If we have an open font definition, we have to close it
2838 running_font.latexWriteEndChanges(file, basefont);
2841 basefont = getFont(-1);
2842 running_font = basefont;
2843 cell = table->CellHasContRow(current_cell_number);
2845 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2846 return return_value;
2850 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2852 bool retval = false;
2854 case LyXParagraph::META_HFILL:
2855 sgml_string.clear();
2857 case LyXParagraph::META_PROTECTED_SEPARATOR:
2860 case LyXParagraph::META_NEWLINE:
2864 sgml_string = "&";
2867 sgml_string = "<";
2870 sgml_string = ">";
2873 sgml_string = "$";
2876 sgml_string = "#";
2879 sgml_string = "%";
2882 sgml_string = "[";
2885 sgml_string = "]";
2888 sgml_string = "{";
2891 sgml_string = "}";
2894 sgml_string = "˜";
2897 sgml_string = """;
2900 sgml_string = "\";
2906 case '\0': /* Ignore :-) */
2907 sgml_string.clear();
2917 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2918 int & desc_on, int depth)
2921 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2923 LyXFont font1, font2;
2926 size_type main_body;
2927 string emph = "emphasis";
2928 bool emph_flag = false;
2930 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2933 if (style.labeltype != LABEL_MANUAL)
2936 main_body = BeginningOfMainBody();
2938 /* gets paragraph main font */
2940 font1 = style.labelfont;
2944 int char_line_count = depth;
2945 addNewlineAndDepth(file, depth);
2946 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2947 file += "<INFORMALTABLE>";
2948 addNewlineAndDepth(file, ++depth);
2950 int current_cell_number = -1;
2951 int tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2953 /* parsing main loop */
2954 for (size_type i = 0; i < size(); ++i) {
2956 if (table->IsContRow(current_cell_number+1)) {
2957 if (c == LyXParagraph::META_NEWLINE)
2958 ++current_cell_number;
2963 // Fully instantiated font
2966 /* handle <emphasis> tag */
2967 if (font1.emph() != font2.emph() && i) {
2968 if (font2.emph() == LyXFont::ON) {
2969 file += "<emphasis>";
2971 } else if (emph_flag) {
2972 file += "</emphasis>";
2976 if (c == LyXParagraph::META_NEWLINE) {
2977 // we have only to control for emphasis open here!
2979 file += "</emphasis>";
2982 font1 = font2 = getFont(-1);
2983 current_cell_number++;
2984 if (table->CellHasContRow(current_cell_number) >= 0) {
2985 DocBookContTableRows(file, extra, desc_on, i+1,
2986 current_cell_number,
2989 // if this cell follow only ContRows till end don't
2990 // put the EndOfCell because it is put after the
2992 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2993 current_cell_number--;
2996 tmp= table->DocBookEndOfCell(file, current_cell_number,
3001 } else if (c == LyXParagraph::META_INSET) {
3002 inset = GetInset(i);
3004 inset->DocBook(tmp_out);
3006 // This code needs some explanation:
3007 // Two insets are treated specially
3008 // label if it is the first element in a
3009 // command paragraph
3011 // graphics inside tables or figure floats
3013 // title (the equivalente in latex for this
3015 // and title should come first
3018 if(desc_on != 3 || i != 0) {
3019 if(tmp_out[0] == '@') {
3021 extra += frontStrip(tmp_out,
3024 file += frontStrip(tmp_out,
3029 } else if (font2.latex() == LyXFont::ON) {
3030 // "TeX"-Mode on == > SGML-Mode on.
3036 if (linuxDocConvertChar(c, sgml_string)
3037 && !style.free_spacing) {
3038 // in freespacing mode, spaces are
3039 // non-breaking characters
3044 file += "</term><listitem><para>";
3050 file += sgml_string;
3056 /* needed if there is an optional argument but no contents */
3057 if (main_body > 0 && main_body == size()) {
3062 file += "</emphasis>";
3065 current_cell_number++;
3066 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3067 /* resets description flag correctly */
3070 /* <term> not closed... */
3074 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3075 file += "</INFORMALTABLE>";
3077 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3082 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3084 LyXParagraph::size_type i,
3085 int current_cell_number, int &column)
3090 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3093 LyXFont font1, font2;
3096 size_type main_body;
3098 string emph= "emphasis";
3099 bool emph_flag= false;
3100 int char_line_count= 0;
3102 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3105 if (style.labeltype != LABEL_MANUAL)
3108 main_body = BeginningOfMainBody();
3110 /* gets paragraph main font */
3112 font1 = style.labelfont;
3117 cell = table->CellHasContRow(current_cell_number);
3118 ++current_cell_number;
3120 // first find the right position
3122 for (; i < size() && current_cell_number < cell; ++i) {
3124 if (c == LyXParagraph::META_NEWLINE)
3125 current_cell_number++;
3129 // I don't know how to handle this so I comment it
3130 // for the moment (Jug)
3131 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3132 // file += " \\\\\n";
3135 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3140 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3144 // Fully instantiated font
3147 /* handle <emphasis> tag */
3148 if (font1.emph() != font2.emph() && i) {
3149 if (font2.emph() == LyXFont::ON) {
3150 file += "<emphasis>";
3152 } else if (emph_flag) {
3153 file += "</emphasis>";
3157 if (c == LyXParagraph::META_INSET) {
3158 inset = GetInset(i);
3160 inset->DocBook(tmp_out);
3162 // This code needs some explanation:
3163 // Two insets are treated specially
3164 // label if it is the first element in a command paragraph
3166 // graphics inside tables or figure floats can't go on
3167 // title (the equivalente in latex for this case is caption
3168 // and title should come first
3171 if(desc_on != 3 || i != 0) {
3172 if(tmp_out[0] == '@') {
3174 extra += frontStrip(tmp_out, '@');
3176 file += frontStrip(tmp_out, '@');
3180 } else if (font2.latex() == LyXFont::ON) {
3181 // "TeX"-Mode on == > SGML-Mode on.
3187 if (linuxDocConvertChar(c, sgml_string)
3188 && !style.free_spacing) {
3189 // in freespacing mode, spaces are
3190 // non-breaking characters
3195 file += "</term><listitem><para>";
3201 file += sgml_string;
3205 // we have only to control for emphasis open here!
3207 file += "</emphasis>";
3210 font1 = font2 = getFont(-1);
3211 cell = table->CellHasContRow(current_cell_number);
3213 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3217 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3218 LyXParagraph::size_type const i,
3219 int & column, LyXFont const & font,
3220 LyXLayout const & style)
3222 if (column > tex_code_break_column
3224 && GetChar(i - 1) != ' '
3226 // In LaTeX mode, we don't want to
3227 // break lines since some commands
3229 && ! (font.latex() == LyXFont::ON)
3230 // same in FreeSpacing mode
3231 && !style.free_spacing
3232 // In typewriter mode, we want to avoid
3233 // ! . ? : at the end of a line
3234 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3235 && (GetChar(i-1) == '.'
3236 || GetChar(i-1) == '?'
3237 || GetChar(i-1) == ':'
3238 || GetChar(i-1) == '!'))) {
3239 if (tex_code_break_column == 0) {
3240 // in batchmode we need LaTeX to still
3241 // see it as a space not as an extra '\n'
3247 texrow.start(this, i+1);
3249 } else if (font.latex() == LyXFont::OFF) {
3250 if (style.free_spacing) {
3259 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3261 LyXFont & running_font,
3264 LyXLayout const & style,
3265 LyXParagraph::size_type & i,
3266 int & column, char const c)
3268 // Two major modes: LaTeX or plain
3269 // Handle here those cases common to both modes
3270 // and then split to handle the two modes separately.
3272 case LyXParagraph::META_INSET: {
3273 Inset * inset = GetInset(i);
3275 int len = file.length();
3276 int tmp = inset->Latex(file, style.isCommand());
3281 column += file.length() - len;
3290 case LyXParagraph::META_NEWLINE:
3292 column += running_font.latexWriteEndChanges(file,
3296 basefont = getFont(-1);
3297 running_font = basefont;
3300 case LyXParagraph::META_HFILL:
3301 file += "\\hfill{}";
3306 // And now for the special cases within each mode
3307 // Are we in LaTeX mode?
3308 if (font.latex() == LyXFont::ON) {
3309 // at present we only have one option
3310 // but I'll leave it as a switch statement
3311 // so its simpler to extend. (ARRae)
3313 case LyXParagraph::META_PROTECTED_SEPARATOR:
3318 // make sure that we will not print
3319 // error generating chars to the tex
3320 // file. This test would not be needed
3321 // if it were done in the buffer
3329 // Plain mode (i.e. not LaTeX)
3331 case LyXParagraph::META_PROTECTED_SEPARATOR:
3336 file += "\\textbackslash{}";
3340 case '°': case '±': case '²': case '³':
3341 case '×': case '÷': case '¹': case 'ª':
3342 case 'º': case '¬': case 'µ':
3343 if (current_view->buffer()->params.inputenc == "latin1") {
3344 file += "\\ensuremath{";
3353 case '|': case '<': case '>':
3354 // In T1 encoding, these characters exist
3355 if (lyxrc->fontenc == "T1") {
3357 //... but we should avoid ligatures
3358 if ((c == '>' || c == '<')
3360 && GetChar(i+1) == c){
3361 file += "\\textcompwordmark{}";
3366 // Typewriter font also has them
3367 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3371 // Otherwise, we use what LaTeX
3375 file += "\\textless{}";
3379 file += "\\textgreater{}";
3383 file += "\\textbar{}";
3389 case '-': // "--" in Typewriter mode -> "-{}-"
3391 && GetChar(i + 1) == '-'
3392 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3401 file += "\\char`\\\"{}";
3406 if (current_view->buffer()->params.inputenc == "default") {
3407 file += "\\pounds{}";
3415 case '%': case '#': case '{':
3423 file += "\\textasciitilde{}";
3428 file += "\\textasciicircum{}";
3432 case '*': case '[': case ']':
3433 // avoid being mistaken for optional arguments
3441 /* blanks are printed before font switching */
3442 // Sure? I am not! (try nice-latex)
3443 // I am sure it's correct. LyX might be smarter
3444 // in the future, but for now, nothing wrong is
3449 /* idea for labels --- begin*/
3453 && font.family() != LyXFont::TYPEWRITER_FAMILY
3454 && GetChar(i + 1) == 'y'
3455 && GetChar(i + 2) == 'X') {
3463 && font.family() != LyXFont::TYPEWRITER_FAMILY
3464 && GetChar(i + 1) == 'e'
3465 && GetChar(i + 2) == 'X') {
3470 /* check for LaTeX2e */
3473 && font.family() != LyXFont::TYPEWRITER_FAMILY
3474 && GetChar(i + 1) == 'a'
3475 && GetChar(i + 2) == 'T'
3476 && GetChar(i + 3) == 'e'
3477 && GetChar(i + 4) == 'X'
3478 && GetChar(i + 5) == '2'
3479 && GetChar(i + 6) == 'e') {
3480 file += "\\LaTeXe{}";
3484 /* check for LaTeX */
3487 && font.family() != LyXFont::TYPEWRITER_FAMILY
3488 && GetChar(i + 1) == 'a'
3489 && GetChar(i + 2) == 'T'
3490 && GetChar(i + 3) == 'e'
3491 && GetChar(i + 4) == 'X') {
3492 file += "\\LaTeX{}";
3495 /* idea for labels --- end*/
3496 } else if (c != '\0') {
3506 bool LyXParagraph::RoffContTableRows(ostream & os,
3507 LyXParagraph::size_type i,
3513 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3518 string fname2 = TmpFileName(string(), "RAT2");
3520 int cell = table->CellHasContRow(actcell);
3523 // first find the right position
3525 for (; i < size() && actcell < cell; ++i) {
3527 if (c == LyXParagraph::META_NEWLINE)
3532 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3535 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3537 font2 = GetFontSettings(i);
3538 if (font1.latex() != font2.latex()) {
3539 if (font2.latex() != LyXFont::OFF)
3544 case LyXParagraph::META_INSET:
3545 if ((inset = GetInset(i))) {
3546 fstream fs(fname2.c_str(),
3549 WriteAlert(_("LYX_ERROR:"),
3550 _("Cannot open temporary file:"),
3554 inset->Latex(fs, -1);
3567 case LyXParagraph::META_NEWLINE:
3569 case LyXParagraph::META_HFILL:
3571 case LyXParagraph::META_PROTECTED_SEPARATOR:
3580 lyxerr.debug() << "RoffAsciiTable: "
3581 "NULL char in structure."
3586 cell = table->CellHasContRow(actcell);
3592 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3593 string & foot, TexRow & foot_texrow,
3596 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3597 LyXParagraph * par = this;
3599 while (par && par->depth == depth) {
3601 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3602 if (textclasslist.Style(GetCurrentTextClass(),
3603 par->layout).isEnvironment()
3604 || par->pextra_type != PEXTRA_NONE)
3606 par = par->TeXEnvironment(file, texrow,
3610 par = par->TeXOnePar(file, texrow,
3615 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3621 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3622 string & foot, TexRow & foot_texrow,
3625 bool eindent_open = false;
3626 bool foot_this_level = false;
3627 // flags when footnotetext should be appended to file.
3628 static bool minipage_open = false;
3629 static int minipage_open_depth = 0;
3630 char par_sep = current_view->buffer()->params.paragraph_separation;
3632 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3634 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3636 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3639 if (pextra_type == PEXTRA_INDENT) {
3640 if (!pextra_width.empty()) {
3641 file += "\\begin{LyXParagraphIndent}{"
3642 + pextra_width + "}\n";
3644 //float ib = atof(pextra_widthp.c_str())/100;
3645 // string can't handle floats at present (971109)
3646 // so I'll do a conversion by hand knowing that
3647 // the limits are 0.0 to 1.0. ARRae.
3648 file += "\\begin{LyXParagraphIndent}{";
3649 switch (pextra_widthp.length()) {
3655 file += pextra_widthp;
3659 file += pextra_widthp;
3661 file += "\\columnwidth}\n";
3664 eindent_open = true;
3666 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3667 if (pextra_hfill && Previous() &&
3668 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3669 file += "\\hfill{}\n";
3672 if (par_sep == BufferParams::PARSEP_INDENT) {
3673 file += "{\\setlength\\parindent{0pt}\n";
3676 file += "\\begin{minipage}";
3677 switch(pextra_alignment) {
3678 case MINIPAGE_ALIGN_TOP:
3681 case MINIPAGE_ALIGN_MIDDLE:
3684 case MINIPAGE_ALIGN_BOTTOM:
3688 if (!pextra_width.empty()) {
3690 file += pextra_width + "}\n";
3692 //float ib = atof(par->pextra_width.c_str())/100;
3693 // string can't handle floats at present
3694 // so I'll do a conversion by hand knowing that
3695 // the limits are 0.0 to 1.0. ARRae.
3697 switch (pextra_widthp.length()) {
3703 file += pextra_widthp;
3707 file += pextra_widthp;
3709 file += "\\columnwidth}\n";
3712 if (par_sep == BufferParams::PARSEP_INDENT) {
3713 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3716 minipage_open = true;
3717 minipage_open_depth = depth;
3720 #ifdef WITH_WARNINGS
3721 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3722 //I disabled it because it breaks when lists span on several
3725 if (style.isEnvironment()){
3726 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3727 #ifdef FANCY_FOOTNOTE_CODE
3728 if (foot_count < 0) {
3729 // flag that footnote[mark][text] should be
3730 // used for any footnotes from now on
3732 foot_this_level = true;
3735 file += "\\begin{" + style.latexname() + "}{"
3736 + labelwidthstring + "}\n";
3737 } else if (style.labeltype == LABEL_BIBLIO) {
3739 file += "\\begin{" + style.latexname() + "}{"
3740 + bibitemWidthest() + "}\n";
3741 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3742 #ifdef FANCY_FOOTNOTE_CODE
3743 if (foot_count < 0) {
3744 // flag that footnote[mark][text] should be
3745 // used for any footnotes from now on
3747 foot_this_level = true;
3750 file += "\\begin{" + style.latexname() + '}'
3751 + style.latexparam() + '\n';
3753 file += "\\begin{" + style.latexname() + '}'
3754 + style.latexparam() + '\n';
3757 LyXParagraph * par = this;
3759 par = par->TeXOnePar(file, texrow,
3760 foot, foot_texrow, foot_count);
3762 if (minipage_open && par && !style.isEnvironment() &&
3763 (par->pextra_type == PEXTRA_MINIPAGE) &&
3764 par->pextra_start_minipage) {
3765 file += "\\end{minipage}\n";
3767 if (par_sep == BufferParams::PARSEP_INDENT) {
3771 minipage_open = false;
3773 if (par && par->depth > depth) {
3774 if (textclasslist.Style(GetCurrentTextClass(),
3775 par->layout).isParagraph()
3777 && !suffixIs(file, "\n\n")) {
3778 // There should be at least one '\n' already
3779 // but we need there to be two for Standard
3780 // paragraphs that are depth-increment'ed to be
3781 // output correctly. However, tables can
3782 // also be paragraphs so don't adjust them.
3787 par = par->TeXDeeper(file, texrow,
3788 foot, foot_texrow, foot_count);
3790 if (par && par->layout == layout && par->depth == depth &&
3791 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3792 if (par->pextra_hfill && par->Previous() &&
3793 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3794 file += "\\hfill{}\n";
3797 if (par_sep == BufferParams::PARSEP_INDENT) {
3798 file += "{\\setlength\\parindent{0pt}\n";
3801 file += "\\begin{minipage}";
3802 switch(par->pextra_alignment) {
3803 case MINIPAGE_ALIGN_TOP:
3806 case MINIPAGE_ALIGN_MIDDLE:
3809 case MINIPAGE_ALIGN_BOTTOM:
3813 if (!par->pextra_width.empty()) {
3815 file += par->pextra_width;
3818 //float ib = atof(par->pextra_widthp.c_str())/100;
3819 // string can't handle floats at present
3820 // so I'll do a conversion by hand knowing that
3821 // the limits are 0.0 to 1.0. ARRae.
3823 switch (par->pextra_widthp.length()) {
3829 file += par->pextra_widthp;
3833 file += par->pextra_widthp;
3835 file += "\\columnwidth}\n";
3838 if (par_sep == BufferParams::PARSEP_INDENT) {
3839 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3842 minipage_open = true;
3843 minipage_open_depth = par->depth;
3846 && par->layout == layout
3847 && par->depth == depth
3848 && par->pextra_type == pextra_type);
3850 if (style.isEnvironment()) {
3851 file += "\\end{" + style.latexname() + '}';
3852 // maybe this should go after the minipage closes?
3853 if (foot_this_level) {
3854 if (foot_count >= 1) {
3855 if (foot_count > 1) {
3856 file += "\\addtocounter{footnote}{-";
3857 file += tostr(foot_count - 1);
3861 texrow += foot_texrow;
3863 foot_texrow.reset();
3868 if (minipage_open && (minipage_open_depth == depth) &&
3869 (!par || par->pextra_start_minipage ||
3870 par->pextra_type != PEXTRA_MINIPAGE)) {
3871 file += "\\end{minipage}\n";
3873 if (par_sep == BufferParams::PARSEP_INDENT) {
3877 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3878 file += "\\medskip\n\n";
3882 minipage_open = false;
3885 file += "\\end{LyXParagraphIndent}\n";
3888 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3889 && par->pextra_hfill)) {
3893 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3894 return par; // ale970302
3898 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3899 string & foot, TexRow & foot_texrow,
3902 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3903 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3904 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3905 "No footnote!" << endl;
3907 LyXParagraph * par = this;
3908 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3909 previous->GetLayout());
3911 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3912 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3913 "Float other than footnote in command"
3914 " with moving argument is illegal" << endl;
3917 if (footnotekind != LyXParagraph::FOOTNOTE
3918 && footnotekind != LyXParagraph::MARGIN
3920 && !suffixIs(file, '\n')) {
3921 // we need to ensure that real floats like tables and figures
3922 // have their \begin{} on a new line otherwise we can get
3923 // incorrect results when using the endfloat.sty package
3924 // especially if two floats follow one another. ARRae 981022
3925 // NOTE: if the file is length 0 it must have just been
3926 // written out so we assume it ended with a '\n'
3931 BufferParams * params = ¤t_view->buffer()->params;
3932 bool footer_in_body = true;
3933 switch (footnotekind) {
3934 case LyXParagraph::FOOTNOTE:
3935 if (style.intitle) {
3936 file += "\\thanks{\n";
3937 footer_in_body = false;
3939 if (foot_count == -1) {
3940 // we're at depth 0 so we can use:
3941 file += "\\footnote{%\n";
3942 footer_in_body = false;
3944 file += "\\footnotemark{}%\n";
3946 // we only need this when there are
3947 // multiple footnotes
3948 foot += "\\stepcounter{footnote}";
3950 foot += "\\footnotetext{%\n";
3951 foot_texrow.start(this, 0);
3952 foot_texrow.newline();
3957 case LyXParagraph::MARGIN:
3958 file += "\\marginpar{\n";
3960 case LyXParagraph::FIG:
3961 if (pextra_type == PEXTRA_FLOATFLT
3962 && (!pextra_width.empty()
3963 || !pextra_widthp.empty())) {
3965 if (!pextra_width.empty())
3966 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3967 pextra_width.c_str());
3970 "\\begin{floatingfigure}{%f\\textwidth}\n",
3971 atoi(pextra_widthp.c_str())/100.0);
3974 file += "\\begin{figure}";
3975 if (!params->float_placement.empty()) {
3977 file += params->float_placement;
3984 case LyXParagraph::TAB:
3985 file += "\\begin{table}";
3986 if (!params->float_placement.empty()) {
3988 file += params->float_placement;
3994 case LyXParagraph::WIDE_FIG:
3995 file += "\\begin{figure*}";
3996 if (!params->float_placement.empty()) {
3998 file += params->float_placement;
4004 case LyXParagraph::WIDE_TAB:
4005 file += "\\begin{table*}";
4006 if (!params->float_placement.empty()) {
4008 file += params->float_placement;
4014 case LyXParagraph::ALGORITHM:
4015 file += "\\begin{algorithm}\n";
4020 if (footnotekind != LyXParagraph::FOOTNOTE
4021 || !footer_in_body) {
4022 // Process text for all floats except footnotes in body
4024 LyXLayout const & style =
4025 textclasslist.Style(GetCurrentTextClass(),
4028 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4030 if (style.isEnvironment()
4031 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4032 // Allows the use of minipages within float
4033 // environments. Shouldn't be circular because
4034 // we don't support footnotes inside
4035 // floats (yet). ARRae
4036 par = par->TeXEnvironment(file, texrow,
4040 par = par->TeXOnePar(file, texrow,
4045 if (par && !par->IsDummy() && par->depth > depth) {
4046 par = par->TeXDeeper(file, texrow,
4050 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4052 // process footnotes > depth 0 or in environments separately
4053 // NOTE: Currently don't support footnotes within footnotes
4054 // even though that is possible using the \footnotemark
4056 TexRow dummy_texrow;
4057 int dummy_count = 0;
4059 LyXLayout const & style =
4060 textclasslist.Style(GetCurrentTextClass(),
4063 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4065 if (style.isEnvironment()
4066 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4067 // Allows the use of minipages within float
4068 // environments. Shouldn't be circular because
4069 // we don't support footnotes inside
4070 // floats (yet). ARRae
4071 par = par->TeXEnvironment(foot, foot_texrow,
4072 dummy, dummy_texrow,
4075 par = par->TeXOnePar(foot, foot_texrow,
4076 dummy, dummy_texrow,
4080 if (par && !par->IsDummy() && par->depth > depth) {
4081 par = par->TeXDeeper(foot, foot_texrow,
4082 dummy, dummy_texrow,
4086 && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4088 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4089 "Footnote in a Footnote -- not supported"
4094 switch (footnotekind) {
4095 case LyXParagraph::FOOTNOTE:
4096 if (footer_in_body) {
4097 // This helps tell which of the multiple
4098 // footnotetexts an error was in.
4100 foot_texrow.newline();
4105 case LyXParagraph::MARGIN:
4108 case LyXParagraph::FIG:
4109 if (pextra_type == PEXTRA_FLOATFLT
4110 && (!pextra_width.empty()
4111 || !pextra_widthp.empty()))
4112 file += "\\end{floatingfigure}";
4114 file += "\\end{figure}";
4116 case LyXParagraph::TAB:
4117 file += "\\end{table}";
4119 case LyXParagraph::WIDE_FIG:
4120 file += "\\end{figure*}";
4122 case LyXParagraph::WIDE_TAB:
4123 file += "\\end{table*}";
4125 case LyXParagraph::ALGORITHM:
4126 file += "\\end{algorithm}";
4130 if (footnotekind != LyXParagraph::FOOTNOTE
4131 && footnotekind != LyXParagraph::MARGIN) {
4132 // we need to ensure that real floats like tables and figures
4133 // have their \end{} on a line of their own otherwise we can
4134 // get incorrect results when using the endfloat.sty package.
4139 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4144 void LyXParagraph::SetPExtraType(int type, char const * width,
4145 char const * widthp)
4148 pextra_width = width;
4149 pextra_widthp = widthp;
4151 if (textclasslist.Style(GetCurrentTextClass(),
4152 layout).isEnvironment()) {
4157 while (par && (par->layout == layout)
4158 && (par->depth == depth)) {
4160 par = par->Previous();
4162 par = par->FirstPhysicalPar();
4163 while (par && par->depth > depth) {
4164 par = par->Previous();
4166 par = par->FirstPhysicalPar();
4170 while (par && (par->layout == layout)
4171 && (par->depth == depth)) {
4172 par->pextra_type = type;
4173 par->pextra_width = width;
4174 par->pextra_widthp = widthp;
4175 par = par->NextAfterFootnote();
4176 if (par && (par->depth > depth))
4177 par->SetPExtraType(type, width, widthp);
4178 while (par && ((par->depth > depth) || par->IsDummy()))
4179 par = par->NextAfterFootnote();
4185 void LyXParagraph::UnsetPExtraType()
4187 if (pextra_type == PEXTRA_NONE)
4190 pextra_type = PEXTRA_NONE;
4191 pextra_width.clear();
4192 pextra_widthp.clear();
4194 if (textclasslist.Style(GetCurrentTextClass(),
4195 layout).isEnvironment()) {
4200 while (par && (par->layout == layout)
4201 && (par->depth == depth)) {
4203 par = par->Previous();
4205 par = par->FirstPhysicalPar();
4206 while (par && par->depth > depth) {
4207 par = par->Previous();
4209 par = par->FirstPhysicalPar();
4213 while (par && (par->layout == layout)
4214 && (par->depth == depth)) {
4215 par->pextra_type = PEXTRA_NONE;
4216 par->pextra_width.clear();
4217 par->pextra_widthp.clear();
4218 par = par->NextAfterFootnote();
4219 if (par && (par->depth > depth))
4220 par->UnsetPExtraType();
4221 while (par && ((par->depth > depth) || par->IsDummy()))
4222 par = par->NextAfterFootnote();
4228 bool LyXParagraph::IsHfill(size_type pos) const
4230 return IsHfillChar(GetChar(pos));
4234 bool LyXParagraph::IsInset(size_type pos) const
4236 return IsInsetChar(GetChar(pos));
4240 bool LyXParagraph::IsFloat(size_type pos) const
4242 return IsFloatChar(GetChar(pos));
4246 bool LyXParagraph::IsNewline(size_type pos) const
4250 tmp = IsNewlineChar(GetChar(pos));
4255 bool LyXParagraph::IsSeparator(size_type pos) const
4257 return IsSeparatorChar(GetChar(pos));
4261 bool LyXParagraph::IsLineSeparator(size_type pos) const
4263 return IsLineSeparatorChar(GetChar(pos));
4267 bool LyXParagraph::IsKomma(size_type pos) const
4269 return IsKommaChar(GetChar(pos));
4273 /// Used by the spellchecker
4274 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4276 unsigned char c = GetChar(pos);
4277 if (IsLetterChar(c))
4279 // '\0' is not a letter, allthough every string contains "" (below)
4282 // We want to pass the ' and escape chars to ispell
4283 string extra = lyxrc->isp_esc_chars + '\'';
4287 return contains(extra, ch);
4291 bool LyXParagraph::IsWord(size_type pos ) const
4293 return IsWordChar(GetChar(pos)) ;