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"
17 #include "lyxparagraph.h"
18 #include "support/textutils.h"
21 #include "tex-strings.h"
22 #include "bufferparams.h"
23 #include "support/FileInfo.h"
25 #include "LaTeXFeatures.h"
26 #include "insets/insetinclude.h"
27 #include "support/filetools.h"
28 #include "lyx_gui_misc.h"
32 extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
33 extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
34 int tex_code_break_column = 72; // needs non-zero initialization. set later.
35 // this is a bad idea, but how can LyXParagraph find its buffer to get
36 // parameters? (JMarc)
37 extern BufferView * current_view;
42 extern string bibitemWidthest();
44 /* this is a minibuffer */
45 static char minibuffer_char;
46 static LyXFont minibuffer_font;
47 static Inset * minibuffer_inset;
50 // Initialization of the counter for the paragraph id's,
51 // declared in lyxparagraph.h
52 unsigned int LyXParagraph::paragraph_id = 0;
55 LyXParagraph::LyXParagraph()
57 text.reserve(500); // is this number too big?
59 for (int i = 0; i < 10; ++i) setCounter(i , 0);
69 footnoteflag = LyXParagraph::NO_FOOTNOTE;
71 align = LYX_ALIGN_BLOCK;
73 /* table stuff -- begin*/
75 /* table stuff -- end*/
77 bibkey = 0; // ale970302
82 /* this konstruktor inserts the new paragraph in a list */
83 LyXParagraph::LyXParagraph(LyXParagraph * par)
86 par->text.resize(par->text.size());
88 for (int i = 0; i < 10; ++i) setCounter(i, 0);
94 next->previous = this;
96 previous->next = this;
101 footnoteflag = LyXParagraph::NO_FOOTNOTE;
102 footnotekind = LyXParagraph::FOOTNOTE;
104 /* table stuff -- begin*/
106 /* table stuff -- end*/
107 id_ = paragraph_id++;
109 bibkey = 0; // ale970302
115 void LyXParagraph::writeFile(FILE * file, BufferParams & params,
116 char footflag, char dth)
118 LyXFont font1, font2;
124 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
126 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
128 /* The beginning or the end of a footnote environment? */
129 if (footflag != footnoteflag) {
130 footflag = footnoteflag;
132 fprintf(file, "\n\\begin_float %s ",
133 string_footnotekinds[footnotekind]);
136 fprintf(file, "\n\\end_float ");
140 /* The beginning or end of a deeper (i.e. nested) area? */
143 while (depth > dth) {
144 fprintf(file, "\n\\begin_deeper ");
149 while (depth < dth) {
150 fprintf(file, "\n\\end_deeper ");
156 /* First write the layout */
157 fprintf(file, "\n\\layout %s\n",
158 textclasslist.NameOfLayout(params.textclass, layout)
161 /* maybe some vertical spaces */
162 if (added_space_top.kind() != VSpace::NONE)
163 fprintf(file, "\\added_space_top %s ",
164 added_space_top.asLyXCommand().c_str());
165 if (added_space_bottom.kind() != VSpace::NONE)
166 fprintf(file, "\\added_space_bottom %s ",
167 added_space_bottom.asLyXCommand().c_str());
169 /* The labelwidth string used in lists */
170 if (!labelwidthstring.empty())
171 fprintf(file, "\\labelwidthstring %s\n",
172 labelwidthstring.c_str());
174 /* Lines above or below? */
176 fprintf(file, "\\line_top ");
178 fprintf(file, "\\line_bottom ");
180 /* Pagebreaks above or below? */
182 fprintf(file, "\\pagebreak_top ");
183 if (pagebreak_bottom)
184 fprintf(file, "\\pagebreak_bottom ");
186 /* Start of appendix? */
187 if (start_of_appendix)
188 fprintf(file, "\\start_of_appendix ");
192 fprintf(file, "\\noindent ");
195 if (align != LYX_ALIGN_LAYOUT) {
197 case LYX_ALIGN_LEFT: h = 1; break;
198 case LYX_ALIGN_RIGHT: h = 2; break;
199 case LYX_ALIGN_CENTER: h = 3; break;
200 default: h = 0; break;
202 fprintf(file, "\\align %s ", string_align[h]);
204 if (pextra_type != PEXTRA_NONE) {
205 fprintf(file, "\\pextra_type %d", pextra_type);
206 if (pextra_type == PEXTRA_MINIPAGE) {
207 fprintf(file, " \\pextra_alignment %d",
210 fprintf(file, " \\pextra_hfill %d",
212 if (pextra_start_minipage)
214 " \\pextra_start_minipage %d",
215 pextra_start_minipage);
217 if (!pextra_width.empty()) {
218 fprintf(file, " \\pextra_width %s",
220 .asLyXCommand().c_str());
221 } else if (!pextra_widthp.empty()) {
222 fprintf(file, " \\pextra_widthp %s",
223 pextra_widthp.c_str());
229 /* Dummy layout. This means that a footnote ended */
230 fprintf(file, "\n\\end_float ");
231 footflag = LyXParagraph::NO_FOOTNOTE;
234 /* It might be a table */
236 fprintf(file, "\\LyXTable\n");
244 font1 = LyXFont(LyXFont::ALL_INHERIT);
247 for (size_type i = 0; i < size(); i++) {
253 // Write font changes
254 font2 = GetFontSettings(i);
255 if (font2 != font1) {
256 font2.lyxWriteChanges(font1, file);
266 if (inset->DirectWrite()) {
267 // international char, let it write
268 // code directly so it's shorter in
272 fprintf(file, "\n\\begin_inset ");
274 fprintf(file, "\n\\end_inset \n");
280 fprintf(file, "\n\\newline \n");
284 fprintf(file, "\n\\hfill \n");
287 case META_PROTECTED_SEPARATOR:
288 fprintf(file, "\n\\protected_separator \n");
292 fprintf(file, "\n\\backslash \n");
296 if (i + 1 < size() && GetChar(i + 1) == ' ') {
297 fprintf(file, ".\n");
303 if ((column > 70 && c == ' ')
308 // this check is to amend a bug. LyX sometimes
309 // inserts '\0' this could cause problems.
311 fprintf(file, "%c", c);
313 lyxerr << "ERROR (LyXParagraph::writeFile):"
314 " NULL char in structure." << endl;
320 // now write the next paragraph
322 next->writeFile(file, params, footflag, dth);
326 void LyXParagraph::validate(LaTeXFeatures & features)
328 // this will be useful later
329 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
333 if (line_top || line_bottom)
334 features.lyxline = true;
337 features.layout[GetLayout()] = true;
340 for (FontList::const_iterator cit = fontlist.begin();
341 cit != fontlist.end(); ++cit) {
342 if ((*cit).font.noun() == LyXFont::ON) {
343 lyxerr[Debug::LATEX] << "font.noun: "
344 << (*cit).font.noun()
346 features.noun = true;
347 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
348 << (*cit).font.stateText()
351 switch ((*cit).font.color()) {
353 case LyXFont::INHERIT_COLOR:
354 case LyXFont::IGNORE_COLOR: break;
356 features.color = true;
357 lyxerr[Debug::LATEX] << "Color enabled. Font: "
358 << (*cit).font.stateText()
364 FontTable * tmpfonttable = fonttable;
365 while (tmpfonttable) {
366 if (tmpfonttable->font.noun() == LyXFont::ON) {
367 lyxerr[Debug::LATEX] << "font.noun: "
368 << tmpfonttable->font.noun()
370 features.noun = true;
371 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
372 << tmpfonttable->font.stateText()
375 switch (tmpfonttable->font.color()) {
377 case LyXFont::INHERIT_COLOR:
378 case LyXFont::IGNORE_COLOR:
381 features.color = true;
382 lyxerr[Debug::LATEX] << "Color enabled. Font: "
383 << tmpfonttable->font.stateText()
386 tmpfonttable = tmpfonttable->next;
390 for (InsetList::const_iterator cit = insetlist.begin();
391 cit != insetlist.end(); ++cit) {
392 (*cit).inset->Validate(features);
396 InsetTable * tmpinsettable = insettable;
397 while (tmpinsettable) {
398 if (tmpinsettable->inset) {
399 tmpinsettable->inset->Validate(features);
401 tmpinsettable = tmpinsettable->next;
404 if (table && table->IsLongTable())
405 features.longtable = true;
406 if (pextra_type == PEXTRA_INDENT)
407 features.LyXParagraphIndent = true;
408 if (pextra_type == PEXTRA_FLOATFLT)
409 features.floatflt = true;
410 if (layout.needprotect
411 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
412 features.NeedLyXFootnoteCode = true;
413 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
414 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
415 features.NeedLyXMinipageIndent = true;
416 if (table && table->NeedRotating())
417 features.rotating = true;
418 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
419 features.algorithm = true;
423 /* first few functions needed for cut and paste and paragraph breaking */
424 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const
426 minibuffer_char = GetChar(pos);
427 minibuffer_font = GetFontSettings(pos);
428 minibuffer_inset = 0;
429 if (minibuffer_char == LyXParagraph::META_INSET) {
431 minibuffer_inset = GetInset(pos)->Clone();
433 minibuffer_inset = 0;
434 minibuffer_char = ' ';
435 // This reflects what GetInset() does (ARRae)
440 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
442 minibuffer_char = GetChar(pos);
443 minibuffer_font = GetFontSettings(pos);
444 minibuffer_inset = 0;
445 if (minibuffer_char == LyXParagraph::META_INSET) {
447 minibuffer_inset = GetInset(pos);
448 // This is a little hack since I want exactly
449 // the inset, not just a clone. Otherwise
450 // the inset would be deleted when calling Erase(pos)
452 for (InsetList::iterator it = insetlist.begin();
453 it != insetlist.end(); ++it) {
454 if ((*it).pos == pos) {
461 InsetTable * tmpi = insettable;
462 while (tmpi && tmpi->pos != pos) {
465 if (tmpi) { /* This should always be true */
470 minibuffer_inset = 0;
471 minibuffer_char = ' ';
472 // This reflects what GetInset() does (ARRae)
477 /* Erase(pos); now the caller is responsible for that*/
481 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
483 InsertChar(pos, minibuffer_char);
484 SetFont(pos, minibuffer_font);
485 if (minibuffer_char == LyXParagraph::META_INSET)
486 InsertInset(pos, minibuffer_inset);
489 /* end of minibuffer */
493 void LyXParagraph::Clear()
498 pagebreak_top = false;
499 pagebreak_bottom = false;
501 added_space_top = VSpace(VSpace::NONE);
502 added_space_bottom = VSpace(VSpace::NONE);
504 align = LYX_ALIGN_LAYOUT;
508 pextra_type = PEXTRA_NONE;
509 pextra_width.clear();
510 pextra_widthp.clear();
511 pextra_alignment = MINIPAGE_ALIGN_TOP;
512 pextra_hfill = false;
513 pextra_start_minipage = false;
516 labelwidthstring.clear();
520 start_of_appendix = false;
524 /* the destructor removes the new paragraph from the list */
525 LyXParagraph::~LyXParagraph()
528 previous->next = next;
530 next->previous = previous;
533 InsetTable * tmpinset;
535 tmpinset = insettable;
536 insettable = insettable->next;
538 delete tmpinset->inset;
540 if (insettable && insettable->next == insettable) {
541 // somehow this recursion appears occasionally
542 // but I can't find where. This bandaid
543 // helps but isn't the best fix. (ARRae)
544 if (insettable->inset) {
545 delete insettable->inset;
555 fonttable = fonttable->next;
560 /* table stuff -- begin*/
563 /* table stuff -- end*/
571 void LyXParagraph::Erase(LyXParagraph::size_type pos)
573 /* > because last is the next unused position, and you can
574 * use it if you want */
576 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
577 NextAfterFootnote()->Erase(pos - text.size() - 1);
579 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
580 "position does not exist." << endl;
583 if (pos < size()) { // last is free for insertation, but should be empty
585 /* if it is an inset, delete the inset entry */
586 if (text[pos] == LyXParagraph::META_INSET) {
588 for(InsetList::iterator it = insetlist.begin();
589 it != insetlist.end(); ++it) {
590 if ((*it).pos == pos) {
598 /* if it is an inset, delete the inset entry */
599 if (text[pos] == LyXParagraph::META_INSET) {
601 InsetTable *tmpi = insettable;
602 InsetTable *tmpi2 = tmpi;
603 while (tmpi && tmpi->pos != pos) {
607 if (tmpi) { // this should always be true
608 if (tmpi->inset) // delete the inset if it exists
610 if (tmpi == insettable)
611 insettable = tmpi->next;
613 tmpi2->next = tmpi->next;
618 text.erase(text.begin() + pos);
620 /* erase entries in the tables */
621 for(FontList::iterator it = fontlist.begin();
622 it != fontlist.end(); ++it) {
623 if (pos >= (*it).pos && pos <= (*it).pos_end) {
624 if ((*it).pos == (*it).pos_end) {
631 /* update all other entries */
632 for(FontList::iterator it = fontlist.begin();
633 it != fontlist.end(); ++it) {
636 if ((*it).pos_end >= pos)
640 /* update the inset table */
641 for(InsetList::iterator it = insetlist.begin();
642 it != insetlist.end(); ++it) {
647 /* erase entries in the tables */
649 FontTable * tmp = fonttable;
650 FontTable * prev = 0;
651 while (tmp && !found) {
652 if (pos >= tmp->pos && pos <= tmp->pos_end)
660 if (found && tmp->pos == tmp->pos_end) {
661 /* if it is a multi-character font entry, we just make
662 * it smaller (see update below), otherwise we should
665 prev->next = tmp->next;
667 fonttable = tmp->next;
672 /* update all other entries */
678 if (tmp->pos_end >= pos)
683 /* update the inset table */
684 InsetTable * tmpi = insettable;
692 lyxerr << "ERROR (LyXParagraph::Erase): "
693 "can't erase non-existant char." << endl;
698 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
700 /* > because last is the next unused position, and you can
701 * use it if you want */
704 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
705 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
708 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
709 "position does not exist." << endl;
712 text.insert(text.begin() + pos, c);
714 // update the font table
715 for(FontList::iterator it = fontlist.begin();
716 it != fontlist.end(); ++it) {
717 if ((*it).pos >= pos)
719 if ((*it).pos_end >= pos)
722 // update the inset table
723 for(InsetList::iterator it = insetlist.begin();
724 it != insetlist.end(); ++it) {
725 if ((*it).pos >= pos)
729 /* update the font table */
730 FontTable * tmp = fonttable;
734 if (tmp->pos_end >= pos)
739 /* update the inset table */
740 InsetTable * tmpi = insettable;
742 if (tmpi->pos >= pos)
750 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
753 /* > because last is the next unused position, and you can
754 * use it if you want */
757 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
759 ->InsertInset(pos - text.size() - 1, inset);
761 lyxerr << "ERROR (LyXParagraph::InsertInset): "
762 "position does not exist: " << pos << endl;
765 if (text[pos] != LyXParagraph::META_INSET) {
766 lyxerr << "ERROR (LyXParagraph::InsertInset): "
767 "there is no LyXParagraph::META_INSET" << endl;
776 insetlist.push_back(tmp);
781 /* add a new entry in the inset table */
782 InsetTable * tmpi = new InsetTable;
785 tmpi->next = insettable;
792 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
796 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
797 return NextAfterFootnote()
798 ->GetInset(pos - text.size() - 1);
800 lyxerr << "ERROR (LyXParagraph::GetInset): "
801 "position does not exist: "
808 for(InsetList::iterator it = insetlist.begin();
809 it != insetlist.end(); ++it) {
810 if ((*it).pos == pos) {
814 lyxerr << "ERROR (LyXParagraph::GetInset): "
815 "Inset does not exist: " << pos << endl;
816 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
817 // Did this commenting out introduce a bug? So far I have not
818 // seen any, please enlighten me. (Lgb)
819 // My guess is that since the inset does not exist, we might
820 // as well replace it with a space to prevent crashes. (Asger)
824 InsetTable * tmpi = insettable;
826 while (tmpi && tmpi->pos != pos)
832 lyxerr << "ERROR (LyXParagraph::GetInset): "
833 "Inset does not exist: " << pos << endl;
834 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
835 // Did this commenting out introduce a bug? So far I have not
836 // seen any, please enlighten me. (Lgb)
837 // My guess is that since the inset does not exist, we might
838 // as well replace it with a space to prevent crashes. (Asger)
845 Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const
849 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
850 return NextAfterFootnote()
851 ->GetInset(pos - text.size() - 1);
853 lyxerr << "ERROR (LyXParagraph::GetInset): "
854 "position does not exist: "
861 for(InsetList::const_iterator cit = insetlist.begin();
862 cit != insetlist.end(); ++cit) {
863 if ((*cit).pos == pos) {
867 lyxerr << "ERROR (LyXParagraph::GetInset): "
868 "Inset does not exist: " << pos << endl;
869 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
870 // Did this commenting out introduce a bug? So far I have not
871 // seen any, please enlighten me. (Lgb)
872 // My guess is that since the inset does not exist, we might
873 // as well replace it with a space to prevent crashes. (Asger)
877 InsetTable * tmpi = insettable;
879 while (tmpi && tmpi->pos != pos)
885 lyxerr << "ERROR (LyXParagraph::GetInset): "
886 "Inset does not exist: " << pos << endl;
887 // in the const version we need to comment it out anyway...
888 //text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
889 // Did this commenting out introduce a bug? So far I have not
890 // seen any, please enlighten me. (Lgb)
891 // My guess is that since the inset does not exist, we might
892 // as well replace it with a space to prevent crashes. (Asger)
899 // Gets uninstantiated font setting at position.
900 // Optimized after profiling. (Asger)
901 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const
905 for(FontList::iterator it = fontlist.begin();
906 it != fontlist.end(); ++it) {
907 if (pos >= (*it).pos && pos <= (*it).pos_end)
911 FontTable * tmp = fonttable;
913 if (pos >= tmp->pos && pos <= tmp->pos_end)
919 /* > because last is the next unused position, and you can
920 * use it if you want */
921 else if (pos > size()) {
923 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
924 return NextAfterFootnote()
925 ->GetFontSettings(pos - text.size() - 1);
927 // Why is it an error to ask for the font of a
928 // position that does not exist? Would it be
929 // enough for this to be anable on debug?
930 // We want strict error checking, but it's ok to only
931 // have it when debugging. (Asger)
932 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
933 "position does not exist. "
934 << pos << " (" << static_cast<int>(pos)
938 return GetFontSettings(pos - 1);
940 return LyXFont(LyXFont::ALL_INHERIT);
944 // Gets the fully instantiated font at a given position in a paragraph
945 // This is basically the same function as LyXText::GetFont() in text2.C.
946 // The difference is that this one is used for generating the LaTeX file,
947 // and thus cosmetic "improvements" are disallowed: This has to deliver
948 // the true picture of the buffer. (Asger)
949 // If position is -1, we get the layout font of the paragraph.
950 // If position is -2, we get the font of the manual label of the paragraph.
951 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
954 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
956 LyXParagraph::size_type main_body = 0;
957 if (layout.labeltype == LABEL_MANUAL)
958 main_body = BeginningOfMainBody();
963 layoutfont = layout.labelfont;
965 layoutfont = layout.font;
966 tmpfont = GetFontSettings(pos);
967 tmpfont.realize(layoutfont);
969 // process layoutfont for pos == -1 and labelfont for pos < -1
971 tmpfont = layout.font;
973 tmpfont = layout.labelfont;
976 // check for environment font information
977 char par_depth = GetDepth();
978 LyXParagraph const * par = this;
979 while (par && par_depth && !tmpfont.resolved()) {
980 par = par->DepthHook(par_depth - 1);
982 tmpfont.realize(textclasslist.
983 Style(GetCurrentTextClass(),
984 par->GetLayout()).font);
985 par_depth = par->GetDepth();
989 tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
994 /// Returns the height of the highest font in range
995 LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
997 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
999 for(FontList::const_iterator cit = fontlist.begin();
1000 cit != fontlist.end(); ++cit) {
1001 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
1002 LyXFont::FONT_SIZE size = (*cit).font.size();
1003 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
1008 FontTable * tmp = fonttable;
1010 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
1011 LyXFont::FONT_SIZE size = tmp->font.size();
1012 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
1022 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
1024 #ifdef DEVEL_VERSION
1025 /* a workaround to 'fix' some bugs in text-class */
1027 // This function is important. It should not work around bugs.
1028 // Let's find the bugs instead and fix them. (Asger)
1029 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
1030 " bad position " << pos << endl;
1038 /* > because last is the next unused position, and you can
1039 * use it if you want */
1040 else if (pos > size()) {
1041 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1042 return NextAfterFootnote()
1043 ->GetChar(pos - text.size() - 1);
1045 lyxerr << "ERROR (LyXParagraph::GetChar): "
1046 "position does not exist."
1047 << pos << " (" << static_cast<int>(pos)
1052 /* we should have a footnote environment */
1053 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1054 // Notice that LyX does request the
1055 // last char from time to time. (Asger)
1056 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1057 // "expected footnote." << endl;
1060 switch (next->footnotekind) {
1061 case LyXParagraph::FOOTNOTE:
1062 return LyXParagraph::META_FOOTNOTE;
1063 case LyXParagraph::MARGIN:
1064 return LyXParagraph::META_MARGIN;
1065 case LyXParagraph::FIG:
1066 case LyXParagraph::WIDE_FIG:
1067 return LyXParagraph::META_FIG;
1068 case LyXParagraph::TAB:
1069 case LyXParagraph::WIDE_TAB:
1070 return LyXParagraph::META_TAB;
1071 case LyXParagraph::ALGORITHM:
1072 return LyXParagraph::META_ALGORITHM;
1074 return '\0'; // to shut up gcc
1079 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1081 #ifdef DEVEL_VERSION
1082 /* a workaround to 'fix' some bugs in text-class */
1084 // This function is important. It should not work around bugs.
1085 // Let's find the bugs instead and fix them. (Asger)
1086 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
1087 " bad position " << pos << endl;
1095 /* > because last is the next unused position, and you can
1096 * use it if you want */
1097 else if (pos > size()) {
1098 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1099 return NextAfterFootnote()
1100 ->GetChar(pos - text.size() - 1);
1102 lyxerr << "ERROR (LyXParagraph::GetChar): "
1103 "position does not exist."
1104 << pos << " (" << static_cast<int>(pos)
1109 /* we should have a footnote environment */
1110 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1111 // Notice that LyX does request the
1112 // last char from time to time. (Asger)
1113 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1114 // "expected footnote." << endl;
1117 switch (next->footnotekind) {
1118 case LyXParagraph::FOOTNOTE:
1119 return LyXParagraph::META_FOOTNOTE;
1120 case LyXParagraph::MARGIN:
1121 return LyXParagraph::META_MARGIN;
1122 case LyXParagraph::FIG:
1123 case LyXParagraph::WIDE_FIG:
1124 return LyXParagraph::META_FIG;
1125 case LyXParagraph::TAB:
1126 case LyXParagraph::WIDE_TAB:
1127 return LyXParagraph::META_TAB;
1128 case LyXParagraph::ALGORITHM:
1129 return LyXParagraph::META_ALGORITHM;
1131 return '\0'; // to shut up gcc
1136 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1137 //Added 98/9/21 by REH
1138 // return an string of the current word, and the end of the word
1141 // the current word is defined as starting at the first character from
1142 // the immediate left of lastpospos which meets the definition of IsLetter(),
1143 // continuing to the last character to the right of this meeting
1147 // i just left this in from GetChar()
1149 #ifdef DEVEL_VERSION
1150 /* a workaround to 'fix' some bugs in text-class */
1152 // This function is important. It should not work around bugs.
1153 // Let's find the bugs instead and fix them. (Asger)
1154 lyxerr << "FATAL ERROR (LyXParagraph::GetWord):"
1155 " bad position " << lastpos << endl;
1165 //i think the devcode aborts before this, but why not be
1167 if (lastpos < 0) lastpos= 0;
1170 // move back until we have a letter
1172 //there's no real reason to have firstpos & lastpos as
1173 //separate variables as this is written, but maybe someon
1174 // will want to return firstpos in the future.
1176 //since someone might have typed a punctuation first
1177 int firstpos = lastpos;
1179 while ((firstpos >= 0) && !IsLetter(firstpos))
1182 // now find the beginning by looking for a nonletter
1184 while ((firstpos>= 0) && IsLetter(firstpos))
1187 // the above is now pointing to the preceeding non-letter
1191 // so copy characters into theword until we get a nonletter
1192 // note that this can easily exceed lastpos, wich means
1193 // that if used in the middle of a word, the whole word
1196 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1203 LyXParagraph::size_type LyXParagraph::Last() const
1205 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1206 return text.size() + NextAfterFootnote()->Last() + 1;
1207 /* the 1 is the symbol
1214 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1216 /* > because last is the next unused position, and you can
1217 * use it if you want */
1220 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1221 return NextAfterFootnote()
1222 ->ParFromPos(pos - text.size() - 1);
1224 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1225 "position does not exist." << endl;
1233 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1235 /* > because last is the next unused position, and you can
1236 * use it if you want */
1239 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1240 return NextAfterFootnote()
1241 ->PositionInParFromPos(pos - text.size() - 1);
1244 "ERROR (LyXParagraph::PositionInParFromPos): "
1245 "position does not exist." << endl;
1253 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1254 LyXFont const & font)
1256 /* > because last is the next unused position, and you can
1257 * use it if you want */
1259 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1260 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1263 lyxerr << "ERROR (LyXParagraph::SetFont): "
1264 "position does not exist." << endl;
1268 LyXFont patternfont(LyXFont::ALL_INHERIT);
1270 // First, reduce font against layout/label font
1271 // Update: The SetCharFont() routine in text2.C already reduces font, so
1272 // we don't need to do that here. (Asger)
1273 // No need to simplify this because it will disappear in a new kernel. (Asger)
1275 // Next search font table
1276 for(FontList::iterator it = fontlist.begin();
1277 it != fontlist.end(); ++it) {
1278 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1280 // we found a font entry. maybe we have to
1281 // split it and create a new one
1283 if ((*it).pos != (*it).pos_end) {
1284 // more than one character
1285 if (pos == (*it).pos) {
1286 // maybe we could enlarge
1287 // the left fonttable
1288 for(FontList::iterator fit = fontlist.begin();
1289 fit != fontlist.end(); ++fit) {
1290 if (pos - 1 >= (*fit).pos
1291 && pos - 1 <= (*fit).pos_end
1292 && (*fit).font == font) {
1300 // Add a new entry in the
1301 // fonttable for the position
1304 tmp.pos_end = (*it).pos_end;
1305 tmp.font = (*it).font;
1306 (*it).pos_end = pos;
1307 fontlist.push_back(tmp);
1308 } else if (pos == (*it).pos_end) {
1309 // Add a new entry in the
1310 // fonttable for the position
1312 tmp.pos = (*it).pos;
1313 tmp.pos_end = (*it).pos_end - 1;
1314 tmp.font = (*it).font;
1315 (*it).pos = (*it).pos_end;
1316 fontlist.push_back(tmp);
1318 // Add a new entry in the
1319 // fonttable for the position
1321 tmp.pos = (*it).pos;
1322 tmp.pos_end = pos - 1;
1323 tmp.font = (*it).font;
1324 fontlist.push_back(tmp);
1327 tmp.pos_end = (*it).pos_end;
1328 tmp.font = (*it).font;
1329 fontlist.push_back(tmp);
1332 (*it).pos_end = pos;
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) return;
1344 // ok, we did not find a font entry. But maybe there is exactly
1345 // the needed font entry one position left
1346 for(FontList::iterator it = fontlist.begin();
1347 it != fontlist.end(); ++it) {
1348 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1349 && (*it).font == font) {
1354 // Add a new entry in the
1355 // fonttable for the position
1359 tmp.font = patternfont;
1360 fontlist.push_back(tmp);
1362 // Next search font table
1366 FontTable * tmp = fonttable;
1367 while (tmp && !found) {
1368 if (pos >= tmp->pos && pos <= tmp->pos_end)
1375 /* if we did not find a font entry, but if the font at hand
1376 * is the same as default, we just forget it */
1377 if (font == patternfont)
1380 /* ok, we did not find a font entry. But maybe there is exactly
1381 * the needed font entry one position left */
1384 while (tmp2 && !found) {
1385 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1391 /* ok there is one. maybe it is exactly the needed font */
1392 if (tmp2->font == font) {
1393 /* put the position under the font */
1398 /* Add a new entry in the
1399 * fonttable for the position */
1400 tmp = new FontTable;
1403 tmp->font = patternfont;
1404 tmp->next = fonttable;
1407 /* we found a font entry. maybe we have to split it and create
1410 if (tmp->pos != tmp->pos_end) { /* more than one character */
1412 if (pos == tmp->pos) {
1413 /* maybe we could enlarge the left fonttable */
1417 while (tmp2 && !found) {
1418 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1424 /* Is there is one, and is it exactly the needed font? */
1425 if (found && tmp2->font == font) {
1426 /* put the position under the font */
1432 /* Add a new entry in the
1433 * fonttable for the position */
1434 tmp2 = new FontTable;
1435 tmp2->pos = pos + 1;
1436 tmp2->pos_end = tmp->pos_end;
1437 tmp2->font = tmp->font;
1439 tmp2->next = fonttable;
1442 else if (pos == tmp->pos_end) {
1443 /* Add a new entry in the
1444 * fonttable for the position */
1445 tmp2 = new FontTable;
1446 tmp2->pos = tmp->pos;
1447 tmp2->pos_end = tmp->pos_end - 1;
1448 tmp2->font = tmp->font;
1449 tmp->pos = tmp->pos_end;
1450 tmp2->next = fonttable;
1454 /* Add a new entry in the
1455 * fonttable for the position */
1456 tmp2 = new FontTable;
1457 tmp2->pos = tmp->pos;
1458 tmp2->pos_end = pos - 1;
1459 tmp2->font = tmp->font;
1460 tmp2->next = fonttable;
1463 tmp2 = new FontTable;
1464 tmp2->pos = pos + 1;
1465 tmp2->pos_end = tmp->pos_end;
1466 tmp2->font = tmp->font;
1467 tmp2->next = fonttable;
1480 /* this function is able to hide closed footnotes */
1481 LyXParagraph * LyXParagraph::Next()
1483 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1484 LyXParagraph * tmp = next;
1486 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1488 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1489 return tmp->Next(); /* there can be more than one
1490 footnote in a logical
1493 return next; /* this should never happen! */
1500 LyXParagraph * LyXParagraph::NextAfterFootnote()
1502 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1503 LyXParagraph * tmp = next;
1504 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
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 next; /* this should never happen! */
1517 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1519 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1520 LyXParagraph * tmp = next;
1521 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1523 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1524 return tmp; /* there can be more than one footnote
1525 in a logical paragraph */
1527 return next; /* this should never happen! */
1534 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1537 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1539 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1540 tmp = tmp->previous;
1541 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1542 return tmp; /* there can be more than one footnote
1543 in a logical paragraph */
1545 return previous; /* this should never happen! */
1552 LyXParagraph * LyXParagraph::LastPhysicalPar()
1554 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1557 LyXParagraph * tmp = this;
1559 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1560 tmp = tmp->NextAfterFootnote();
1567 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1571 LyXParagraph * tmppar = this;
1573 while (tmppar && (tmppar->IsDummy()
1574 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1575 tmppar = tmppar->previous;
1578 return this; /* this should never happen! */
1584 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1588 LyXParagraph const * tmppar = this;
1590 while (tmppar && (tmppar->IsDummy()
1591 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1592 tmppar = tmppar->previous;
1595 return this; /* this should never happen! */
1601 /* this function is able to hide closed footnotes */
1602 LyXParagraph * LyXParagraph::Previous()
1604 LyXParagraph * tmp = previous;
1609 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1610 tmp = tmp->previous;
1612 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1613 tmp = tmp->previous;
1614 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1615 return tmp->next->Previous();
1625 /* this function is able to hide closed footnotes */
1626 LyXParagraph const * LyXParagraph::Previous() const
1628 LyXParagraph * tmp = previous;
1633 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1634 tmp = tmp->previous;
1636 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1637 tmp = tmp->previous;
1638 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1639 return tmp->next->Previous();
1649 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1652 size_type i, pos_end, pos_first;
1653 /* create a new paragraph */
1654 LyXParagraph * par = ParFromPos(pos);
1655 LyXParagraph * firstpar = FirstPhysicalPar();
1657 LyXParagraph * tmp = new LyXParagraph(par);
1659 tmp->footnoteflag = footnoteflag;
1660 tmp->footnotekind = footnotekind;
1662 /* this is an idea for a more userfriendly layout handling, I will
1663 * see what the users say */
1665 /* layout stays the same with latex-environments */
1667 tmp->SetOnlyLayout(firstpar->layout);
1668 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1671 if (Last() > pos || !Last() || flag == 2) {
1672 tmp->SetOnlyLayout(firstpar->layout);
1673 tmp->align = firstpar->align;
1674 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1676 tmp->line_bottom = firstpar->line_bottom;
1677 firstpar->line_bottom = false;
1678 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1679 firstpar->pagebreak_bottom = false;
1680 tmp->added_space_bottom = firstpar->added_space_bottom;
1681 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1683 tmp->depth = firstpar->depth;
1684 tmp->noindent = firstpar->noindent;
1686 /* copy everything behind the break-position
1687 to the new paragraph
1690 while (ParFromPos(pos_first) != par)
1693 pos_end = pos_first + par->text.size() - 1;
1694 tmp->text.reserve(pos_end - pos);
1696 for (i = pos; i <= pos_end; i++) {
1697 par->CutIntoMinibuffer(i - pos_first);
1698 tmp->InsertFromMinibuffer(i - pos);
1701 for (i = pos_end; i >= pos; i--)
1702 par->Erase(i - pos_first);
1704 par->text.resize(par->text.size());
1707 /* just an idea of me */
1709 tmp->line_top = firstpar->line_top;
1710 tmp->pagebreak_top = firstpar->pagebreak_top;
1711 tmp->added_space_top = firstpar->added_space_top;
1712 tmp->bibkey = firstpar->bibkey;
1714 /* layout stays the same with latex-environments */
1716 firstpar->SetOnlyLayout(tmp->layout);
1717 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1718 firstpar->depth = tmp->depth;
1724 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1726 par = par->FirstPhysicalPar();
1727 footnoteflag = par->footnoteflag;
1728 footnotekind = par->footnotekind;
1730 layout = par->layout;
1731 align = par-> align;
1732 SetLabelWidthString(par->labelwidthstring);
1734 line_bottom = par->line_bottom;
1735 pagebreak_bottom = par->pagebreak_bottom;
1736 added_space_bottom = par->added_space_bottom;
1738 line_top = par->line_top;
1739 pagebreak_top = par->pagebreak_top;
1740 added_space_top = par->added_space_top;
1742 pextra_type = par->pextra_type;
1743 pextra_width = par->pextra_width;
1744 pextra_widthp = par->pextra_widthp;
1745 pextra_alignment = par->pextra_alignment;
1746 pextra_hfill = par->pextra_hfill;
1747 pextra_start_minipage = par->pextra_start_minipage;
1749 noindent = par->noindent;
1754 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1756 LyXParagraph * tmppar = this;
1759 && tmppar->previous->footnoteflag ==
1760 LyXParagraph::CLOSED_FOOTNOTE)
1761 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1762 tmppar = tmppar->previous;
1765 return this; /* this should never happen! */
1771 LyXParagraph * LyXParagraph::Clone() const
1773 /* create a new paragraph */
1774 LyXParagraph * result = new LyXParagraph;
1776 result->MakeSameLayout(this);
1778 /* this is because of the dummy layout of the paragraphs that
1780 result->layout = layout;
1782 /* table stuff -- begin*/
1784 result->table = table->Clone();
1787 /* table stuff -- end*/
1790 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1793 /* copy everything behind the break-position to the new paragraph */
1795 for (size_type i = 0; i < size(); i++) {
1796 CopyIntoMinibuffer(i);
1797 result->InsertFromMinibuffer(i);
1799 result->text.resize(result->text.size());
1804 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1806 par = par->FirstPhysicalPar();
1809 par->footnoteflag == footnoteflag &&
1810 par->footnotekind == footnotekind &&
1812 par->layout == layout &&
1814 par->align == align &&
1816 par->line_bottom == line_bottom &&
1817 par->pagebreak_bottom == pagebreak_bottom &&
1818 par->added_space_bottom == added_space_bottom &&
1820 par->line_top == line_top &&
1821 par->pagebreak_top == pagebreak_top &&
1822 par->added_space_top == added_space_top &&
1824 par->pextra_type == pextra_type &&
1825 par->pextra_width == pextra_width &&
1826 par->pextra_widthp == pextra_widthp &&
1827 par->pextra_alignment == pextra_alignment &&
1828 par->pextra_hfill == pextra_hfill &&
1829 par->pextra_start_minipage == pextra_start_minipage &&
1831 par->table == table && // what means: NO TABLE AT ALL
1833 par->noindent == noindent &&
1834 par->depth == depth);
1838 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1840 size_type i, pos_end, pos_first;
1842 /* create a new paragraph */
1843 LyXParagraph * par = ParFromPos(pos);
1845 LyXParagraph * tmp = new LyXParagraph(par);
1847 tmp->MakeSameLayout(par);
1850 /* copy everything behind the break-position to the new
1853 while (ParFromPos(pos_first) != par)
1855 pos_end = pos_first + par->text.size() - 1;
1856 /* make shure there is enough memory for the now larger
1857 paragraph. This is not neccessary, because
1858 InsertFromMinibuffer will enlarge the memory (it uses
1859 InsertChar of course). But doing it by hand
1860 is MUCH faster! (only one time, not thousend times!!) */
1861 tmp->text.reserve(pos_end - pos);
1863 for (i = pos; i <= pos_end; i++) {
1865 par->CutIntoMinibuffer(i - pos_first);
1866 tmp->InsertFromMinibuffer(i - pos);
1868 for (i = pos_end; i >= pos; i--)
1869 par->Erase(i - pos_first);
1871 par->text.resize(par->text.size());
1876 /* be carefull, this does not make any check at all */
1877 void LyXParagraph::PasteParagraph()
1879 /* copy the next paragraph to this one */
1880 LyXParagraph * the_next = Next();
1882 LyXParagraph * firstpar = FirstPhysicalPar();
1884 /* first the DTP-stuff */
1885 firstpar->line_bottom = the_next->line_bottom;
1886 firstpar->added_space_bottom = the_next->added_space_bottom;
1887 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1889 size_type pos_end = the_next->text.size() - 1;
1890 size_type pos_insert = Last();
1893 /* ok, now copy the paragraph */
1894 for (i = 0; i <= pos_end; i++) {
1895 the_next->CutIntoMinibuffer(i);
1896 InsertFromMinibuffer(pos_insert + i);
1899 /* delete the next paragraph */
1904 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1906 LyXParagraph * par = ParFromPos(pos);
1908 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1909 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1915 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1917 LyXParagraph * par = ParFromPos(pos);
1919 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1920 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1926 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1928 return FirstPhysicalPar()->layout;
1932 char LyXParagraph::GetDepth() const
1934 return FirstPhysicalPar()->depth;
1938 char LyXParagraph::GetAlign() const
1940 return FirstPhysicalPar()->align;
1944 string LyXParagraph::GetLabestring() const
1946 return FirstPhysicalPar()->labelstring;
1950 int LyXParagraph::GetFirstCounter(int i) const
1952 return FirstPhysicalPar()->counter_[i];
1956 /* the next two functions are for the manual labels */
1957 string LyXParagraph::GetLabelWidthString() const
1959 if (!FirstPhysicalPar()->labelwidthstring.empty())
1960 return FirstPhysicalPar()->labelwidthstring;
1962 return _("Senseless with this layout!");
1966 void LyXParagraph::SetLabelWidthString(string const & s)
1968 LyXParagraph * par = FirstPhysicalPar();
1970 par->labelwidthstring = s;
1974 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1976 LyXParagraph * par = FirstPhysicalPar();
1977 LyXParagraph * ppar = 0;
1978 LyXParagraph * npar = 0;
1980 par->layout = new_layout;
1981 /* table stuff -- begin*/
1984 /* table stuff -- end*/
1985 if (par->pextra_type == PEXTRA_NONE) {
1986 if (par->Previous()) {
1987 ppar = par->Previous()->FirstPhysicalPar();
1990 && (ppar->depth > par->depth))
1991 ppar = ppar->Previous()->FirstPhysicalPar();
1994 npar = par->Next()->NextAfterFootnote();
1997 && (npar->depth > par->depth))
1998 npar = npar->Next()->NextAfterFootnote();
2000 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2002 p1 = ppar->pextra_width,
2003 p2 = ppar->pextra_widthp;
2004 ppar->SetPExtraType(ppar->pextra_type,
2005 p1.c_str(), p2.c_str());
2007 if ((par->pextra_type == PEXTRA_NONE) &&
2008 npar && (npar->pextra_type != PEXTRA_NONE)) {
2010 p1 = npar->pextra_width,
2011 p2 = npar->pextra_widthp;
2012 npar->SetPExtraType(npar->pextra_type,
2013 p1.c_str(), p2.c_str());
2019 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
2022 * par = FirstPhysicalPar(),
2026 par->layout = new_layout;
2027 par->labelwidthstring.clear();
2028 par->align = LYX_ALIGN_LAYOUT;
2029 par->added_space_top = VSpace(VSpace::NONE);
2030 par->added_space_bottom = VSpace(VSpace::NONE);
2031 /* table stuff -- begin*/
2034 /* table stuff -- end*/
2035 if (par->pextra_type == PEXTRA_NONE) {
2036 if (par->Previous()) {
2037 ppar = par->Previous()->FirstPhysicalPar();
2040 && (ppar->depth > par->depth))
2041 ppar = ppar->Previous()->FirstPhysicalPar();
2044 npar = par->Next()->NextAfterFootnote();
2047 && (npar->depth > par->depth))
2048 npar = npar->Next()->NextAfterFootnote();
2050 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2052 p1 = ppar->pextra_width,
2053 p2 = ppar->pextra_widthp;
2054 ppar->SetPExtraType(ppar->pextra_type,
2055 p1.c_str(), p2.c_str());
2057 if ((par->pextra_type == PEXTRA_NONE) &&
2058 npar && (npar->pextra_type != PEXTRA_NONE)) {
2060 p1 = npar->pextra_width,
2061 p2 = npar->pextra_widthp;
2062 npar->SetPExtraType(npar->pextra_type,
2063 p1.c_str(), p2.c_str());
2069 /* if the layout of a paragraph contains a manual label, the beginning of the
2070 * main body is the beginning of the second word. This is what the par-
2071 * function returns. If the layout does not contain a label, the main
2072 * body always starts with position 0. This differentiation is necessary,
2073 * because there cannot be a newline or a blank <= the beginning of the
2074 * main body in TeX. */
2076 int LyXParagraph::BeginningOfMainBody() const
2078 if (FirstPhysicalPar() != this)
2081 // Unroll the first two cycles of the loop
2082 // and remember the previous character to
2083 // remove unnecessary GetChar() calls
2086 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2088 char previous_char, temp;
2090 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2091 // Yes, this ^ is supposed to be "= " not "=="
2094 && previous_char != ' '
2095 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2097 previous_char = temp;
2102 if (i == 0 && i == size() &&
2103 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2104 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2105 i++; /* the cursor should not jump
2106 * to the main body if there
2112 LyXParagraph * LyXParagraph::DepthHook(int deth)
2114 LyXParagraph * newpar = this;
2119 newpar = newpar->FirstPhysicalPar()->Previous();
2120 } while (newpar && newpar->GetDepth() > deth
2121 && newpar->footnoteflag == footnoteflag);
2124 if (Previous() || GetDepth())
2125 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2129 return newpar->FirstPhysicalPar();
2133 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2135 LyXParagraph const * newpar = this;
2140 newpar = newpar->FirstPhysicalPar()->Previous();
2141 } while (newpar && newpar->GetDepth() > deth
2142 && newpar->footnoteflag == footnoteflag);
2145 if (Previous() || GetDepth())
2146 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2150 return newpar->FirstPhysicalPar();
2154 int LyXParagraph::AutoDeleteInsets()
2158 for (InsetList::iterator it = insetlist.begin();
2159 it != insetlist.end(); ++it) {
2160 if ((*it).inset->AutoDelete()) {
2167 InsetTable * tmpi = insettable;
2168 InsetTable * tmpi2 = tmpi;
2174 if (tmpi2->inset->AutoDelete()) {
2179 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2180 "cannot auto-delete insets" << endl;
2187 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2190 InsetTable * tmp = 0;
2191 for (InsetList::iterator it = insetlist.begin();
2192 it != insetlist.end(); ++it) {
2193 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2204 InsetTable * tmpi = insettable;
2205 InsetTable * tmpi2 = 0;
2207 if (tmpi->pos >= pos) {
2208 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2215 return tmpi2->inset;
2223 /* returns -1 if inset not found */
2224 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2227 for (InsetList::iterator it = insetlist.begin();
2228 it != insetlist.end(); ++it) {
2229 if ((*it).inset == inset) {
2233 // Think about footnotes
2234 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2235 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2236 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2238 return size() + 1 + further;
2242 /* find the entry */
2243 InsetTable * tmpi = insettable;
2244 while (tmpi && tmpi->inset != inset) {
2247 if (tmpi && tmpi->inset)
2250 /* think about footnotes */
2251 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2252 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2254 NextAfterFootnote()->GetPositionOfInset(inset);
2256 return text.size() + 1 + further;
2264 void LyXParagraph::readSimpleWholeFile(FILE * myfile)
2268 if (!feof(myfile)) {
2272 InsertChar(text.size(), c);
2273 } while (!feof(myfile));
2279 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2280 string & foot, TexRow & foot_texrow,
2283 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2284 LyXParagraph * par = next;
2285 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2288 bool further_blank_line = false;
2290 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2292 if (start_of_appendix) {
2293 file += "\\appendix\n";
2297 if (tex_code_break_column && style.isCommand()){
2302 if (pagebreak_top) {
2303 file += "\\newpage";
2304 further_blank_line = true;
2306 if (added_space_top.kind() != VSpace::NONE) {
2307 file += added_space_top.asLatexCommand();
2308 further_blank_line = true;
2312 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2313 file += "\\vspace{-1\\parskip}";
2314 further_blank_line = true;
2317 if (further_blank_line){
2322 switch (style.latextype) {
2325 file += style.latexname();
2326 file += style.latexparam();
2328 case LATEX_ITEM_ENVIRONMENT:
2330 bibkey->Latex(file, false);
2334 case LATEX_LIST_ENVIRONMENT:
2341 bool need_par = SimpleTeXOnePar(file, texrow);
2343 // Spit out footnotes
2344 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2345 && par->footnoteflag != footnoteflag) {
2346 par = par->TeXFootnote(file, texrow,
2347 foot, foot_texrow, foot_count);
2348 par->SimpleTeXOnePar(file, texrow);
2352 // Make sure that \\par is done with the font of the last
2353 // character if this has another size as the default.
2354 // This is necessary because LaTeX (and LyX on the screen)
2355 // calculates the space between the baselines according
2356 // to this font. (Matthias)
2357 LyXFont font = getFont(Last()-1);
2359 if (style.resfont.size() != font.size()) {
2361 file += font.latexSize();
2365 } else if (textclasslist.Style(GetCurrentTextClass(),
2366 GetLayout()).isCommand()){
2367 if (style.resfont.size() != font.size()) {
2369 file += font.latexSize();
2373 } else if (style.resfont.size() != font.size()){
2374 file += "{\\" + font.latexSize() + " \\par}";
2377 switch (style.latextype) {
2378 case LATEX_ITEM_ENVIRONMENT:
2379 case LATEX_LIST_ENVIRONMENT:
2380 if (par && (depth < par->depth)) {
2385 case LATEX_ENVIRONMENT:
2386 // if its the last paragraph of the current environment
2387 // skip it otherwise fall through
2389 && (par->layout != layout
2390 || par->depth != depth
2391 || par->pextra_type != pextra_type))
2394 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2395 && footnotekind != LyXParagraph::FOOTNOTE
2396 && footnotekind != LyXParagraph::MARGIN
2400 // don't insert this if we would be adding it
2401 // before or after a table in a float. This
2402 // little trick is needed in order to allow
2403 // use of tables in \subfigures or \subtables.
2409 further_blank_line = false;
2411 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2412 further_blank_line = true;
2415 if (added_space_bottom.kind() != VSpace::NONE) {
2416 file += added_space_bottom.asLatexCommand();
2417 further_blank_line = true;
2420 if (pagebreak_bottom) {
2421 file += "\\newpage";
2422 further_blank_line = true;
2425 if (further_blank_line){
2430 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2431 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2436 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2441 // This one spits out the text of the paragraph
2442 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2444 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2447 return SimpleTeXOneTablePar(file, texrow);
2450 size_type main_body;
2452 bool return_value = false;
2454 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2457 /* maybe we have to create a optional argument */
2458 if (style.labeltype != LABEL_MANUAL)
2461 main_body = BeginningOfMainBody();
2463 if (main_body > 0) {
2465 basefont = getFont(-2); // Get label font
2467 basefont = getFont(-1); // Get layout font
2475 if (style.isCommand()) {
2478 } else if (align != LYX_ALIGN_LAYOUT) {
2481 return_value = true;
2485 // Which font is currently active?
2486 LyXFont running_font = basefont;
2487 // Do we have an open font change?
2488 bool open_font = false;
2490 texrow.start(this, 0);
2492 for (size_type i = 0; i < size(); ++i) {
2494 // First char in paragraph or after label?
2495 if (i == main_body && !IsDummy()) {
2496 if (main_body > 0) {
2498 column += running_font.latexWriteEndChanges(file, basefont);
2501 basefont = getFont(-1); // Now use the layout font
2502 running_font = basefont;
2506 if (style.isCommand()) {
2509 } else if (align != LYX_ALIGN_LAYOUT) {
2512 return_value = true;
2516 file += "\\noindent ";
2520 case LYX_ALIGN_NONE:
2521 case LYX_ALIGN_BLOCK:
2522 case LYX_ALIGN_LAYOUT:
2523 case LYX_ALIGN_SPECIAL: break;
2524 case LYX_ALIGN_LEFT:
2525 file += "\\raggedright ";
2528 case LYX_ALIGN_RIGHT:
2529 file += "\\raggedleft ";
2532 case LYX_ALIGN_CENTER:
2533 file += "\\centering ";
2541 // Fully instantiated font
2542 LyXFont font = getFont(i);
2544 // Spaces at end of font change are simulated to be
2545 // outside font change, i.e. we write "\textXX{text} "
2546 // rather than "\textXX{text }". (Asger)
2547 if (open_font && c == ' ' && i <= size() - 2
2548 && !getFont(i+1).equalExceptLatex(running_font)
2549 && !getFont(i+1).equalExceptLatex(font)) {
2550 font = getFont(i+1);
2552 // We end font definition before blanks
2553 if (!font.equalExceptLatex(running_font) && open_font) {
2554 column += running_font.latexWriteEndChanges(file,
2556 running_font = basefont;
2560 // Blanks are printed before start of fontswitch
2562 // Do not print the separation of the optional argument
2563 if (i != main_body - 1) {
2564 SimpleTeXBlanks(file, texrow, i,
2565 column, font, style);
2569 // Do we need to change font?
2570 if (!font.equalExceptLatex(running_font)
2571 && i != main_body-1) {
2572 column += font.latexWriteStartChanges(file, basefont);
2573 running_font = font;
2577 if (c == LyXParagraph::META_NEWLINE) {
2578 // newlines are handled differently here than
2579 // the default in SimpleTeXSpecialChars().
2580 if (!style.newline_allowed
2581 || font.latex() == LyXFont::ON) {
2585 column += running_font.latexWriteEndChanges(file, basefont);
2588 basefont = getFont(-1);
2589 running_font = basefont;
2590 if (font.family() ==
2591 LyXFont::TYPEWRITER_FAMILY) {
2597 texrow.start(this, i+1);
2600 SimpleTeXSpecialChars(file, texrow,
2601 font, running_font, basefont,
2602 open_font, style, i, column, c);
2606 // If we have an open font definition, we have to close it
2608 running_font.latexWriteEndChanges(file, basefont);
2611 /* needed if there is an optional argument but no contents */
2612 if (main_body > 0 && main_body == size()) {
2614 return_value = false;
2617 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2618 return return_value;
2622 // This one spits out the text of a table paragraph
2623 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2625 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2629 bool return_value = false;
2630 int current_cell_number = -1;
2632 LyXLayout const & style =
2633 textclasslist.Style(GetCurrentTextClass(), GetLayout());
2634 LyXFont basefont = getFont(-1); // Get layout font
2635 // Which font is currently active?
2636 LyXFont running_font = basefont;
2637 // Do we have an open font change?
2638 bool open_font = false;
2641 if (!IsDummy()) { // it is dummy if it is in a float!!!
2642 if (style.isCommand()) {
2645 } else if (align != LYX_ALIGN_LAYOUT) {
2648 return_value = true;
2651 file += "\\noindent ";
2655 case LYX_ALIGN_NONE:
2656 case LYX_ALIGN_BLOCK:
2657 case LYX_ALIGN_LAYOUT:
2658 case LYX_ALIGN_SPECIAL: break;
2659 case LYX_ALIGN_LEFT:
2660 file += "\\raggedright ";
2663 case LYX_ALIGN_RIGHT:
2664 file += "\\raggedleft ";
2667 case LYX_ALIGN_CENTER:
2668 file += "\\centering ";
2673 current_cell_number = -1;
2674 tmp = table->TexEndOfCell(file, current_cell_number);
2675 for (; tmp >0 ; --tmp)
2678 texrow.start(this, 0);
2680 for (size_type i = 0; i < size(); ++i) {
2682 if (table->IsContRow(current_cell_number+1)) {
2683 if (c == LyXParagraph::META_NEWLINE)
2684 current_cell_number++;
2689 // Fully instantiated font
2690 LyXFont font = getFont(i);
2692 // Spaces at end of font change are simulated to be outside font change.
2693 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2694 if (open_font && c == ' ' && i <= size() - 2
2695 && getFont(i+1) != running_font && getFont(i+1) != font) {
2696 font = getFont(i+1);
2699 // We end font definition before blanks
2700 if (font != running_font && open_font) {
2701 column += running_font.latexWriteEndChanges(file,
2703 running_font = basefont;
2706 // Blanks are printed before start of fontswitch
2708 SimpleTeXBlanks(file, texrow, i, column, font, style);
2710 // Do we need to change font?
2711 if (font != running_font) {
2712 column += font.latexWriteStartChanges(file, basefont);
2713 running_font = font;
2716 // Do we need to turn on LaTeX mode?
2717 if (font.latex() != running_font.latex()) {
2718 if (font.latex() == LyXFont::ON
2719 && style.needprotect) {
2720 file += "\\protect ";
2724 if (c == LyXParagraph::META_NEWLINE) {
2725 // special case for inside a table
2726 // different from default case in SimpleTeXSpecialChars()
2728 column += running_font.latexWriteEndChanges(file, basefont);
2731 basefont = getFont(-1);
2732 running_font = basefont;
2733 current_cell_number++;
2734 if (table->CellHasContRow(current_cell_number) >= 0) {
2735 TeXContTableRows(file, i+1,
2736 current_cell_number,
2739 // if this cell follow only ContRows till end don't
2740 // put the EndOfCell because it is put after the
2742 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2743 current_cell_number--;
2746 int tmp = table->TexEndOfCell(file,
2747 current_cell_number);
2750 } else if (tmp < 0) {
2756 texrow.start(this, i+1);
2758 SimpleTeXSpecialChars(file, texrow,
2759 font, running_font, basefont,
2760 open_font, style, i, column, c);
2764 // If we have an open font definition, we have to close it
2766 running_font.latexWriteEndChanges(file, basefont);
2768 current_cell_number++;
2769 tmp = table->TexEndOfCell(file, current_cell_number);
2770 for (; tmp > 0; --tmp)
2772 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2773 return return_value;
2777 // This one spits out the text off ContRows in tables
2778 bool LyXParagraph::TeXContTableRows(string & file,
2779 LyXParagraph::size_type i,
2780 int current_cell_number,
2781 int & column, TexRow & texrow)
2783 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2789 bool return_value = false;
2790 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2794 basefont = getFont(-1); // Get layout font
2795 // Which font is currently active?
2796 LyXFont running_font = basefont;
2797 // Do we have an open font change?
2798 bool open_font = false;
2800 size_type lastpos = i;
2801 int cell = table->CellHasContRow(current_cell_number);
2802 current_cell_number++;
2804 // first find the right position
2806 for (; (i < size()) && (current_cell_number<cell); ++i) {
2808 if (c == LyXParagraph::META_NEWLINE)
2809 current_cell_number++;
2813 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2817 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2821 for (; i < size() && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2825 // Fully instantiated font
2826 LyXFont font = getFont(i);
2828 // Spaces at end of font change are simulated to be outside font change.
2829 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2830 if (open_font && c == ' ' && i <= size() - 2
2831 && getFont(i + 1) != running_font
2832 && getFont(i + 1) != font) {
2833 font = getFont(i + 1);
2836 // We end font definition before blanks
2837 if (font != running_font && open_font) {
2838 column += running_font.latexWriteEndChanges(file, basefont);
2839 running_font = basefont;
2842 // Blanks are printed before start of fontswitch
2844 SimpleTeXBlanks(file, texrow, i,
2845 column, font, style);
2847 // Do we need to change font?
2848 if (font != running_font) {
2850 font.latexWriteStartChanges(file,
2852 running_font = font;
2855 // Do we need to turn on LaTeX mode?
2856 if (font.latex() != running_font.latex()) {
2857 if (font.latex() == LyXFont::ON
2858 && style.needprotect)
2860 file += "\\protect ";
2864 SimpleTeXSpecialChars(file, texrow, font,
2865 running_font, basefont,
2866 open_font, style, i, column, c);
2868 // If we have an open font definition, we have to close it
2870 running_font.latexWriteEndChanges(file, basefont);
2873 basefont = getFont(-1);
2874 running_font = basefont;
2875 cell = table->CellHasContRow(current_cell_number);
2877 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2878 return return_value;
2882 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2884 bool retval = false;
2886 case LyXParagraph::META_HFILL:
2887 sgml_string.clear();
2889 case LyXParagraph::META_PROTECTED_SEPARATOR:
2892 case LyXParagraph::META_NEWLINE:
2896 sgml_string = "&";
2899 sgml_string = "<";
2902 sgml_string = ">";
2905 sgml_string = "$";
2908 sgml_string = "#";
2911 sgml_string = "%";
2914 sgml_string = "[";
2917 sgml_string = "]";
2920 sgml_string = "{";
2923 sgml_string = "}";
2926 sgml_string = "˜";
2929 sgml_string = """;
2932 sgml_string = "\";
2938 case '\0': /* Ignore :-) */
2939 sgml_string.clear();
2948 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2949 int & desc_on, int depth)
2953 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2955 int current_cell_number = -1;
2956 LyXFont font1, font2;
2959 size_type main_body;
2960 string emph = "emphasis";
2961 bool emph_flag= false;
2962 int char_line_count= 0;
2964 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2966 if (style.labeltype != LABEL_MANUAL)
2969 main_body = BeginningOfMainBody();
2971 /* gets paragraph main font */
2973 font1 = style.labelfont;
2977 char_line_count = depth;
2978 addNewlineAndDepth(file, depth);
2979 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2980 file += "<INFORMALTABLE>";
2981 addNewlineAndDepth(file, ++depth);
2983 current_cell_number = -1;
2984 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2986 /* parsing main loop */
2987 for (size_type i = 0; i < size(); ++i) {
2989 if (table->IsContRow(current_cell_number+1)) {
2990 if (c == LyXParagraph::META_NEWLINE)
2991 current_cell_number++;
2996 // Fully instantiated font
2999 /* handle <emphasis> tag */
3000 if (font1.emph() != font2.emph() && i) {
3001 if (font2.emph() == LyXFont::ON) {
3002 file += "<emphasis>";
3004 } else if (emph_flag) {
3005 file += "</emphasis>";
3009 if (c == LyXParagraph::META_NEWLINE) {
3010 // we have only to control for emphasis open here!
3012 file += "</emphasis>";
3015 font1 = font2 = getFont(-1);
3016 current_cell_number++;
3017 if (table->CellHasContRow(current_cell_number) >= 0) {
3018 DocBookContTableRows(file, extra, desc_on, i+1,
3019 current_cell_number,
3022 // if this cell follow only ContRows till end don't
3023 // put the EndOfCell because it is put after the
3025 if (table->ShouldBeVeryLastCell(current_cell_number)) {
3026 current_cell_number--;
3029 tmp= table->DocBookEndOfCell(file, current_cell_number,
3034 } else if (c == LyXParagraph::META_INSET) {
3035 inset = GetInset(i);
3037 inset->DocBook(tmp_out);
3039 // This code needs some explanation:
3040 // Two insets are treated specially
3041 // label if it is the first element in a command paragraph
3043 // graphics inside tables or figure floats can't go on
3044 // title (the equivalente in latex for this case is caption
3045 // and title should come first
3048 if(desc_on != 3 || i != 0) {
3049 if(tmp_out[0] == '@') {
3051 extra += frontStrip(tmp_out, '@');
3053 file += frontStrip(tmp_out, '@');
3057 } else if (font2.latex() == LyXFont::ON) {
3058 // "TeX"-Mode on == > SGML-Mode on.
3064 if (linuxDocConvertChar(c, sgml_string)
3065 && !style.free_spacing) {
3066 // in freespacing mode, spaces are
3067 // non-breaking characters
3072 file += "</term><listitem><para>";
3078 file += sgml_string;
3084 /* needed if there is an optional argument but no contents */
3085 if (main_body > 0 && main_body == size()) {
3090 file += "</emphasis>";
3093 current_cell_number++;
3094 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3095 /* resets description flag correctly */
3098 /* <term> not closed... */
3102 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3103 file += "</INFORMALTABLE>";
3105 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3110 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3111 int & desc_on, LyXParagraph::size_type i,
3112 int current_cell_number, int &column)
3118 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3121 LyXFont font1, font2;
3124 size_type main_body;
3126 string emph= "emphasis";
3127 bool emph_flag= false;
3128 int char_line_count= 0;
3130 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3133 if (style.labeltype != LABEL_MANUAL)
3136 main_body = BeginningOfMainBody();
3138 /* gets paragraph main font */
3140 font1 = style.labelfont;
3145 cell = table->CellHasContRow(current_cell_number);
3146 current_cell_number++;
3148 // first find the right position
3150 for (; i < size() && current_cell_number < cell; ++i) {
3152 if (c == LyXParagraph::META_NEWLINE)
3153 current_cell_number++;
3157 // I don't know how to handle this so I comment it
3158 // for the moment (Jug)
3159 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3160 // file += " \\\\\n";
3163 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3168 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3172 // Fully instantiated font
3175 /* handle <emphasis> tag */
3176 if (font1.emph() != font2.emph() && i) {
3177 if (font2.emph() == LyXFont::ON) {
3178 file += "<emphasis>";
3180 } else if (emph_flag) {
3181 file += "</emphasis>";
3185 if (c == LyXParagraph::META_INSET) {
3186 inset = GetInset(i);
3188 inset->DocBook(tmp_out);
3190 // This code needs some explanation:
3191 // Two insets are treated specially
3192 // label if it is the first element in a command paragraph
3194 // graphics inside tables or figure floats can't go on
3195 // title (the equivalente in latex for this case is caption
3196 // and title should come first
3199 if(desc_on != 3 || i != 0) {
3200 if(tmp_out[0] == '@') {
3202 extra += frontStrip(tmp_out, '@');
3204 file += frontStrip(tmp_out, '@');
3208 } else if (font2.latex() == LyXFont::ON) {
3209 // "TeX"-Mode on == > SGML-Mode on.
3215 if (linuxDocConvertChar(c, sgml_string)
3216 && !style.free_spacing) {
3217 // in freespacing mode, spaces are
3218 // non-breaking characters
3223 file += "</term><listitem><para>";
3229 file += sgml_string;
3233 // we have only to control for emphasis open here!
3235 file += "</emphasis>";
3238 font1 = font2 = getFont(-1);
3239 cell = table->CellHasContRow(current_cell_number);
3241 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3244 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3245 LyXParagraph::size_type const i,
3246 int & column, LyXFont const & font,
3247 LyXLayout const & style)
3249 if (column > tex_code_break_column
3251 && GetChar(i - 1) != ' '
3253 // In LaTeX mode, we don't want to
3254 // break lines since some commands
3256 && ! (font.latex() == LyXFont::ON)
3257 // same in FreeSpacing mode
3258 && !style.free_spacing
3259 // In typewriter mode, we want to avoid
3260 // ! . ? : at the end of a line
3261 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3262 && (GetChar(i-1) == '.'
3263 || GetChar(i-1) == '?'
3264 || GetChar(i-1) == ':'
3265 || GetChar(i-1) == '!'))) {
3266 if (tex_code_break_column == 0) {
3267 // in batchmode we need LaTeX to still
3268 // see it as a space not as an extra '\n'
3274 texrow.start(this, i+1);
3276 } else if (font.latex() == LyXFont::OFF) {
3277 if (style.free_spacing) {
3286 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3288 LyXFont & running_font,
3291 LyXLayout const & style,
3292 LyXParagraph::size_type & i,
3293 int & column, char const c)
3295 // Two major modes: LaTeX or plain
3296 // Handle here those cases common to both modes
3297 // and then split to handle the two modes separately.
3299 case LyXParagraph::META_INSET: {
3300 Inset * inset = GetInset(i);
3302 int len = file.length();
3303 int tmp = inset->Latex(file, style.isCommand());
3308 column += file.length() - len;
3317 case LyXParagraph::META_NEWLINE:
3319 column += running_font.latexWriteEndChanges(file,
3323 basefont = getFont(-1);
3324 running_font = basefont;
3327 case LyXParagraph::META_HFILL:
3328 file += "\\hfill{}";
3333 // And now for the special cases within each mode
3334 // Are we in LaTeX mode?
3335 if (font.latex() == LyXFont::ON) {
3336 // at present we only have one option
3337 // but I'll leave it as a switch statement
3338 // so its simpler to extend. (ARRae)
3340 case LyXParagraph::META_PROTECTED_SEPARATOR:
3345 // make sure that we will not print
3346 // error generating chars to the tex
3347 // file. This test would not be needed
3348 // if it were done in the buffer
3356 // Plain mode (i.e. not LaTeX)
3358 case LyXParagraph::META_PROTECTED_SEPARATOR:
3363 file += "\\textbackslash{}";
3367 case '°': case '±': case '²': case '³':
3368 case '×': case '÷': case '¹': case 'ª':
3369 case 'º': case '¬': case 'µ':
3370 if (current_view->buffer()->params.inputenc == "latin1") {
3371 file += "\\ensuremath{";
3380 case '|': case '<': case '>':
3381 // In T1 encoding, these characters exist
3382 if (lyxrc->fontenc == "T1") {
3384 //... but we should avoid ligatures
3385 if ((c == '>' || c == '<')
3387 && GetChar(i+1) == c){
3388 file += "\\textcompwordmark{}";
3393 // Typewriter font also has them
3394 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3398 // Otherwise, we use what LaTeX
3402 file += "\\textless{}";
3406 file += "\\textgreater{}";
3410 file += "\\textbar{}";
3416 case '-': // "--" in Typewriter mode -> "-{}-"
3418 && GetChar(i + 1) == '-'
3419 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3428 file += "\\char`\\\"{}";
3433 if (current_view->buffer()->params.inputenc == "default") {
3434 file += "\\pounds{}";
3442 case '%': case '#': case '{':
3450 file += "\\textasciitilde{}";
3455 file += "\\textasciicircum{}";
3459 case '*': case '[': case ']':
3460 // avoid being mistaken for optional arguments
3468 /* blanks are printed before font switching */
3469 // Sure? I am not! (try nice-latex)
3470 // I am sure it's correct. LyX might be smarter
3471 // in the future, but for now, nothing wrong is
3476 /* idea for labels --- begin*/
3480 && font.family() != LyXFont::TYPEWRITER_FAMILY
3481 && GetChar(i + 1) == 'y'
3482 && GetChar(i + 2) == 'X') {
3490 && font.family() != LyXFont::TYPEWRITER_FAMILY
3491 && GetChar(i + 1) == 'e'
3492 && GetChar(i + 2) == 'X') {
3497 /* check for LaTeX2e */
3500 && font.family() != LyXFont::TYPEWRITER_FAMILY
3501 && GetChar(i + 1) == 'a'
3502 && GetChar(i + 2) == 'T'
3503 && GetChar(i + 3) == 'e'
3504 && GetChar(i + 4) == 'X'
3505 && GetChar(i + 5) == '2'
3506 && GetChar(i + 6) == 'e') {
3507 file += "\\LaTeXe{}";
3511 /* check for LaTeX */
3514 && font.family() != LyXFont::TYPEWRITER_FAMILY
3515 && GetChar(i + 1) == 'a'
3516 && GetChar(i + 2) == 'T'
3517 && GetChar(i + 3) == 'e'
3518 && GetChar(i + 4) == 'X') {
3519 file += "\\LaTeX{}";
3522 /* idea for labels --- end*/
3523 } else if (c != '\0') {
3533 bool LyXParagraph::RoffContTableRows(FILE * fp,
3534 LyXParagraph::size_type i,
3540 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3546 string fname2 = TmpFileName(string(), "RAT2");
3548 int cell = table->CellHasContRow(actcell);
3551 // first find the right position
3553 for (; i < size() && actcell < cell; ++i) {
3555 if (c == LyXParagraph::META_NEWLINE)
3560 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3563 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3565 font2 = GetFontSettings(i);
3566 if (font1.latex() != font2.latex()) {
3567 if (font2.latex() != LyXFont::OFF)
3572 case LyXParagraph::META_INSET:
3573 if ((inset = GetInset(i))) {
3574 if (!(fp2= fopen(fname2.c_str(), "w+"))) {
3575 WriteAlert(_("LYX_ERROR:"),
3576 _("Cannot open temporary file:"),
3580 inset->Latex(fp2,-1);
3585 fprintf(fp, "\\\\");
3593 case LyXParagraph::META_NEWLINE:
3595 case LyXParagraph::META_HFILL:
3597 case LyXParagraph::META_PROTECTED_SEPARATOR:
3600 fprintf(fp, "\\\\");
3604 fprintf(fp, "%c", c);
3606 lyxerr.debug() << "RoffAsciiTable: NULL char in structure." << endl;
3610 cell = table->CellHasContRow(actcell);
3616 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3617 string & foot, TexRow & foot_texrow,
3620 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3621 LyXParagraph * par = this;
3623 while (par && par->depth == depth) {
3625 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3626 if (textclasslist.Style(GetCurrentTextClass(),
3627 par->layout).isEnvironment()
3628 || par->pextra_type != PEXTRA_NONE)
3630 par = par->TeXEnvironment(file, texrow,
3634 par = par->TeXOnePar(file, texrow,
3639 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3645 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3646 string & foot, TexRow & foot_texrow,
3649 bool eindent_open = false;
3650 bool foot_this_level = false;
3651 // flags when footnotetext should be appended to file.
3652 static bool minipage_open = false;
3653 static int minipage_open_depth = 0;
3654 char par_sep = current_view->buffer()->params.paragraph_separation;
3656 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3658 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3660 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3663 if (pextra_type == PEXTRA_INDENT) {
3664 if (!pextra_width.empty()) {
3665 file += "\\begin{LyXParagraphIndent}{"
3666 + pextra_width + "}\n";
3668 //float ib = atof(pextra_widthp.c_str())/100;
3669 // string can't handle floats at present (971109)
3670 // so I'll do a conversion by hand knowing that
3671 // the limits are 0.0 to 1.0. ARRae.
3672 file += "\\begin{LyXParagraphIndent}{";
3673 switch (pextra_widthp.length()) {
3679 file += pextra_widthp;
3683 file += pextra_widthp;
3685 file += "\\columnwidth}\n";
3688 eindent_open = true;
3690 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3691 if (pextra_hfill && Previous() &&
3692 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3693 file += "\\hfill{}\n";
3696 if (par_sep == BufferParams::PARSEP_INDENT) {
3697 file += "{\\setlength\\parindent{0pt}\n";
3700 file += "\\begin{minipage}";
3701 switch(pextra_alignment) {
3702 case MINIPAGE_ALIGN_TOP:
3705 case MINIPAGE_ALIGN_MIDDLE:
3708 case MINIPAGE_ALIGN_BOTTOM:
3712 if (!pextra_width.empty()) {
3714 file += pextra_width + "}\n";
3716 //float ib = atof(par->pextra_width.c_str())/100;
3717 // string can't handle floats at present
3718 // so I'll do a conversion by hand knowing that
3719 // the limits are 0.0 to 1.0. ARRae.
3721 switch (pextra_widthp.length()) {
3727 file += pextra_widthp;
3731 file += pextra_widthp;
3733 file += "\\columnwidth}\n";
3736 if (par_sep == BufferParams::PARSEP_INDENT) {
3737 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3740 minipage_open = true;
3741 minipage_open_depth = depth;
3744 #ifdef WITH_WARNINGS
3745 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3746 //I disabled it because it breaks when lists span on several
3749 if (style.isEnvironment()){
3750 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3751 #ifdef FANCY_FOOTNOTE_CODE
3752 if (foot_count < 0) {
3753 // flag that footnote[mark][text] should be
3754 // used for any footnotes from now on
3756 foot_this_level = true;
3759 file += "\\begin{" + style.latexname() + "}{"
3760 + labelwidthstring + "}\n";
3761 } else if (style.labeltype == LABEL_BIBLIO) {
3763 file += "\\begin{" + style.latexname() + "}{"
3764 + bibitemWidthest() + "}\n";
3765 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3766 #ifdef FANCY_FOOTNOTE_CODE
3767 if (foot_count < 0) {
3768 // flag that footnote[mark][text] should be
3769 // used for any footnotes from now on
3771 foot_this_level = true;
3774 file += "\\begin{" + style.latexname() + '}'
3775 + style.latexparam() + '\n';
3777 file += "\\begin{" + style.latexname() + '}'
3778 + style.latexparam() + '\n';
3781 LyXParagraph * par = this;
3783 par = par->TeXOnePar(file, texrow,
3784 foot, foot_texrow, foot_count);
3786 if (minipage_open && par && !style.isEnvironment() &&
3787 (par->pextra_type == PEXTRA_MINIPAGE) &&
3788 par->pextra_start_minipage) {
3789 file += "\\end{minipage}\n";
3791 if (par_sep == BufferParams::PARSEP_INDENT) {
3795 minipage_open = false;
3797 if (par && par->depth > depth) {
3798 if (textclasslist.Style(GetCurrentTextClass(),
3799 par->layout).isParagraph()
3801 && !suffixIs(file, "\n\n")) {
3802 // There should be at least one '\n' already
3803 // but we need there to be two for Standard
3804 // paragraphs that are depth-increment'ed to be
3805 // output correctly. However, tables can also be
3806 // paragraphs so don't adjust them. ARRae
3810 par = par->TeXDeeper(file, texrow,
3811 foot, foot_texrow, foot_count);
3813 if (par && par->layout == layout && par->depth == depth &&
3814 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3815 if (par->pextra_hfill && par->Previous() &&
3816 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3817 file += "\\hfill{}\n";
3820 if (par_sep == BufferParams::PARSEP_INDENT) {
3821 file += "{\\setlength\\parindent{0pt}\n";
3824 file += "\\begin{minipage}";
3825 switch(par->pextra_alignment) {
3826 case MINIPAGE_ALIGN_TOP:
3829 case MINIPAGE_ALIGN_MIDDLE:
3832 case MINIPAGE_ALIGN_BOTTOM:
3836 if (!par->pextra_width.empty()) {
3838 file += par->pextra_width;
3841 //float ib = atof(par->pextra_widthp.c_str())/100;
3842 // string can't handle floats at present
3843 // so I'll do a conversion by hand knowing that
3844 // the limits are 0.0 to 1.0. ARRae.
3846 switch (par->pextra_widthp.length()) {
3852 file += par->pextra_widthp;
3856 file += par->pextra_widthp;
3858 file += "\\columnwidth}\n";
3861 if (par_sep == BufferParams::PARSEP_INDENT) {
3862 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3865 minipage_open = true;
3866 minipage_open_depth = par->depth;
3869 && par->layout == layout
3870 && par->depth == depth
3871 && par->pextra_type == pextra_type);
3873 if (style.isEnvironment()) {
3874 file += "\\end{" + style.latexname() + '}';
3875 // maybe this should go after the minipage closes?
3876 if (foot_this_level) {
3877 if (foot_count >= 1) {
3878 if (foot_count > 1) {
3879 file += "\\addtocounter{footnote}{-";
3880 file += tostr(foot_count - 1);
3884 texrow += foot_texrow;
3886 foot_texrow.reset();
3891 if (minipage_open && (minipage_open_depth == depth) &&
3892 (!par || par->pextra_start_minipage ||
3893 par->pextra_type != PEXTRA_MINIPAGE)) {
3894 file += "\\end{minipage}\n";
3896 if (par_sep == BufferParams::PARSEP_INDENT) {
3900 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3901 file += "\\medskip\n\n";
3905 minipage_open = false;
3908 file += "\\end{LyXParagraphIndent}\n";
3911 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3912 && par->pextra_hfill)) {
3916 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3917 return par; // ale970302
3921 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3922 string & foot, TexRow & foot_texrow,
3925 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3926 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3927 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3928 "No footnote!" << endl;
3930 LyXParagraph * par = this;
3931 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3932 previous->GetLayout());
3934 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3935 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3936 "Float other than footnote in command"
3937 " with moving argument is illegal" << endl;
3940 if (footnotekind != LyXParagraph::FOOTNOTE
3941 && footnotekind != LyXParagraph::MARGIN
3943 && !suffixIs(file, '\n')) {
3944 // we need to ensure that real floats like tables and figures
3945 // have their \begin{} on a new line otherwise we can get
3946 // incorrect results when using the endfloat.sty package
3947 // especially if two floats follow one another. ARRae 981022
3948 // NOTE: if the file is length 0 it must have just been
3949 // written out so we assume it ended with a '\n'
3954 BufferParams * params = ¤t_view->buffer()->params;
3955 bool footer_in_body = true;
3956 switch (footnotekind) {
3957 case LyXParagraph::FOOTNOTE:
3958 if (style.intitle) {
3959 file += "\\thanks{\n";
3960 footer_in_body = false;
3962 if (foot_count == -1) {
3963 // we're at depth 0 so we can use:
3964 file += "\\footnote{%\n";
3965 footer_in_body = false;
3967 file += "\\footnotemark{}%\n";
3969 // we only need this when there are
3970 // multiple footnotes
3971 foot += "\\stepcounter{footnote}";
3973 foot += "\\footnotetext{%\n";
3974 foot_texrow.start(this, 0);
3975 foot_texrow.newline();
3980 case LyXParagraph::MARGIN:
3981 file += "\\marginpar{\n";
3983 case LyXParagraph::FIG:
3984 if (pextra_type == PEXTRA_FLOATFLT
3985 && (!pextra_width.empty()
3986 || !pextra_widthp.empty())) {
3988 if (!pextra_width.empty())
3989 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3990 pextra_width.c_str());
3992 sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
3993 atoi(pextra_widthp.c_str())/100.0);
3996 file += "\\begin{figure}";
3997 if (!params->float_placement.empty()) {
3999 file += params->float_placement;
4006 case LyXParagraph::TAB:
4007 file += "\\begin{table}";
4008 if (!params->float_placement.empty()) {
4010 file += params->float_placement;
4016 case LyXParagraph::WIDE_FIG:
4017 file += "\\begin{figure*}";
4018 if (!params->float_placement.empty()) {
4020 file += params->float_placement;
4026 case LyXParagraph::WIDE_TAB:
4027 file += "\\begin{table*}";
4028 if (!params->float_placement.empty()) {
4030 file += params->float_placement;
4036 case LyXParagraph::ALGORITHM:
4037 file += "\\begin{algorithm}\n";
4042 if (footnotekind != LyXParagraph::FOOTNOTE
4043 || !footer_in_body) {
4044 // Process text for all floats except footnotes in body
4046 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
4049 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4051 if (style.isEnvironment()
4052 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4053 // Allows the use of minipages within float environments.
4054 // Shouldn't be circular because we don't support
4055 // footnotes inside floats (yet). ARRae
4056 par = par->TeXEnvironment(file, texrow,
4060 par = par->TeXOnePar(file, texrow,
4065 if (par && !par->IsDummy() && par->depth > depth) {
4066 par = par->TeXDeeper(file, texrow,
4070 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4072 // process footnotes > depth 0 or in environments separately
4073 // NOTE: Currently don't support footnotes within footnotes
4074 // even though that is possible using the \footnotemark
4076 TexRow dummy_texrow;
4077 int dummy_count = 0;
4079 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
4082 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4084 if (style.isEnvironment()
4085 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4086 // Allows the use of minipages within float environments.
4087 // Shouldn't be circular because we don't support
4088 // footnotes inside floats (yet). ARRae
4089 par = par->TeXEnvironment(foot, foot_texrow,
4090 dummy, dummy_texrow,
4093 par = par->TeXOnePar(foot, foot_texrow,
4094 dummy, dummy_texrow,
4098 if (par && !par->IsDummy() && par->depth > depth) {
4099 par = par->TeXDeeper(foot, foot_texrow,
4100 dummy, dummy_texrow,
4103 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4105 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4106 "Footnote in a Footnote -- not supported"
4111 switch (footnotekind) {
4112 case LyXParagraph::FOOTNOTE:
4113 if (footer_in_body) {
4114 // This helps tell which of the multiple
4115 // footnotetexts an error was in.
4117 foot_texrow.newline();
4122 case LyXParagraph::MARGIN:
4125 case LyXParagraph::FIG:
4126 if (pextra_type == PEXTRA_FLOATFLT
4127 && (!pextra_width.empty()
4128 || !pextra_widthp.empty()))
4129 file += "\\end{floatingfigure}";
4131 file += "\\end{figure}";
4133 case LyXParagraph::TAB:
4134 file += "\\end{table}";
4136 case LyXParagraph::WIDE_FIG:
4137 file += "\\end{figure*}";
4139 case LyXParagraph::WIDE_TAB:
4140 file += "\\end{table*}";
4142 case LyXParagraph::ALGORITHM:
4143 file += "\\end{algorithm}";
4147 if (footnotekind != LyXParagraph::FOOTNOTE
4148 && footnotekind != LyXParagraph::MARGIN) {
4149 // we need to ensure that real floats like tables and figures
4150 // have their \end{} on a line of their own otherwise we can
4151 // get incorrect results when using the endfloat.sty package.
4156 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4161 void LyXParagraph::SetPExtraType(int type, char const * width,
4162 char const * widthp)
4165 pextra_width = width;
4166 pextra_widthp = widthp;
4168 if (textclasslist.Style(GetCurrentTextClass(),
4169 layout).isEnvironment()) {
4174 while (par && (par->layout == layout) && (par->depth == depth)) {
4176 par = par->Previous();
4178 par = par->FirstPhysicalPar();
4179 while (par && par->depth > depth) {
4180 par = par->Previous();
4182 par = par->FirstPhysicalPar();
4186 while (par && (par->layout == layout) && (par->depth == depth)) {
4187 par->pextra_type = type;
4188 par->pextra_width = width;
4189 par->pextra_widthp = widthp;
4190 par = par->NextAfterFootnote();
4191 if (par && (par->depth > depth))
4192 par->SetPExtraType(type, width, widthp);
4193 while (par && ((par->depth > depth) || par->IsDummy()))
4194 par = par->NextAfterFootnote();
4200 void LyXParagraph::UnsetPExtraType()
4202 if (pextra_type == PEXTRA_NONE)
4205 pextra_type = PEXTRA_NONE;
4206 pextra_width.clear();
4207 pextra_widthp.clear();
4209 if (textclasslist.Style(GetCurrentTextClass(),
4210 layout).isEnvironment()) {
4215 while (par && (par->layout == layout) && (par->depth == depth)) {
4217 par = par->Previous();
4219 par = par->FirstPhysicalPar();
4220 while (par && par->depth > depth) {
4221 par = par->Previous();
4223 par = par->FirstPhysicalPar();
4227 while (par && (par->layout == layout) && (par->depth == depth)) {
4228 par->pextra_type = PEXTRA_NONE;
4229 par->pextra_width.clear();
4230 par->pextra_widthp.clear();
4231 par = par->NextAfterFootnote();
4232 if (par && (par->depth > depth))
4233 par->UnsetPExtraType();
4234 while (par && ((par->depth > depth) || par->IsDummy()))
4235 par = par->NextAfterFootnote();
4241 bool LyXParagraph::IsHfill(size_type pos) const
4243 return IsHfillChar(GetChar(pos));
4247 bool LyXParagraph::IsInset(size_type pos) const
4249 return IsInsetChar(GetChar(pos));
4253 bool LyXParagraph::IsFloat(size_type pos) const
4255 return IsFloatChar(GetChar(pos));
4259 bool LyXParagraph::IsNewline(size_type pos) const
4263 tmp = IsNewlineChar(GetChar(pos));
4268 bool LyXParagraph::IsSeparator(size_type pos) const
4270 return IsSeparatorChar(GetChar(pos));
4274 bool LyXParagraph::IsLineSeparator(size_type pos) const
4276 return IsLineSeparatorChar(GetChar(pos));
4280 bool LyXParagraph::IsKomma(size_type pos) const
4282 return IsKommaChar(GetChar(pos));
4286 /// Used by the spellchecker
4287 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4289 unsigned char c = GetChar(pos);
4290 if (IsLetterChar(c))
4292 // '\0' is not a letter, allthough every string contains "" (below)
4295 // We want to pass the ' and escape chars to ispell
4296 string extra = lyxrc->isp_esc_chars + '\'';
4300 return contains(extra, ch);
4304 bool LyXParagraph::IsWord(size_type pos ) const
4306 return IsWordChar( GetChar(pos) ) ;