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)
85 #warning we also need a reserve here
86 #warning this would be a nice place to shrink par
87 for (int i = 0; i < 10; ++i) setCounter(i, 0);
93 next->previous = this;
95 previous->next = this;
100 footnoteflag = LyXParagraph::NO_FOOTNOTE;
101 footnotekind = LyXParagraph::FOOTNOTE;
103 /* table stuff -- begin*/
105 /* table stuff -- end*/
106 id_ = paragraph_id++;
108 bibkey = 0; // ale970302
114 void LyXParagraph::writeFile(FILE * file, BufferParams & params,
115 char footflag, char dth)
117 LyXFont font1, font2;
123 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
125 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
127 /* The beginning or the end of a footnote environment? */
128 if (footflag != footnoteflag) {
129 footflag = footnoteflag;
131 fprintf(file, "\n\\begin_float %s ",
132 string_footnotekinds[footnotekind]);
135 fprintf(file, "\n\\end_float ");
139 /* The beginning or end of a deeper (i.e. nested) area? */
142 while (depth > dth) {
143 fprintf(file, "\n\\begin_deeper ");
148 while (depth < dth) {
149 fprintf(file, "\n\\end_deeper ");
155 /* First write the layout */
156 fprintf(file, "\n\\layout %s\n",
157 textclasslist.NameOfLayout(params.textclass, layout)
160 /* maybe some vertical spaces */
161 if (added_space_top.kind() != VSpace::NONE)
162 fprintf(file, "\\added_space_top %s ",
163 added_space_top.asLyXCommand().c_str());
164 if (added_space_bottom.kind() != VSpace::NONE)
165 fprintf(file, "\\added_space_bottom %s ",
166 added_space_bottom.asLyXCommand().c_str());
168 /* The labelwidth string used in lists */
169 if (!labelwidthstring.empty())
170 fprintf(file, "\\labelwidthstring %s\n",
171 labelwidthstring.c_str());
173 /* Lines above or below? */
175 fprintf(file, "\\line_top ");
177 fprintf(file, "\\line_bottom ");
179 /* Pagebreaks above or below? */
181 fprintf(file, "\\pagebreak_top ");
182 if (pagebreak_bottom)
183 fprintf(file, "\\pagebreak_bottom ");
185 /* Start of appendix? */
186 if (start_of_appendix)
187 fprintf(file, "\\start_of_appendix ");
191 fprintf(file, "\\noindent ");
194 if (align != LYX_ALIGN_LAYOUT) {
196 case LYX_ALIGN_LEFT: h = 1; break;
197 case LYX_ALIGN_RIGHT: h = 2; break;
198 case LYX_ALIGN_CENTER: h = 3; break;
199 default: h = 0; break;
201 fprintf(file, "\\align %s ", string_align[h]);
203 if (pextra_type != PEXTRA_NONE) {
204 fprintf(file, "\\pextra_type %d", pextra_type);
205 if (pextra_type == PEXTRA_MINIPAGE) {
206 fprintf(file, " \\pextra_alignment %d",
209 fprintf(file, " \\pextra_hfill %d",
211 if (pextra_start_minipage)
213 " \\pextra_start_minipage %d",
214 pextra_start_minipage);
216 if (!pextra_width.empty()) {
217 fprintf(file, " \\pextra_width %s",
219 .asLyXCommand().c_str());
220 } else if (!pextra_widthp.empty()) {
221 fprintf(file, " \\pextra_widthp %s",
222 pextra_widthp.c_str());
228 /* Dummy layout. This means that a footnote ended */
229 fprintf(file, "\n\\end_float ");
230 footflag = LyXParagraph::NO_FOOTNOTE;
233 /* It might be a table */
235 fprintf(file, "\\LyXTable\n");
243 font1 = LyXFont(LyXFont::ALL_INHERIT);
246 for (size_type i = 0; i < size(); i++) {
252 // Write font changes
253 font2 = GetFontSettings(i);
254 if (font2 != font1) {
255 font2.lyxWriteChanges(font1, file);
265 if (inset->DirectWrite()) {
266 // international char, let it write
267 // code directly so it's shorter in
271 fprintf(file, "\n\\begin_inset ");
273 fprintf(file, "\n\\end_inset \n");
279 fprintf(file, "\n\\newline \n");
283 fprintf(file, "\n\\hfill \n");
286 case META_PROTECTED_SEPARATOR:
287 fprintf(file, "\n\\protected_separator \n");
291 fprintf(file, "\n\\backslash \n");
295 if (i + 1 < size() && GetChar(i + 1) == ' ') {
296 fprintf(file, ".\n");
302 if ((column > 70 && c == ' ')
307 // this check is to amend a bug. LyX sometimes
308 // inserts '\0' this could cause problems.
310 fprintf(file, "%c", c);
312 lyxerr << "ERROR (LyXParagraph::writeFile):"
313 " NULL char in structure." << endl;
319 // now write the next paragraph
321 next->writeFile(file, params, footflag, dth);
325 void LyXParagraph::validate(LaTeXFeatures & features)
327 // this will be useful later
328 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
332 if (line_top || line_bottom)
333 features.lyxline = true;
336 features.layout[GetLayout()] = true;
339 for (FontList::const_iterator cit = fontlist.begin();
340 cit != fontlist.end(); ++cit) {
341 if ((*cit).font.noun() == LyXFont::ON) {
342 lyxerr[Debug::LATEX] << "font.noun: "
343 << (*cit).font.noun()
345 features.noun = true;
346 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
347 << (*cit).font.stateText()
350 switch ((*cit).font.color()) {
352 case LyXFont::INHERIT_COLOR:
353 case LyXFont::IGNORE_COLOR: break;
355 features.color = true;
356 lyxerr[Debug::LATEX] << "Color enabled. Font: "
357 << (*cit).font.stateText()
363 FontTable * tmpfonttable = fonttable;
364 while (tmpfonttable) {
365 if (tmpfonttable->font.noun() == LyXFont::ON) {
366 lyxerr[Debug::LATEX] << "font.noun: "
367 << tmpfonttable->font.noun()
369 features.noun = true;
370 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
371 << tmpfonttable->font.stateText()
374 switch (tmpfonttable->font.color()) {
376 case LyXFont::INHERIT_COLOR:
377 case LyXFont::IGNORE_COLOR:
380 features.color = true;
381 lyxerr[Debug::LATEX] << "Color enabled. Font: "
382 << tmpfonttable->font.stateText()
385 tmpfonttable = tmpfonttable->next;
389 for (InsetList::const_iterator cit = insetlist.begin();
390 cit != insetlist.end(); ++cit) {
391 (*cit).inset->Validate(features);
395 InsetTable * tmpinsettable = insettable;
396 while (tmpinsettable) {
397 if (tmpinsettable->inset) {
398 tmpinsettable->inset->Validate(features);
400 tmpinsettable = tmpinsettable->next;
403 if (table && table->IsLongTable())
404 features.longtable = true;
405 if (pextra_type == PEXTRA_INDENT)
406 features.LyXParagraphIndent = true;
407 if (pextra_type == PEXTRA_FLOATFLT)
408 features.floatflt = true;
409 if (layout.needprotect
410 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
411 features.NeedLyXFootnoteCode = true;
412 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
413 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
414 features.NeedLyXMinipageIndent = true;
415 if (table && table->NeedRotating())
416 features.rotating = true;
417 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
418 features.algorithm = true;
422 /* first few functions needed for cut and paste and paragraph breaking */
423 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const
425 minibuffer_char = GetChar(pos);
426 minibuffer_font = GetFontSettings(pos);
427 minibuffer_inset = 0;
428 if (minibuffer_char == LyXParagraph::META_INSET) {
430 minibuffer_inset = GetInset(pos)->Clone();
432 minibuffer_inset = 0;
433 minibuffer_char = ' ';
434 // This reflects what GetInset() does (ARRae)
439 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
441 minibuffer_char = GetChar(pos);
442 minibuffer_font = GetFontSettings(pos);
443 minibuffer_inset = 0;
444 if (minibuffer_char == LyXParagraph::META_INSET) {
446 minibuffer_inset = GetInset(pos);
447 // This is a little hack since I want exactly
448 // the inset, not just a clone. Otherwise
449 // the inset would be deleted when calling Erase(pos)
451 for (InsetList::iterator it = insetlist.begin();
452 it != insetlist.end(); ++it) {
453 if ((*it).pos == pos) {
460 InsetTable * tmpi = insettable;
461 while (tmpi && tmpi->pos != pos) {
464 if (tmpi) { /* This should always be true */
469 minibuffer_inset = 0;
470 minibuffer_char = ' ';
471 // This reflects what GetInset() does (ARRae)
476 /* Erase(pos); now the caller is responsible for that*/
480 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
482 InsertChar(pos, minibuffer_char);
483 SetFont(pos, minibuffer_font);
484 if (minibuffer_char == LyXParagraph::META_INSET)
485 InsertInset(pos, minibuffer_inset);
488 /* end of minibuffer */
492 void LyXParagraph::Clear()
497 pagebreak_top = false;
498 pagebreak_bottom = false;
500 added_space_top = VSpace(VSpace::NONE);
501 added_space_bottom = VSpace(VSpace::NONE);
503 align = LYX_ALIGN_LAYOUT;
507 pextra_type = PEXTRA_NONE;
508 pextra_width.clear();
509 pextra_widthp.clear();
510 pextra_alignment = MINIPAGE_ALIGN_TOP;
511 pextra_hfill = false;
512 pextra_start_minipage = false;
515 labelwidthstring.clear();
519 start_of_appendix = false;
523 /* the destructor removes the new paragraph from the list */
524 LyXParagraph::~LyXParagraph()
527 previous->next = next;
529 next->previous = previous;
532 InsetTable * tmpinset;
534 tmpinset = insettable;
535 insettable = insettable->next;
537 delete tmpinset->inset;
539 if (insettable && insettable->next == insettable) {
540 // somehow this recursion appears occasionally
541 // but I can't find where. This bandaid
542 // helps but isn't the best fix. (ARRae)
543 if (insettable->inset) {
544 delete insettable->inset;
554 fonttable = fonttable->next;
559 /* table stuff -- begin*/
562 /* table stuff -- end*/
570 void LyXParagraph::Erase(LyXParagraph::size_type pos)
572 /* > because last is the next unused position, and you can
573 * use it if you want */
575 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
576 NextAfterFootnote()->Erase(pos - text.size() - 1);
578 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
579 "position does not exist." << endl;
582 if (pos < size()) { // last is free for insertation, but should be empty
584 /* if it is an inset, delete the inset entry */
585 if (text[pos] == LyXParagraph::META_INSET) {
587 for(InsetList::iterator it = insetlist.begin();
588 it != insetlist.end(); ++it) {
589 if ((*it).pos == pos) {
597 /* if it is an inset, delete the inset entry */
598 if (text[pos] == LyXParagraph::META_INSET) {
600 InsetTable *tmpi = insettable;
601 InsetTable *tmpi2 = tmpi;
602 while (tmpi && tmpi->pos != pos) {
606 if (tmpi) { // this should always be true
607 if (tmpi->inset) // delete the inset if it exists
609 if (tmpi == insettable)
610 insettable = tmpi->next;
612 tmpi2->next = tmpi->next;
617 text.erase(text.begin() + pos);
619 /* erase entries in the tables */
620 for(FontList::iterator it = fontlist.begin();
621 it != fontlist.end(); ++it) {
622 if (pos >= (*it).pos && pos <= (*it).pos_end) {
623 if ((*it).pos == (*it).pos_end) {
630 /* update all other entries */
631 for(FontList::iterator it = fontlist.begin();
632 it != fontlist.end(); ++it) {
635 if ((*it).pos_end >= pos)
639 /* update the inset table */
640 for(InsetList::iterator it = insetlist.begin();
641 it != insetlist.end(); ++it) {
646 /* erase entries in the tables */
648 FontTable * tmp = fonttable;
649 FontTable * prev = 0;
650 while (tmp && !found) {
651 if (pos >= tmp->pos && pos <= tmp->pos_end)
659 if (found && tmp->pos == tmp->pos_end) {
660 /* if it is a multi-character font entry, we just make
661 * it smaller (see update below), otherwise we should
664 prev->next = tmp->next;
666 fonttable = tmp->next;
671 /* update all other entries */
677 if (tmp->pos_end >= pos)
682 /* update the inset table */
683 InsetTable * tmpi = insettable;
691 lyxerr << "ERROR (LyXParagraph::Erase): "
692 "can't erase non-existant char." << endl;
697 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
699 /* > because last is the next unused position, and you can
700 * use it if you want */
703 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
704 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
707 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
708 "position does not exist." << endl;
711 text.insert(text.begin() + pos, c);
713 // update the font table
714 for(FontList::iterator it = fontlist.begin();
715 it != fontlist.end(); ++it) {
716 if ((*it).pos >= pos)
718 if ((*it).pos_end >= pos)
721 // update the inset table
722 for(InsetList::iterator it = insetlist.begin();
723 it != insetlist.end(); ++it) {
724 if ((*it).pos >= pos)
728 /* update the font table */
729 FontTable * tmp = fonttable;
733 if (tmp->pos_end >= pos)
738 /* update the inset table */
739 InsetTable * tmpi = insettable;
741 if (tmpi->pos >= pos)
749 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
752 /* > because last is the next unused position, and you can
753 * use it if you want */
756 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
758 ->InsertInset(pos - text.size() - 1, inset);
760 lyxerr << "ERROR (LyXParagraph::InsertInset): "
761 "position does not exist: " << pos << endl;
764 if (text[pos] != LyXParagraph::META_INSET) {
765 lyxerr << "ERROR (LyXParagraph::InsertInset): "
766 "there is no LyXParagraph::META_INSET" << endl;
775 insetlist.push_back(tmp);
780 /* add a new entry in the inset table */
781 InsetTable * tmpi = new InsetTable;
784 tmpi->next = insettable;
791 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
795 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
796 return NextAfterFootnote()
797 ->GetInset(pos - text.size() - 1);
799 lyxerr << "ERROR (LyXParagraph::GetInset): "
800 "position does not exist: "
807 for(InsetList::iterator it = insetlist.begin();
808 it != insetlist.end(); ++it) {
809 if ((*it).pos == pos) {
813 lyxerr << "ERROR (LyXParagraph::GetInset): "
814 "Inset does not exist: " << pos << endl;
815 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
816 // Did this commenting out introduce a bug? So far I have not
817 // seen any, please enlighten me. (Lgb)
818 // My guess is that since the inset does not exist, we might
819 // as well replace it with a space to prevent crashes. (Asger)
823 InsetTable * tmpi = insettable;
825 while (tmpi && tmpi->pos != pos)
831 lyxerr << "ERROR (LyXParagraph::GetInset): "
832 "Inset does not exist: " << pos << endl;
833 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
834 // Did this commenting out introduce a bug? So far I have not
835 // seen any, please enlighten me. (Lgb)
836 // My guess is that since the inset does not exist, we might
837 // as well replace it with a space to prevent crashes. (Asger)
844 Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const
848 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
849 return NextAfterFootnote()
850 ->GetInset(pos - text.size() - 1);
852 lyxerr << "ERROR (LyXParagraph::GetInset): "
853 "position does not exist: "
860 for(InsetList::const_iterator cit = insetlist.begin();
861 cit != insetlist.end(); ++cit) {
862 if ((*cit).pos == pos) {
866 lyxerr << "ERROR (LyXParagraph::GetInset): "
867 "Inset does not exist: " << pos << endl;
868 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
869 // Did this commenting out introduce a bug? So far I have not
870 // seen any, please enlighten me. (Lgb)
871 // My guess is that since the inset does not exist, we might
872 // as well replace it with a space to prevent crashes. (Asger)
876 InsetTable * tmpi = insettable;
878 while (tmpi && tmpi->pos != pos)
884 lyxerr << "ERROR (LyXParagraph::GetInset): "
885 "Inset does not exist: " << pos << endl;
886 // in the const version we need to comment it out anyway...
887 //text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
888 // Did this commenting out introduce a bug? So far I have not
889 // seen any, please enlighten me. (Lgb)
890 // My guess is that since the inset does not exist, we might
891 // as well replace it with a space to prevent crashes. (Asger)
898 // Gets uninstantiated font setting at position.
899 // Optimized after profiling. (Asger)
900 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const
904 for(FontList::iterator it = fontlist.begin();
905 it != fontlist.end(); ++it) {
906 if (pos >= (*it).pos && pos <= (*it).pos_end)
910 FontTable * tmp = fonttable;
912 if (pos >= tmp->pos && pos <= tmp->pos_end)
918 /* > because last is the next unused position, and you can
919 * use it if you want */
920 else if (pos > size()) {
922 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
923 return NextAfterFootnote()
924 ->GetFontSettings(pos - text.size() - 1);
926 // Why is it an error to ask for the font of a
927 // position that does not exist? Would it be
928 // enough for this to be anable on debug?
929 // We want strict error checking, but it's ok to only
930 // have it when debugging. (Asger)
931 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
932 "position does not exist. "
933 << pos << " (" << static_cast<int>(pos)
937 return GetFontSettings(pos - 1);
939 return LyXFont(LyXFont::ALL_INHERIT);
943 // Gets the fully instantiated font at a given position in a paragraph
944 // This is basically the same function as LyXText::GetFont() in text2.C.
945 // The difference is that this one is used for generating the LaTeX file,
946 // and thus cosmetic "improvements" are disallowed: This has to deliver
947 // the true picture of the buffer. (Asger)
948 // If position is -1, we get the layout font of the paragraph.
949 // If position is -2, we get the font of the manual label of the paragraph.
950 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
953 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
955 LyXParagraph::size_type main_body = 0;
956 if (layout.labeltype == LABEL_MANUAL)
957 main_body = BeginningOfMainBody();
962 layoutfont = layout.labelfont;
964 layoutfont = layout.font;
965 tmpfont = GetFontSettings(pos);
966 tmpfont.realize(layoutfont);
968 // process layoutfont for pos == -1 and labelfont for pos < -1
970 tmpfont = layout.font;
972 tmpfont = layout.labelfont;
975 // check for environment font information
976 char par_depth = GetDepth();
977 LyXParagraph const * par = this;
978 while (par && par_depth && !tmpfont.resolved()) {
979 par = par->DepthHook(par_depth - 1);
981 tmpfont.realize(textclasslist.
982 Style(GetCurrentTextClass(),
983 par->GetLayout()).font);
984 par_depth = par->GetDepth();
988 tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
993 /// Returns the height of the highest font in range
994 LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
996 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
998 for(FontList::const_iterator cit = fontlist.begin();
999 cit != fontlist.end(); ++cit) {
1000 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
1001 LyXFont::FONT_SIZE size = (*cit).font.size();
1002 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
1007 FontTable * tmp = fonttable;
1009 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
1010 LyXFont::FONT_SIZE size = tmp->font.size();
1011 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
1021 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
1023 #ifdef DEVEL_VERSION
1024 /* a workaround to 'fix' some bugs in text-class */
1026 // This function is important. It should not work around bugs.
1027 // Let's find the bugs instead and fix them. (Asger)
1028 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
1029 " bad position " << pos << endl;
1037 /* > because last is the next unused position, and you can
1038 * use it if you want */
1039 else if (pos > size()) {
1040 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1041 return NextAfterFootnote()
1042 ->GetChar(pos - text.size() - 1);
1044 lyxerr << "ERROR (LyXParagraph::GetChar): "
1045 "position does not exist."
1046 << pos << " (" << static_cast<int>(pos)
1051 /* we should have a footnote environment */
1052 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1053 // Notice that LyX does request the
1054 // last char from time to time. (Asger)
1055 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1056 // "expected footnote." << endl;
1059 switch (next->footnotekind) {
1060 case LyXParagraph::FOOTNOTE:
1061 return LyXParagraph::META_FOOTNOTE;
1062 case LyXParagraph::MARGIN:
1063 return LyXParagraph::META_MARGIN;
1064 case LyXParagraph::FIG:
1065 case LyXParagraph::WIDE_FIG:
1066 return LyXParagraph::META_FIG;
1067 case LyXParagraph::TAB:
1068 case LyXParagraph::WIDE_TAB:
1069 return LyXParagraph::META_TAB;
1070 case LyXParagraph::ALGORITHM:
1071 return LyXParagraph::META_ALGORITHM;
1073 return '\0'; // to shut up gcc
1078 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1080 #ifdef DEVEL_VERSION
1081 /* a workaround to 'fix' some bugs in text-class */
1083 // This function is important. It should not work around bugs.
1084 // Let's find the bugs instead and fix them. (Asger)
1085 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
1086 " bad position " << pos << endl;
1094 /* > because last is the next unused position, and you can
1095 * use it if you want */
1096 else if (pos > size()) {
1097 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1098 return NextAfterFootnote()
1099 ->GetChar(pos - text.size() - 1);
1101 lyxerr << "ERROR (LyXParagraph::GetChar): "
1102 "position does not exist."
1103 << pos << " (" << static_cast<int>(pos)
1108 /* we should have a footnote environment */
1109 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1110 // Notice that LyX does request the
1111 // last char from time to time. (Asger)
1112 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1113 // "expected footnote." << endl;
1116 switch (next->footnotekind) {
1117 case LyXParagraph::FOOTNOTE:
1118 return LyXParagraph::META_FOOTNOTE;
1119 case LyXParagraph::MARGIN:
1120 return LyXParagraph::META_MARGIN;
1121 case LyXParagraph::FIG:
1122 case LyXParagraph::WIDE_FIG:
1123 return LyXParagraph::META_FIG;
1124 case LyXParagraph::TAB:
1125 case LyXParagraph::WIDE_TAB:
1126 return LyXParagraph::META_TAB;
1127 case LyXParagraph::ALGORITHM:
1128 return LyXParagraph::META_ALGORITHM;
1130 return '\0'; // to shut up gcc
1135 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1136 //Added 98/9/21 by REH
1137 // return an string of the current word, and the end of the word
1140 // the current word is defined as starting at the first character from
1141 // the immediate left of lastpospos which meets the definition of IsLetter(),
1142 // continuing to the last character to the right of this meeting
1146 // i just left this in from GetChar()
1148 #ifdef DEVEL_VERSION
1149 /* a workaround to 'fix' some bugs in text-class */
1151 // This function is important. It should not work around bugs.
1152 // Let's find the bugs instead and fix them. (Asger)
1153 lyxerr << "FATAL ERROR (LyXParagraph::GetWord):"
1154 " bad position " << lastpos << endl;
1164 //i think the devcode aborts before this, but why not be
1166 if (lastpos < 0) lastpos= 0;
1169 // move back until we have a letter
1171 //there's no real reason to have firstpos & lastpos as
1172 //separate variables as this is written, but maybe someon
1173 // will want to return firstpos in the future.
1175 //since someone might have typed a punctuation first
1176 int firstpos = lastpos;
1178 while ((firstpos >= 0) && !IsLetter(firstpos))
1181 // now find the beginning by looking for a nonletter
1183 while ((firstpos>= 0) && IsLetter(firstpos))
1186 // the above is now pointing to the preceeding non-letter
1190 // so copy characters into theword until we get a nonletter
1191 // note that this can easily exceed lastpos, wich means
1192 // that if used in the middle of a word, the whole word
1195 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1202 LyXParagraph::size_type LyXParagraph::Last() const
1204 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1205 return text.size() + NextAfterFootnote()->Last() + 1;
1206 /* the 1 is the symbol
1213 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1215 /* > because last is the next unused position, and you can
1216 * use it if you want */
1219 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1220 return NextAfterFootnote()
1221 ->ParFromPos(pos - text.size() - 1);
1223 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1224 "position does not exist." << endl;
1232 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1234 /* > because last is the next unused position, and you can
1235 * use it if you want */
1238 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1239 return NextAfterFootnote()
1240 ->PositionInParFromPos(pos - text.size() - 1);
1243 "ERROR (LyXParagraph::PositionInParFromPos): "
1244 "position does not exist." << endl;
1252 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1253 LyXFont const & font)
1255 /* > because last is the next unused position, and you can
1256 * use it if you want */
1258 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1259 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1262 lyxerr << "ERROR (LyXParagraph::SetFont): "
1263 "position does not exist." << endl;
1267 LyXFont patternfont(LyXFont::ALL_INHERIT);
1269 // First, reduce font against layout/label font
1270 // Update: The SetCharFont() routine in text2.C already reduces font, so
1271 // we don't need to do that here. (Asger)
1272 // No need to simplify this because it will disappear in a new kernel. (Asger)
1274 // Next search font table
1275 for(FontList::iterator it = fontlist.begin();
1276 it != fontlist.end(); ++it) {
1277 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1279 // we found a font entry. maybe we have to
1280 // split it and create a new one
1282 if ((*it).pos != (*it).pos_end) {
1283 // more than one character
1284 if (pos == (*it).pos) {
1285 // maybe we could enlarge
1286 // the left fonttable
1287 for(FontList::iterator fit = fontlist.begin();
1288 fit != fontlist.end(); ++fit) {
1289 if (pos - 1 >= (*fit).pos
1290 && pos - 1 <= (*fit).pos_end
1291 && (*fit).font == font) {
1299 // Add a new entry in the
1300 // fonttable for the position
1303 tmp.pos_end = (*it).pos_end;
1304 tmp.font = (*it).font;
1305 (*it).pos_end = pos;
1306 fontlist.push_back(tmp);
1307 } else if (pos == (*it).pos_end) {
1308 // Add a new entry in the
1309 // fonttable for the position
1311 tmp.pos = (*it).pos;
1312 tmp.pos_end = (*it).pos_end - 1;
1313 tmp.font = (*it).font;
1314 (*it).pos = (*it).pos_end;
1315 fontlist.push_back(tmp);
1317 // Add a new entry in the
1318 // fonttable for the position
1320 tmp.pos = (*it).pos;
1321 tmp.pos_end = pos - 1;
1322 tmp.font = (*it).font;
1323 fontlist.push_back(tmp);
1326 tmp.pos_end = (*it).pos_end;
1327 tmp.font = (*it).font;
1328 fontlist.push_back(tmp);
1331 (*it).pos_end = pos;
1339 // if we did not find a font entry, but if the font at hand
1340 // is the same as default, we just forget it
1341 if (font == patternfont) return;
1343 // ok, we did not find a font entry. But maybe there is exactly
1344 // the needed font entry one position left
1345 for(FontList::iterator it = fontlist.begin();
1346 it != fontlist.end(); ++it) {
1347 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1348 && (*it).font == font) {
1353 // Add a new entry in the
1354 // fonttable for the position
1358 tmp.font = patternfont;
1359 fontlist.push_back(tmp);
1361 // Next search font table
1365 FontTable * tmp = fonttable;
1366 while (tmp && !found) {
1367 if (pos >= tmp->pos && pos <= tmp->pos_end)
1374 /* if we did not find a font entry, but if the font at hand
1375 * is the same as default, we just forget it */
1376 if (font == patternfont)
1379 /* ok, we did not find a font entry. But maybe there is exactly
1380 * the needed font entry one position left */
1383 while (tmp2 && !found) {
1384 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1390 /* ok there is one. maybe it is exactly the needed font */
1391 if (tmp2->font == font) {
1392 /* put the position under the font */
1397 /* Add a new entry in the
1398 * fonttable for the position */
1399 tmp = new FontTable;
1402 tmp->font = patternfont;
1403 tmp->next = fonttable;
1406 /* we found a font entry. maybe we have to split it and create
1409 if (tmp->pos != tmp->pos_end) { /* more than one character */
1411 if (pos == tmp->pos) {
1412 /* maybe we could enlarge the left fonttable */
1416 while (tmp2 && !found) {
1417 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1423 /* Is there is one, and is it exactly the needed font? */
1424 if (found && tmp2->font == font) {
1425 /* put the position under the font */
1431 /* Add a new entry in the
1432 * fonttable for the position */
1433 tmp2 = new FontTable;
1434 tmp2->pos = pos + 1;
1435 tmp2->pos_end = tmp->pos_end;
1436 tmp2->font = tmp->font;
1438 tmp2->next = fonttable;
1441 else if (pos == tmp->pos_end) {
1442 /* Add a new entry in the
1443 * fonttable for the position */
1444 tmp2 = new FontTable;
1445 tmp2->pos = tmp->pos;
1446 tmp2->pos_end = tmp->pos_end - 1;
1447 tmp2->font = tmp->font;
1448 tmp->pos = tmp->pos_end;
1449 tmp2->next = fonttable;
1453 /* Add a new entry in the
1454 * fonttable for the position */
1455 tmp2 = new FontTable;
1456 tmp2->pos = tmp->pos;
1457 tmp2->pos_end = pos - 1;
1458 tmp2->font = tmp->font;
1459 tmp2->next = fonttable;
1462 tmp2 = new FontTable;
1463 tmp2->pos = pos + 1;
1464 tmp2->pos_end = tmp->pos_end;
1465 tmp2->font = tmp->font;
1466 tmp2->next = fonttable;
1479 /* this function is able to hide closed footnotes */
1480 LyXParagraph * LyXParagraph::Next()
1482 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1483 LyXParagraph * tmp = next;
1485 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1487 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1488 return tmp->Next(); /* there can be more than one
1489 footnote in a logical
1492 return next; /* this should never happen! */
1499 LyXParagraph * LyXParagraph::NextAfterFootnote()
1501 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1502 LyXParagraph * tmp = next;
1503 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1505 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1506 return tmp; /* there can be more than one footnote
1507 in a logical paragraph */
1509 return next; /* this should never happen! */
1516 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1518 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1519 LyXParagraph * tmp = next;
1520 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1522 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1523 return tmp; /* there can be more than one footnote
1524 in a logical paragraph */
1526 return next; /* this should never happen! */
1533 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1536 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1538 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1539 tmp = tmp->previous;
1540 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1541 return tmp; /* there can be more than one footnote
1542 in a logical paragraph */
1544 return previous; /* this should never happen! */
1551 LyXParagraph * LyXParagraph::LastPhysicalPar()
1553 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1556 LyXParagraph * tmp = this;
1558 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1559 tmp = tmp->NextAfterFootnote();
1566 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1570 LyXParagraph * tmppar = this;
1572 while (tmppar && (tmppar->IsDummy()
1573 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1574 tmppar = tmppar->previous;
1577 return this; /* this should never happen! */
1583 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1587 LyXParagraph const * tmppar = this;
1589 while (tmppar && (tmppar->IsDummy()
1590 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1591 tmppar = tmppar->previous;
1594 return this; /* this should never happen! */
1600 /* this function is able to hide closed footnotes */
1601 LyXParagraph * LyXParagraph::Previous()
1603 LyXParagraph * tmp = previous;
1608 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1609 tmp = tmp->previous;
1611 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1612 tmp = tmp->previous;
1613 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1614 return tmp->next->Previous();
1624 /* this function is able to hide closed footnotes */
1625 LyXParagraph const * LyXParagraph::Previous() const
1627 LyXParagraph * tmp = previous;
1632 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1633 tmp = tmp->previous;
1635 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1636 tmp = tmp->previous;
1637 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1638 return tmp->next->Previous();
1648 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1651 size_type i, pos_end, pos_first;
1652 /* create a new paragraph */
1653 LyXParagraph * par = ParFromPos(pos);
1654 LyXParagraph * firstpar = FirstPhysicalPar();
1656 LyXParagraph * tmp = new LyXParagraph(par);
1658 tmp->footnoteflag = footnoteflag;
1659 tmp->footnotekind = footnotekind;
1661 /* this is an idea for a more userfriendly layout handling, I will
1662 * see what the users say */
1664 /* layout stays the same with latex-environments */
1666 tmp->SetOnlyLayout(firstpar->layout);
1667 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1670 if (Last() > pos || !Last() || flag == 2) {
1671 tmp->SetOnlyLayout(firstpar->layout);
1672 tmp->align = firstpar->align;
1673 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1675 tmp->line_bottom = firstpar->line_bottom;
1676 firstpar->line_bottom = false;
1677 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1678 firstpar->pagebreak_bottom = false;
1679 tmp->added_space_bottom = firstpar->added_space_bottom;
1680 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1682 tmp->depth = firstpar->depth;
1683 tmp->noindent = firstpar->noindent;
1685 /* copy everything behind the break-position
1686 to the new paragraph
1689 while (ParFromPos(pos_first) != par)
1692 pos_end = pos_first + par->text.size() - 1;
1693 tmp->text.reserve(pos_end - pos);
1695 for (i = pos; i <= pos_end; i++) {
1696 par->CutIntoMinibuffer(i - pos_first);
1697 tmp->InsertFromMinibuffer(i - pos);
1700 for (i = pos_end; i >= pos; i--)
1701 par->Erase(i - pos_first);
1703 par->text.resize(par->text.size());
1706 /* just an idea of me */
1708 tmp->line_top = firstpar->line_top;
1709 tmp->pagebreak_top = firstpar->pagebreak_top;
1710 tmp->added_space_top = firstpar->added_space_top;
1711 tmp->bibkey = firstpar->bibkey;
1713 /* layout stays the same with latex-environments */
1715 firstpar->SetOnlyLayout(tmp->layout);
1716 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1717 firstpar->depth = tmp->depth;
1723 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1725 par = par->FirstPhysicalPar();
1726 footnoteflag = par->footnoteflag;
1727 footnotekind = par->footnotekind;
1729 layout = par->layout;
1730 align = par-> align;
1731 SetLabelWidthString(par->labelwidthstring);
1733 line_bottom = par->line_bottom;
1734 pagebreak_bottom = par->pagebreak_bottom;
1735 added_space_bottom = par->added_space_bottom;
1737 line_top = par->line_top;
1738 pagebreak_top = par->pagebreak_top;
1739 added_space_top = par->added_space_top;
1741 pextra_type = par->pextra_type;
1742 pextra_width = par->pextra_width;
1743 pextra_widthp = par->pextra_widthp;
1744 pextra_alignment = par->pextra_alignment;
1745 pextra_hfill = par->pextra_hfill;
1746 pextra_start_minipage = par->pextra_start_minipage;
1748 noindent = par->noindent;
1753 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1755 LyXParagraph * tmppar = this;
1758 && tmppar->previous->footnoteflag ==
1759 LyXParagraph::CLOSED_FOOTNOTE)
1760 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1761 tmppar = tmppar->previous;
1764 return this; /* this should never happen! */
1770 LyXParagraph * LyXParagraph::Clone() const
1772 /* create a new paragraph */
1773 LyXParagraph * result = new LyXParagraph;
1775 result->MakeSameLayout(this);
1777 /* this is because of the dummy layout of the paragraphs that
1779 result->layout = layout;
1781 /* table stuff -- begin*/
1783 result->table = table->Clone();
1786 /* table stuff -- end*/
1789 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1792 /* copy everything behind the break-position to the new paragraph */
1794 for (size_type i = 0; i < size(); i++) {
1795 CopyIntoMinibuffer(i);
1796 result->InsertFromMinibuffer(i);
1798 result->text.resize(result->text.size());
1803 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1805 par = par->FirstPhysicalPar();
1808 par->footnoteflag == footnoteflag &&
1809 par->footnotekind == footnotekind &&
1811 par->layout == layout &&
1813 par->align == align &&
1815 par->line_bottom == line_bottom &&
1816 par->pagebreak_bottom == pagebreak_bottom &&
1817 par->added_space_bottom == added_space_bottom &&
1819 par->line_top == line_top &&
1820 par->pagebreak_top == pagebreak_top &&
1821 par->added_space_top == added_space_top &&
1823 par->pextra_type == pextra_type &&
1824 par->pextra_width == pextra_width &&
1825 par->pextra_widthp == pextra_widthp &&
1826 par->pextra_alignment == pextra_alignment &&
1827 par->pextra_hfill == pextra_hfill &&
1828 par->pextra_start_minipage == pextra_start_minipage &&
1830 par->table == table && // what means: NO TABLE AT ALL
1832 par->noindent == noindent &&
1833 par->depth == depth);
1837 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1839 size_type i, pos_end, pos_first;
1841 /* create a new paragraph */
1842 LyXParagraph * par = ParFromPos(pos);
1844 LyXParagraph * tmp = new LyXParagraph(par);
1846 tmp->MakeSameLayout(par);
1849 /* copy everything behind the break-position to the new
1852 while (ParFromPos(pos_first) != par)
1854 pos_end = pos_first + par->text.size() - 1;
1855 /* make shure there is enough memory for the now larger
1856 paragraph. This is not neccessary, because
1857 InsertFromMinibuffer will enlarge the memory (it uses
1858 InsertChar of course). But doing it by hand
1859 is MUCH faster! (only one time, not thousend times!!) */
1860 tmp->text.reserve(pos_end - pos);
1862 for (i = pos; i <= pos_end; i++) {
1864 par->CutIntoMinibuffer(i - pos_first);
1865 tmp->InsertFromMinibuffer(i - pos);
1867 for (i = pos_end; i >= pos; i--)
1868 par->Erase(i - pos_first);
1870 par->text.resize(par->text.size());
1875 /* be carefull, this does not make any check at all */
1876 void LyXParagraph::PasteParagraph()
1878 /* copy the next paragraph to this one */
1879 LyXParagraph * the_next = Next();
1881 LyXParagraph * firstpar = FirstPhysicalPar();
1883 /* first the DTP-stuff */
1884 firstpar->line_bottom = the_next->line_bottom;
1885 firstpar->added_space_bottom = the_next->added_space_bottom;
1886 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1888 size_type pos_end = the_next->text.size() - 1;
1889 size_type pos_insert = Last();
1892 /* ok, now copy the paragraph */
1893 for (i = 0; i <= pos_end; i++) {
1894 the_next->CutIntoMinibuffer(i);
1895 InsertFromMinibuffer(pos_insert + i);
1898 /* delete the next paragraph */
1903 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1905 LyXParagraph * par = ParFromPos(pos);
1907 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1908 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1914 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1916 LyXParagraph * par = ParFromPos(pos);
1918 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1919 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1925 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1927 return FirstPhysicalPar()->layout;
1931 char LyXParagraph::GetDepth() const
1933 return FirstPhysicalPar()->depth;
1937 char LyXParagraph::GetAlign() const
1939 return FirstPhysicalPar()->align;
1943 string LyXParagraph::GetLabestring() const
1945 return FirstPhysicalPar()->labelstring;
1949 int LyXParagraph::GetFirstCounter(int i) const
1951 return FirstPhysicalPar()->counter_[i];
1955 /* the next two functions are for the manual labels */
1956 string LyXParagraph::GetLabelWidthString() const
1958 if (!FirstPhysicalPar()->labelwidthstring.empty())
1959 return FirstPhysicalPar()->labelwidthstring;
1961 return _("Senseless with this layout!");
1965 void LyXParagraph::SetLabelWidthString(string const & s)
1967 LyXParagraph * par = FirstPhysicalPar();
1969 par->labelwidthstring = s;
1973 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1975 LyXParagraph * par = FirstPhysicalPar();
1976 LyXParagraph * ppar = 0;
1977 LyXParagraph * npar = 0;
1979 par->layout = new_layout;
1980 /* table stuff -- begin*/
1983 /* table stuff -- end*/
1984 if (par->pextra_type == PEXTRA_NONE) {
1985 if (par->Previous()) {
1986 ppar = par->Previous()->FirstPhysicalPar();
1989 && (ppar->depth > par->depth))
1990 ppar = ppar->Previous()->FirstPhysicalPar();
1993 npar = par->Next()->NextAfterFootnote();
1996 && (npar->depth > par->depth))
1997 npar = npar->Next()->NextAfterFootnote();
1999 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2001 p1 = ppar->pextra_width,
2002 p2 = ppar->pextra_widthp;
2003 ppar->SetPExtraType(ppar->pextra_type,
2004 p1.c_str(), p2.c_str());
2006 if ((par->pextra_type == PEXTRA_NONE) &&
2007 npar && (npar->pextra_type != PEXTRA_NONE)) {
2009 p1 = npar->pextra_width,
2010 p2 = npar->pextra_widthp;
2011 npar->SetPExtraType(npar->pextra_type,
2012 p1.c_str(), p2.c_str());
2018 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
2021 * par = FirstPhysicalPar(),
2025 par->layout = new_layout;
2026 par->labelwidthstring.clear();
2027 par->align = LYX_ALIGN_LAYOUT;
2028 par->added_space_top = VSpace(VSpace::NONE);
2029 par->added_space_bottom = VSpace(VSpace::NONE);
2030 /* table stuff -- begin*/
2033 /* table stuff -- end*/
2034 if (par->pextra_type == PEXTRA_NONE) {
2035 if (par->Previous()) {
2036 ppar = par->Previous()->FirstPhysicalPar();
2039 && (ppar->depth > par->depth))
2040 ppar = ppar->Previous()->FirstPhysicalPar();
2043 npar = par->Next()->NextAfterFootnote();
2046 && (npar->depth > par->depth))
2047 npar = npar->Next()->NextAfterFootnote();
2049 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2051 p1 = ppar->pextra_width,
2052 p2 = ppar->pextra_widthp;
2053 ppar->SetPExtraType(ppar->pextra_type,
2054 p1.c_str(), p2.c_str());
2056 if ((par->pextra_type == PEXTRA_NONE) &&
2057 npar && (npar->pextra_type != PEXTRA_NONE)) {
2059 p1 = npar->pextra_width,
2060 p2 = npar->pextra_widthp;
2061 npar->SetPExtraType(npar->pextra_type,
2062 p1.c_str(), p2.c_str());
2068 /* if the layout of a paragraph contains a manual label, the beginning of the
2069 * main body is the beginning of the second word. This is what the par-
2070 * function returns. If the layout does not contain a label, the main
2071 * body always starts with position 0. This differentiation is necessary,
2072 * because there cannot be a newline or a blank <= the beginning of the
2073 * main body in TeX. */
2075 int LyXParagraph::BeginningOfMainBody() const
2077 if (FirstPhysicalPar() != this)
2080 // Unroll the first two cycles of the loop
2081 // and remember the previous character to
2082 // remove unnecessary GetChar() calls
2085 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2087 char previous_char, temp;
2089 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2090 // Yes, this ^ is supposed to be "= " not "== "
2093 && previous_char != ' '
2094 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2096 previous_char = temp;
2101 if (i == 0 && i == size() &&
2102 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2103 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2104 i++; /* the cursor should not jump
2105 * to the main body if there
2111 LyXParagraph * LyXParagraph::DepthHook(int deth)
2113 LyXParagraph * newpar = this;
2118 newpar = newpar->FirstPhysicalPar()->Previous();
2119 } while (newpar && newpar->GetDepth() > deth
2120 && newpar->footnoteflag == footnoteflag);
2123 if (Previous() || GetDepth())
2124 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2128 return newpar->FirstPhysicalPar();
2132 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2134 LyXParagraph const * newpar = this;
2139 newpar = newpar->FirstPhysicalPar()->Previous();
2140 } while (newpar && newpar->GetDepth() > deth
2141 && newpar->footnoteflag == footnoteflag);
2144 if (Previous() || GetDepth())
2145 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2149 return newpar->FirstPhysicalPar();
2153 int LyXParagraph::AutoDeleteInsets()
2157 for (InsetList::iterator it = insetlist.begin();
2158 it != insetlist.end(); ++it) {
2159 if ((*it).inset->AutoDelete()) {
2166 InsetTable * tmpi = insettable;
2167 InsetTable * tmpi2 = tmpi;
2173 if (tmpi2->inset->AutoDelete()) {
2178 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2179 "cannot auto-delete insets" << endl;
2186 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2189 InsetTable * tmp = 0;
2190 for (InsetList::iterator it = insetlist.begin();
2191 it != insetlist.end(); ++it) {
2192 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2203 InsetTable * tmpi = insettable;
2204 InsetTable * tmpi2 = 0;
2206 if (tmpi->pos >= pos) {
2207 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2214 return tmpi2->inset;
2222 /* returns -1 if inset not found */
2223 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2226 for (InsetList::iterator it = insetlist.begin();
2227 it != insetlist.end(); ++it) {
2228 if ((*it).inset == inset) {
2232 // Think about footnotes
2233 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2234 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2235 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2237 return size() + 1 + further;
2241 /* find the entry */
2242 InsetTable * tmpi = insettable;
2243 while (tmpi && tmpi->inset != inset) {
2246 if (tmpi && tmpi->inset)
2249 /* think about footnotes */
2250 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2251 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2253 NextAfterFootnote()->GetPositionOfInset(inset);
2255 return text.size() + 1 + further;
2263 void LyXParagraph::readSimpleWholeFile(FILE * myfile)
2267 if (!feof(myfile)) {
2271 InsertChar(text.size(), c);
2272 } while (!feof(myfile));
2278 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2279 string & foot, TexRow & foot_texrow,
2282 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2283 LyXParagraph * par = next;
2284 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2287 bool further_blank_line = false;
2289 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2291 if (start_of_appendix) {
2292 file += "\\appendix\n";
2296 if (tex_code_break_column && style.isCommand()){
2301 if (pagebreak_top) {
2302 file += "\\newpage";
2303 further_blank_line = true;
2305 if (added_space_top.kind() != VSpace::NONE) {
2306 file += added_space_top.asLatexCommand();
2307 further_blank_line = true;
2311 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2312 file += "\\vspace{-1\\parskip}";
2313 further_blank_line = true;
2316 if (further_blank_line){
2321 switch (style.latextype) {
2324 file += style.latexname();
2325 file += style.latexparam();
2327 case LATEX_ITEM_ENVIRONMENT:
2329 bibkey->Latex(file, false);
2333 case LATEX_LIST_ENVIRONMENT:
2340 bool need_par = SimpleTeXOnePar(file, texrow);
2342 // Spit out footnotes
2343 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2344 && par->footnoteflag != footnoteflag) {
2345 par = par->TeXFootnote(file, texrow,
2346 foot, foot_texrow, foot_count);
2347 par->SimpleTeXOnePar(file, texrow);
2351 // Make sure that \\par is done with the font of the last
2352 // character if this has another size as the default.
2353 // This is necessary because LaTeX (and LyX on the screen)
2354 // calculates the space between the baselines according
2355 // to this font. (Matthias)
2356 LyXFont font = getFont(Last()-1);
2358 if (style.resfont.size() != font.size()) {
2360 file += font.latexSize();
2364 } else if (textclasslist.Style(GetCurrentTextClass(),
2365 GetLayout()).isCommand()){
2366 if (style.resfont.size() != font.size()) {
2368 file += font.latexSize();
2372 } else if (style.resfont.size() != font.size()){
2373 file += "{\\" + font.latexSize() + " \\par}";
2376 switch (style.latextype) {
2377 case LATEX_ITEM_ENVIRONMENT:
2378 case LATEX_LIST_ENVIRONMENT:
2379 if (par && (depth < par->depth)) {
2384 case LATEX_ENVIRONMENT:
2385 // if its the last paragraph of the current environment
2386 // skip it otherwise fall through
2388 && (par->layout != layout
2389 || par->depth != depth
2390 || par->pextra_type != pextra_type))
2393 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2394 && footnotekind != LyXParagraph::FOOTNOTE
2395 && footnotekind != LyXParagraph::MARGIN
2399 // don't insert this if we would be adding it
2400 // before or after a table in a float. This
2401 // little trick is needed in order to allow
2402 // use of tables in \subfigures or \subtables.
2408 further_blank_line = false;
2410 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2411 further_blank_line = true;
2414 if (added_space_bottom.kind() != VSpace::NONE) {
2415 file += added_space_bottom.asLatexCommand();
2416 further_blank_line = true;
2419 if (pagebreak_bottom) {
2420 file += "\\newpage";
2421 further_blank_line = true;
2424 if (further_blank_line){
2429 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2430 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2435 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2440 // This one spits out the text of the paragraph
2441 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2443 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2446 return SimpleTeXOneTablePar(file, texrow);
2449 size_type main_body;
2451 bool return_value = false;
2453 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2456 /* maybe we have to create a optional argument */
2457 if (style.labeltype != LABEL_MANUAL)
2460 main_body = BeginningOfMainBody();
2462 if (main_body > 0) {
2464 basefont = getFont(-2); // Get label font
2466 basefont = getFont(-1); // Get layout font
2474 if (style.isCommand()) {
2477 } else if (align != LYX_ALIGN_LAYOUT) {
2480 return_value = true;
2484 // Which font is currently active?
2485 LyXFont running_font = basefont;
2486 // Do we have an open font change?
2487 bool open_font = false;
2489 texrow.start(this, 0);
2491 for (size_type i = 0; i < size(); ++i) {
2493 // First char in paragraph or after label?
2494 if (i == main_body && !IsDummy()) {
2495 if (main_body > 0) {
2497 column += running_font.latexWriteEndChanges(file, basefont);
2500 basefont = getFont(-1); // Now use the layout font
2501 running_font = basefont;
2505 if (style.isCommand()) {
2508 } else if (align != LYX_ALIGN_LAYOUT) {
2511 return_value = true;
2515 file += "\\noindent ";
2519 case LYX_ALIGN_NONE:
2520 case LYX_ALIGN_BLOCK:
2521 case LYX_ALIGN_LAYOUT:
2522 case LYX_ALIGN_SPECIAL: break;
2523 case LYX_ALIGN_LEFT:
2524 file += "\\raggedright ";
2527 case LYX_ALIGN_RIGHT:
2528 file += "\\raggedleft ";
2531 case LYX_ALIGN_CENTER:
2532 file += "\\centering ";
2540 // Fully instantiated font
2541 LyXFont font = getFont(i);
2543 // Spaces at end of font change are simulated to be
2544 // outside font change, i.e. we write "\textXX{text} "
2545 // rather than "\textXX{text }". (Asger)
2546 if (open_font && c == ' ' && i <= size() - 2
2547 && !getFont(i+1).equalExceptLatex(running_font)
2548 && !getFont(i+1).equalExceptLatex(font)) {
2549 font = getFont(i+1);
2551 // We end font definition before blanks
2552 if (!font.equalExceptLatex(running_font) && open_font) {
2553 column += running_font.latexWriteEndChanges(file,
2555 running_font = basefont;
2559 // Blanks are printed before start of fontswitch
2561 // Do not print the separation of the optional argument
2562 if (i != main_body - 1) {
2563 SimpleTeXBlanks(file, texrow, i,
2564 column, font, style);
2568 // Do we need to change font?
2569 if (!font.equalExceptLatex(running_font)
2570 && i != main_body-1) {
2571 column += font.latexWriteStartChanges(file, basefont);
2572 running_font = font;
2576 if (c == LyXParagraph::META_NEWLINE) {
2577 // newlines are handled differently here than
2578 // the default in SimpleTeXSpecialChars().
2579 if (!style.newline_allowed
2580 || font.latex() == LyXFont::ON) {
2584 column += running_font.latexWriteEndChanges(file, basefont);
2587 basefont = getFont(-1);
2588 running_font = basefont;
2589 if (font.family() ==
2590 LyXFont::TYPEWRITER_FAMILY) {
2596 texrow.start(this, i+1);
2599 SimpleTeXSpecialChars(file, texrow,
2600 font, running_font, basefont,
2601 open_font, style, i, column, c);
2605 // If we have an open font definition, we have to close it
2607 running_font.latexWriteEndChanges(file, basefont);
2610 /* needed if there is an optional argument but no contents */
2611 if (main_body > 0 && main_body == size()) {
2613 return_value = false;
2616 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2617 return return_value;
2621 // This one spits out the text of a table paragraph
2622 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2624 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2628 bool return_value = false;
2629 int current_cell_number = -1;
2631 LyXLayout const & style =
2632 textclasslist.Style(GetCurrentTextClass(), GetLayout());
2633 LyXFont basefont = getFont(-1); // Get layout font
2634 // Which font is currently active?
2635 LyXFont running_font = basefont;
2636 // Do we have an open font change?
2637 bool open_font = false;
2640 if (!IsDummy()) { // it is dummy if it is in a float!!!
2641 if (style.isCommand()) {
2644 } else if (align != LYX_ALIGN_LAYOUT) {
2647 return_value = true;
2650 file += "\\noindent ";
2654 case LYX_ALIGN_NONE:
2655 case LYX_ALIGN_BLOCK:
2656 case LYX_ALIGN_LAYOUT:
2657 case LYX_ALIGN_SPECIAL: break;
2658 case LYX_ALIGN_LEFT:
2659 file += "\\raggedright ";
2662 case LYX_ALIGN_RIGHT:
2663 file += "\\raggedleft ";
2666 case LYX_ALIGN_CENTER:
2667 file += "\\centering ";
2672 current_cell_number = -1;
2673 tmp = table->TexEndOfCell(file, current_cell_number);
2674 for (; tmp >0 ; --tmp)
2677 texrow.start(this, 0);
2679 for (size_type i = 0; i < size(); ++i) {
2681 if (table->IsContRow(current_cell_number+1)) {
2682 if (c == LyXParagraph::META_NEWLINE)
2683 current_cell_number++;
2688 // Fully instantiated font
2689 LyXFont font = getFont(i);
2691 // Spaces at end of font change are simulated to be outside font change.
2692 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2693 if (open_font && c == ' ' && i <= size() - 2
2694 && getFont(i+1) != running_font && getFont(i+1) != font) {
2695 font = getFont(i+1);
2698 // We end font definition before blanks
2699 if (font != running_font && open_font) {
2700 column += running_font.latexWriteEndChanges(file,
2702 running_font = basefont;
2705 // Blanks are printed before start of fontswitch
2707 SimpleTeXBlanks(file, texrow, i, column, font, style);
2709 // Do we need to change font?
2710 if (font != running_font) {
2711 column += font.latexWriteStartChanges(file, basefont);
2712 running_font = font;
2715 // Do we need to turn on LaTeX mode?
2716 if (font.latex() != running_font.latex()) {
2717 if (font.latex() == LyXFont::ON
2718 && style.needprotect) {
2719 file += "\\protect ";
2723 if (c == LyXParagraph::META_NEWLINE) {
2724 // special case for inside a table
2725 // different from default case in SimpleTeXSpecialChars()
2727 column += running_font.latexWriteEndChanges(file, basefont);
2730 basefont = getFont(-1);
2731 running_font = basefont;
2732 current_cell_number++;
2733 if (table->CellHasContRow(current_cell_number) >= 0) {
2734 TeXContTableRows(file, i+1,
2735 current_cell_number,
2738 // if this cell follow only ContRows till end don't
2739 // put the EndOfCell because it is put after the
2741 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2742 current_cell_number--;
2745 int tmp = table->TexEndOfCell(file,
2746 current_cell_number);
2749 } else if (tmp < 0) {
2755 texrow.start(this, i+1);
2757 SimpleTeXSpecialChars(file, texrow,
2758 font, running_font, basefont,
2759 open_font, style, i, column, c);
2763 // If we have an open font definition, we have to close it
2765 running_font.latexWriteEndChanges(file, basefont);
2767 current_cell_number++;
2768 tmp = table->TexEndOfCell(file, current_cell_number);
2769 for (; tmp > 0; --tmp)
2771 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2772 return return_value;
2776 // This one spits out the text off ContRows in tables
2777 bool LyXParagraph::TeXContTableRows(string & file,
2778 LyXParagraph::size_type i,
2779 int current_cell_number,
2780 int & column, TexRow & texrow)
2782 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2788 bool return_value = false;
2789 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2793 basefont = getFont(-1); // Get layout font
2794 // Which font is currently active?
2795 LyXFont running_font = basefont;
2796 // Do we have an open font change?
2797 bool open_font = false;
2799 size_type lastpos = i;
2800 int cell = table->CellHasContRow(current_cell_number);
2801 current_cell_number++;
2803 // first find the right position
2805 for (; (i < size()) && (current_cell_number<cell); ++i) {
2807 if (c == LyXParagraph::META_NEWLINE)
2808 current_cell_number++;
2812 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2816 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2820 for (; i < size() && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2824 // Fully instantiated font
2825 LyXFont font = getFont(i);
2827 // Spaces at end of font change are simulated to be outside font change.
2828 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2829 if (open_font && c == ' ' && i <= size() - 2
2830 && getFont(i + 1) != running_font
2831 && getFont(i + 1) != font) {
2832 font = getFont(i + 1);
2835 // We end font definition before blanks
2836 if (font != running_font && open_font) {
2837 column += running_font.latexWriteEndChanges(file, basefont);
2838 running_font = basefont;
2841 // Blanks are printed before start of fontswitch
2843 SimpleTeXBlanks(file, texrow, i,
2844 column, font, style);
2846 // Do we need to change font?
2847 if (font != running_font) {
2849 font.latexWriteStartChanges(file,
2851 running_font = font;
2854 // Do we need to turn on LaTeX mode?
2855 if (font.latex() != running_font.latex()) {
2856 if (font.latex() == LyXFont::ON
2857 && style.needprotect)
2859 file += "\\protect ";
2863 SimpleTeXSpecialChars(file, texrow, font,
2864 running_font, basefont,
2865 open_font, style, i, column, c);
2867 // If we have an open font definition, we have to close it
2869 running_font.latexWriteEndChanges(file, basefont);
2872 basefont = getFont(-1);
2873 running_font = basefont;
2874 cell = table->CellHasContRow(current_cell_number);
2876 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2877 return return_value;
2881 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2883 bool retval = false;
2885 case LyXParagraph::META_HFILL:
2886 sgml_string.clear();
2888 case LyXParagraph::META_PROTECTED_SEPARATOR:
2891 case LyXParagraph::META_NEWLINE:
2895 sgml_string = "&";
2898 sgml_string = "<";
2901 sgml_string = ">";
2904 sgml_string = "$";
2907 sgml_string = "#";
2910 sgml_string = "%";
2913 sgml_string = "[";
2916 sgml_string = "]";
2919 sgml_string = "{";
2922 sgml_string = "}";
2925 sgml_string = "˜";
2928 sgml_string = """;
2931 sgml_string = "\";
2937 case '\0': /* Ignore :-) */
2938 sgml_string.clear();
2947 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2948 int & desc_on, int depth)
2952 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2954 int current_cell_number = -1;
2955 LyXFont font1, font2;
2958 size_type main_body;
2959 string emph = "emphasis";
2960 bool emph_flag= false;
2961 int char_line_count= 0;
2963 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2965 if (style.labeltype != LABEL_MANUAL)
2968 main_body = BeginningOfMainBody();
2970 /* gets paragraph main font */
2972 font1 = style.labelfont;
2976 char_line_count = depth;
2977 addNewlineAndDepth(file, depth);
2978 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2979 file += "<INFORMALTABLE>";
2980 addNewlineAndDepth(file, ++depth);
2982 current_cell_number = -1;
2983 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2985 /* parsing main loop */
2986 for (size_type i = 0; i < size(); ++i) {
2988 if (table->IsContRow(current_cell_number+1)) {
2989 if (c == LyXParagraph::META_NEWLINE)
2990 current_cell_number++;
2995 // Fully instantiated font
2998 /* handle <emphasis> tag */
2999 if (font1.emph() != font2.emph() && i) {
3000 if (font2.emph() == LyXFont::ON) {
3001 file += "<emphasis>";
3003 } else if (emph_flag) {
3004 file += "</emphasis>";
3008 if (c == LyXParagraph::META_NEWLINE) {
3009 // we have only to control for emphasis open here!
3011 file += "</emphasis>";
3014 font1 = font2 = getFont(-1);
3015 current_cell_number++;
3016 if (table->CellHasContRow(current_cell_number) >= 0) {
3017 DocBookContTableRows(file, extra, desc_on, i+1,
3018 current_cell_number,
3021 // if this cell follow only ContRows till end don't
3022 // put the EndOfCell because it is put after the
3024 if (table->ShouldBeVeryLastCell(current_cell_number)) {
3025 current_cell_number--;
3028 tmp= table->DocBookEndOfCell(file, current_cell_number,
3033 } else if (c == LyXParagraph::META_INSET) {
3034 inset = GetInset(i);
3036 inset->DocBook(tmp_out);
3038 // This code needs some explanation:
3039 // Two insets are treated specially
3040 // label if it is the first element in a command paragraph
3042 // graphics inside tables or figure floats can't go on
3043 // title (the equivalente in latex for this case is caption
3044 // and title should come first
3047 if(desc_on != 3 || i != 0) {
3048 if(tmp_out[0] == '@') {
3050 extra += frontStrip(tmp_out, '@');
3052 file += frontStrip(tmp_out, '@');
3056 } else if (font2.latex() == LyXFont::ON) {
3057 // "TeX"-Mode on == > SGML-Mode on.
3063 if (linuxDocConvertChar(c, sgml_string)
3064 && !style.free_spacing) {
3065 // in freespacing mode, spaces are
3066 // non-breaking characters
3071 file += "</term><listitem><para>";
3077 file += sgml_string;
3083 /* needed if there is an optional argument but no contents */
3084 if (main_body > 0 && main_body == size()) {
3089 file += "</emphasis>";
3092 current_cell_number++;
3093 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3094 /* resets description flag correctly */
3097 /* <term> not closed... */
3101 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3102 file += "</INFORMALTABLE>";
3104 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3109 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3110 int & desc_on, LyXParagraph::size_type i,
3111 int current_cell_number, int &column)
3117 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3120 LyXFont font1, font2;
3123 size_type main_body;
3125 string emph= "emphasis";
3126 bool emph_flag= false;
3127 int char_line_count= 0;
3129 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3132 if (style.labeltype != LABEL_MANUAL)
3135 main_body = BeginningOfMainBody();
3137 /* gets paragraph main font */
3139 font1 = style.labelfont;
3144 cell = table->CellHasContRow(current_cell_number);
3145 current_cell_number++;
3147 // first find the right position
3149 for (; i < size() && current_cell_number < cell; ++i) {
3151 if (c == LyXParagraph::META_NEWLINE)
3152 current_cell_number++;
3156 // I don't know how to handle this so I comment it
3157 // for the moment (Jug)
3158 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3159 // file += " \\\\\n";
3162 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3167 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3171 // Fully instantiated font
3174 /* handle <emphasis> tag */
3175 if (font1.emph() != font2.emph() && i) {
3176 if (font2.emph() == LyXFont::ON) {
3177 file += "<emphasis>";
3179 } else if (emph_flag) {
3180 file += "</emphasis>";
3184 if (c == LyXParagraph::META_INSET) {
3185 inset = GetInset(i);
3187 inset->DocBook(tmp_out);
3189 // This code needs some explanation:
3190 // Two insets are treated specially
3191 // label if it is the first element in a command paragraph
3193 // graphics inside tables or figure floats can't go on
3194 // title (the equivalente in latex for this case is caption
3195 // and title should come first
3198 if(desc_on != 3 || i != 0) {
3199 if(tmp_out[0] == '@') {
3201 extra += frontStrip(tmp_out, '@');
3203 file += frontStrip(tmp_out, '@');
3207 } else if (font2.latex() == LyXFont::ON) {
3208 // "TeX"-Mode on == > SGML-Mode on.
3214 if (linuxDocConvertChar(c, sgml_string)
3215 && !style.free_spacing) {
3216 // in freespacing mode, spaces are
3217 // non-breaking characters
3222 file += "</term><listitem><para>";
3228 file += sgml_string;
3232 // we have only to control for emphasis open here!
3234 file += "</emphasis>";
3237 font1 = font2 = getFont(-1);
3238 cell = table->CellHasContRow(current_cell_number);
3240 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3243 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3244 LyXParagraph::size_type const i,
3245 int & column, LyXFont const & font,
3246 LyXLayout const & style)
3248 if (column > tex_code_break_column
3250 && GetChar(i - 1) != ' '
3252 // In LaTeX mode, we don't want to
3253 // break lines since some commands
3255 && ! (font.latex() == LyXFont::ON)
3256 // same in FreeSpacing mode
3257 && !style.free_spacing
3258 // In typewriter mode, we want to avoid
3259 // ! . ? : at the end of a line
3260 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3261 && (GetChar(i-1) == '.'
3262 || GetChar(i-1) == '?'
3263 || GetChar(i-1) == ':'
3264 || GetChar(i-1) == '!'))) {
3265 if (tex_code_break_column == 0) {
3266 // in batchmode we need LaTeX to still
3267 // see it as a space not as an extra '\n'
3273 texrow.start(this, i+1);
3275 } else if (font.latex() == LyXFont::OFF) {
3276 if (style.free_spacing) {
3285 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3287 LyXFont & running_font,
3290 LyXLayout const & style,
3291 LyXParagraph::size_type & i,
3292 int & column, char const c)
3294 // Two major modes: LaTeX or plain
3295 // Handle here those cases common to both modes
3296 // and then split to handle the two modes separately.
3298 case LyXParagraph::META_INSET: {
3299 Inset * inset = GetInset(i);
3301 int len = file.length();
3302 int tmp = inset->Latex(file, style.isCommand());
3307 column += file.length() - len;
3316 case LyXParagraph::META_NEWLINE:
3318 column += running_font.latexWriteEndChanges(file,
3322 basefont = getFont(-1);
3323 running_font = basefont;
3326 case LyXParagraph::META_HFILL:
3327 file += "\\hfill{}";
3332 // And now for the special cases within each mode
3333 // Are we in LaTeX mode?
3334 if (font.latex() == LyXFont::ON) {
3335 // at present we only have one option
3336 // but I'll leave it as a switch statement
3337 // so its simpler to extend. (ARRae)
3339 case LyXParagraph::META_PROTECTED_SEPARATOR:
3344 // make sure that we will not print
3345 // error generating chars to the tex
3346 // file. This test would not be needed
3347 // if it were done in the buffer
3355 // Plain mode (i.e. not LaTeX)
3357 case LyXParagraph::META_PROTECTED_SEPARATOR:
3362 file += "\\textbackslash{}";
3366 case '°': case '±': case '²': case '³':
3367 case '×': case '÷': case '¹': case 'ª':
3368 case 'º': case '¬': case 'µ':
3369 if (current_view->buffer()->params.inputenc == "latin1") {
3370 file += "\\ensuremath{";
3379 case '|': case '<': case '>':
3380 // In T1 encoding, these characters exist
3381 if (lyxrc->fontenc == "T1") {
3383 //... but we should avoid ligatures
3384 if ((c == '>' || c == '<')
3386 && GetChar(i+1) == c){
3387 file += "\\textcompwordmark{}";
3392 // Typewriter font also has them
3393 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3397 // Otherwise, we use what LaTeX
3401 file += "\\textless{}";
3405 file += "\\textgreater{}";
3409 file += "\\textbar{}";
3415 case '-': // "--" in Typewriter mode -> "-{}-"
3417 && GetChar(i + 1) == '-'
3418 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3427 file += "\\char`\\\"{}";
3432 if (current_view->buffer()->params.inputenc == "default") {
3433 file += "\\pounds{}";
3441 case '%': case '#': case '{':
3455 case '*': case '[': case ']':
3456 // avoid being mistaken for optional arguments
3464 /* blanks are printed before font switching */
3465 // Sure? I am not! (try nice-latex)
3466 // I am sure it's correct. LyX might be smarter
3467 // in the future, but for now, nothing wrong is
3472 /* idea for labels --- begin*/
3476 && font.family() != LyXFont::TYPEWRITER_FAMILY
3477 && GetChar(i + 1) == 'y'
3478 && GetChar(i + 2) == 'X') {
3486 && font.family() != LyXFont::TYPEWRITER_FAMILY
3487 && GetChar(i + 1) == 'e'
3488 && GetChar(i + 2) == 'X') {
3493 /* check for LaTeX2e */
3496 && font.family() != LyXFont::TYPEWRITER_FAMILY
3497 && GetChar(i + 1) == 'a'
3498 && GetChar(i + 2) == 'T'
3499 && GetChar(i + 3) == 'e'
3500 && GetChar(i + 4) == 'X'
3501 && GetChar(i + 5) == '2'
3502 && GetChar(i + 6) == 'e') {
3503 file += "\\LaTeXe{}";
3507 /* check for LaTeX */
3510 && font.family() != LyXFont::TYPEWRITER_FAMILY
3511 && GetChar(i + 1) == 'a'
3512 && GetChar(i + 2) == 'T'
3513 && GetChar(i + 3) == 'e'
3514 && GetChar(i + 4) == 'X') {
3515 file += "\\LaTeX{}";
3518 /* idea for labels --- end*/
3519 } else if (c != '\0') {
3529 bool LyXParagraph::RoffContTableRows(FILE * fp,
3530 LyXParagraph::size_type i,
3536 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3542 string fname2 = TmpFileName(string(), "RAT2");
3544 int cell = table->CellHasContRow(actcell);
3547 // first find the right position
3549 for (; i < size() && actcell < cell; ++i) {
3551 if (c == LyXParagraph::META_NEWLINE)
3556 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3559 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3561 font2 = GetFontSettings(i);
3562 if (font1.latex() != font2.latex()) {
3563 if (font2.latex() != LyXFont::OFF)
3568 case LyXParagraph::META_INSET:
3569 if ((inset = GetInset(i))) {
3570 if (!(fp2= fopen(fname2.c_str(), "w+"))) {
3571 WriteAlert(_("LYX_ERROR:"),
3572 _("Cannot open temporary file:"),
3576 inset->Latex(fp2,-1);
3581 fprintf(fp, "\\\\");
3589 case LyXParagraph::META_NEWLINE:
3591 case LyXParagraph::META_HFILL:
3593 case LyXParagraph::META_PROTECTED_SEPARATOR:
3596 fprintf(fp, "\\\\");
3600 fprintf(fp, "%c", c);
3602 lyxerr.debug() << "RoffAsciiTable: NULL char in structure." << endl;
3606 cell = table->CellHasContRow(actcell);
3612 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3613 string & foot, TexRow & foot_texrow,
3616 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3617 LyXParagraph * par = this;
3619 while (par && par->depth == depth) {
3621 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3622 if (textclasslist.Style(GetCurrentTextClass(),
3623 par->layout).isEnvironment()
3624 || par->pextra_type != PEXTRA_NONE)
3626 par = par->TeXEnvironment(file, texrow,
3630 par = par->TeXOnePar(file, texrow,
3635 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3641 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3642 string & foot, TexRow & foot_texrow,
3645 bool eindent_open = false;
3646 bool foot_this_level = false;
3647 // flags when footnotetext should be appended to file.
3648 static bool minipage_open = false;
3649 static int minipage_open_depth = 0;
3650 char par_sep = current_view->buffer()->params.paragraph_separation;
3652 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3654 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3656 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3659 if (pextra_type == PEXTRA_INDENT) {
3660 if (!pextra_width.empty()) {
3661 file += "\\begin{LyXParagraphIndent}{"
3662 + pextra_width + "}\n";
3664 //float ib = atof(pextra_widthp.c_str())/100;
3665 // string can't handle floats at present (971109)
3666 // so I'll do a conversion by hand knowing that
3667 // the limits are 0.0 to 1.0. ARRae.
3668 file += "\\begin{LyXParagraphIndent}{";
3669 switch (pextra_widthp.length()) {
3675 file += pextra_widthp;
3679 file += pextra_widthp;
3681 file += "\\columnwidth}\n";
3684 eindent_open = true;
3686 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3687 if (pextra_hfill && Previous() &&
3688 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3689 file += "\\hfill{}\n";
3692 if (par_sep == BufferParams::PARSEP_INDENT) {
3693 file += "{\\setlength\\parindent{0pt}\n";
3696 file += "\\begin{minipage}";
3697 switch(pextra_alignment) {
3698 case MINIPAGE_ALIGN_TOP:
3701 case MINIPAGE_ALIGN_MIDDLE:
3704 case MINIPAGE_ALIGN_BOTTOM:
3708 if (!pextra_width.empty()) {
3710 file += pextra_width + "}\n";
3712 //float ib = atof(par->pextra_width.c_str())/100;
3713 // string can't handle floats at present
3714 // so I'll do a conversion by hand knowing that
3715 // the limits are 0.0 to 1.0. ARRae.
3717 switch (pextra_widthp.length()) {
3723 file += pextra_widthp;
3727 file += pextra_widthp;
3729 file += "\\columnwidth}\n";
3732 if (par_sep == BufferParams::PARSEP_INDENT) {
3733 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3736 minipage_open = true;
3737 minipage_open_depth = depth;
3740 #ifdef WITH_WARNINGS
3741 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3742 //I disabled it because it breaks when lists span on several
3745 if (style.isEnvironment()){
3746 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3747 #ifdef FANCY_FOOTNOTE_CODE
3748 if (foot_count < 0) {
3749 // flag that footnote[mark][text] should be
3750 // used for any footnotes from now on
3752 foot_this_level = true;
3755 file += "\\begin{" + style.latexname() + "}{"
3756 + labelwidthstring + "}\n";
3757 } else if (style.labeltype == LABEL_BIBLIO) {
3759 file += "\\begin{" + style.latexname() + "}{"
3760 + bibitemWidthest() + "}\n";
3761 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3762 #ifdef FANCY_FOOTNOTE_CODE
3763 if (foot_count < 0) {
3764 // flag that footnote[mark][text] should be
3765 // used for any footnotes from now on
3767 foot_this_level = true;
3770 file += "\\begin{" + style.latexname() + '}'
3771 + style.latexparam() + '\n';
3773 file += "\\begin{" + style.latexname() + '}'
3774 + style.latexparam() + '\n';
3777 LyXParagraph * par = this;
3779 par = par->TeXOnePar(file, texrow,
3780 foot, foot_texrow, foot_count);
3782 if (minipage_open && par && !style.isEnvironment() &&
3783 (par->pextra_type == PEXTRA_MINIPAGE) &&
3784 par->pextra_start_minipage) {
3785 file += "\\end{minipage}\n";
3787 if (par_sep == BufferParams::PARSEP_INDENT) {
3791 minipage_open = false;
3793 if (par && par->depth > depth) {
3794 if (textclasslist.Style(GetCurrentTextClass(),
3795 par->layout).isParagraph()
3797 && !suffixIs(file, "\n\n")) {
3798 // There should be at least one '\n' already
3799 // but we need there to be two for Standard
3800 // paragraphs that are depth-increment'ed to be
3801 // output correctly. However, tables can also be
3802 // paragraphs so don't adjust them. ARRae
3806 par = par->TeXDeeper(file, texrow,
3807 foot, foot_texrow, foot_count);
3809 if (par && par->layout == layout && par->depth == depth &&
3810 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3811 if (par->pextra_hfill && par->Previous() &&
3812 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3813 file += "\\hfill{}\n";
3816 if (par_sep == BufferParams::PARSEP_INDENT) {
3817 file += "{\\setlength\\parindent{0pt}\n";
3820 file += "\\begin{minipage}";
3821 switch(par->pextra_alignment) {
3822 case MINIPAGE_ALIGN_TOP:
3825 case MINIPAGE_ALIGN_MIDDLE:
3828 case MINIPAGE_ALIGN_BOTTOM:
3832 if (!par->pextra_width.empty()) {
3834 file += par->pextra_width;
3837 //float ib = atof(par->pextra_widthp.c_str())/100;
3838 // string can't handle floats at present
3839 // so I'll do a conversion by hand knowing that
3840 // the limits are 0.0 to 1.0. ARRae.
3842 switch (par->pextra_widthp.length()) {
3848 file += par->pextra_widthp;
3852 file += par->pextra_widthp;
3854 file += "\\columnwidth}\n";
3857 if (par_sep == BufferParams::PARSEP_INDENT) {
3858 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3861 minipage_open = true;
3862 minipage_open_depth = par->depth;
3865 && par->layout == layout
3866 && par->depth == depth
3867 && par->pextra_type == pextra_type);
3869 if (style.isEnvironment()) {
3870 file += "\\end{" + style.latexname() + '}';
3871 // maybe this should go after the minipage closes?
3872 if (foot_this_level) {
3873 if (foot_count >= 1) {
3874 if (foot_count > 1) {
3875 file += "\\addtocounter{footnote}{-";
3876 file += tostr(foot_count - 1);
3880 texrow += foot_texrow;
3882 foot_texrow.reset();
3887 if (minipage_open && (minipage_open_depth == depth) &&
3888 (!par || par->pextra_start_minipage ||
3889 par->pextra_type != PEXTRA_MINIPAGE)) {
3890 file += "\\end{minipage}\n";
3892 if (par_sep == BufferParams::PARSEP_INDENT) {
3896 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3897 file += "\\medskip\n\n";
3901 minipage_open = false;
3904 file += "\\end{LyXParagraphIndent}\n";
3907 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3908 && par->pextra_hfill)) {
3912 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3913 return par; // ale970302
3917 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3918 string & foot, TexRow & foot_texrow,
3921 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3922 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3923 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3924 "No footnote!" << endl;
3926 LyXParagraph * par = this;
3927 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3928 previous->GetLayout());
3930 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3931 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3932 "Float other than footnote in command"
3933 " with moving argument is illegal" << endl;
3936 if (footnotekind != LyXParagraph::FOOTNOTE
3937 && footnotekind != LyXParagraph::MARGIN
3939 && !suffixIs(file, '\n')) {
3940 // we need to ensure that real floats like tables and figures
3941 // have their \begin{} on a new line otherwise we can get
3942 // incorrect results when using the endfloat.sty package
3943 // especially if two floats follow one another. ARRae 981022
3944 // NOTE: if the file is length 0 it must have just been
3945 // written out so we assume it ended with a '\n'
3950 BufferParams * params = ¤t_view->buffer()->params;
3951 bool footer_in_body = true;
3952 switch (footnotekind) {
3953 case LyXParagraph::FOOTNOTE:
3954 if (style.intitle) {
3955 file += "\\thanks{\n";
3956 footer_in_body = false;
3958 if (foot_count == -1) {
3959 // we're at depth 0 so we can use:
3960 file += "\\footnote{%\n";
3961 footer_in_body = false;
3963 file += "\\footnotemark{}%\n";
3965 // we only need this when there are
3966 // multiple footnotes
3967 foot += "\\stepcounter{footnote}";
3969 foot += "\\footnotetext{%\n";
3970 foot_texrow.start(this, 0);
3971 foot_texrow.newline();
3976 case LyXParagraph::MARGIN:
3977 file += "\\marginpar{\n";
3979 case LyXParagraph::FIG:
3980 if (pextra_type == PEXTRA_FLOATFLT
3981 && (!pextra_width.empty()
3982 || !pextra_widthp.empty())) {
3984 if (!pextra_width.empty())
3985 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3986 pextra_width.c_str());
3988 sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
3989 atoi(pextra_widthp.c_str())/100.0);
3992 file += "\\begin{figure}";
3993 if (!params->float_placement.empty()) {
3995 file += params->float_placement;
4002 case LyXParagraph::TAB:
4003 file += "\\begin{table}";
4004 if (!params->float_placement.empty()) {
4006 file += params->float_placement;
4012 case LyXParagraph::WIDE_FIG:
4013 file += "\\begin{figure*}";
4014 if (!params->float_placement.empty()) {
4016 file += params->float_placement;
4022 case LyXParagraph::WIDE_TAB:
4023 file += "\\begin{table*}";
4024 if (!params->float_placement.empty()) {
4026 file += params->float_placement;
4032 case LyXParagraph::ALGORITHM:
4033 file += "\\begin{algorithm}\n";
4038 if (footnotekind != LyXParagraph::FOOTNOTE
4039 || !footer_in_body) {
4040 // Process text for all floats except footnotes in body
4042 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
4045 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4047 if (style.isEnvironment()
4048 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4049 // Allows the use of minipages within float environments.
4050 // Shouldn't be circular because we don't support
4051 // footnotes inside floats (yet). ARRae
4052 par = par->TeXEnvironment(file, texrow,
4056 par = par->TeXOnePar(file, texrow,
4061 if (par && !par->IsDummy() && par->depth > depth) {
4062 par = par->TeXDeeper(file, texrow,
4066 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4068 // process footnotes > depth 0 or in environments separately
4069 // NOTE: Currently don't support footnotes within footnotes
4070 // even though that is possible using the \footnotemark
4072 TexRow dummy_texrow;
4073 int dummy_count = 0;
4075 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
4078 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4080 if (style.isEnvironment()
4081 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4082 // Allows the use of minipages within float environments.
4083 // Shouldn't be circular because we don't support
4084 // footnotes inside floats (yet). ARRae
4085 par = par->TeXEnvironment(foot, foot_texrow,
4086 dummy, dummy_texrow,
4089 par = par->TeXOnePar(foot, foot_texrow,
4090 dummy, dummy_texrow,
4094 if (par && !par->IsDummy() && par->depth > depth) {
4095 par = par->TeXDeeper(foot, foot_texrow,
4096 dummy, dummy_texrow,
4099 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4101 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4102 "Footnote in a Footnote -- not supported"
4107 switch (footnotekind) {
4108 case LyXParagraph::FOOTNOTE:
4109 if (footer_in_body) {
4110 // This helps tell which of the multiple
4111 // footnotetexts an error was in.
4113 foot_texrow.newline();
4118 case LyXParagraph::MARGIN:
4121 case LyXParagraph::FIG:
4122 if (pextra_type == PEXTRA_FLOATFLT
4123 && (!pextra_width.empty()
4124 || !pextra_widthp.empty()))
4125 file += "\\end{floatingfigure}";
4127 file += "\\end{figure}";
4129 case LyXParagraph::TAB:
4130 file += "\\end{table}";
4132 case LyXParagraph::WIDE_FIG:
4133 file += "\\end{figure*}";
4135 case LyXParagraph::WIDE_TAB:
4136 file += "\\end{table*}";
4138 case LyXParagraph::ALGORITHM:
4139 file += "\\end{algorithm}";
4143 if (footnotekind != LyXParagraph::FOOTNOTE
4144 && footnotekind != LyXParagraph::MARGIN) {
4145 // we need to ensure that real floats like tables and figures
4146 // have their \end{} on a line of their own otherwise we can
4147 // get incorrect results when using the endfloat.sty package.
4152 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4157 void LyXParagraph::SetPExtraType(int type, char const * width,
4158 char const * widthp)
4161 pextra_width = width;
4162 pextra_widthp = widthp;
4164 if (textclasslist.Style(GetCurrentTextClass(),
4165 layout).isEnvironment()) {
4170 while (par && (par->layout == layout) && (par->depth == depth)) {
4172 par = par->Previous();
4174 par = par->FirstPhysicalPar();
4175 while (par && par->depth > depth) {
4176 par = par->Previous();
4178 par = par->FirstPhysicalPar();
4182 while (par && (par->layout == layout) && (par->depth == depth)) {
4183 par->pextra_type = type;
4184 par->pextra_width = width;
4185 par->pextra_widthp = widthp;
4186 par = par->NextAfterFootnote();
4187 if (par && (par->depth > depth))
4188 par->SetPExtraType(type, width, widthp);
4189 while (par && ((par->depth > depth) || par->IsDummy()))
4190 par = par->NextAfterFootnote();
4196 void LyXParagraph::UnsetPExtraType()
4198 if (pextra_type == PEXTRA_NONE)
4201 pextra_type = PEXTRA_NONE;
4202 pextra_width.clear();
4203 pextra_widthp.clear();
4205 if (textclasslist.Style(GetCurrentTextClass(),
4206 layout).isEnvironment()) {
4211 while (par && (par->layout == layout) && (par->depth == depth)) {
4213 par = par->Previous();
4215 par = par->FirstPhysicalPar();
4216 while (par && par->depth > depth) {
4217 par = par->Previous();
4219 par = par->FirstPhysicalPar();
4223 while (par && (par->layout == layout) && (par->depth == depth)) {
4224 par->pextra_type = PEXTRA_NONE;
4225 par->pextra_width.clear();
4226 par->pextra_widthp.clear();
4227 par = par->NextAfterFootnote();
4228 if (par && (par->depth > depth))
4229 par->UnsetPExtraType();
4230 while (par && ((par->depth > depth) || par->IsDummy()))
4231 par = par->NextAfterFootnote();
4237 bool LyXParagraph::IsHfill(size_type pos) const
4239 return IsHfillChar(GetChar(pos));
4243 bool LyXParagraph::IsInset(size_type pos) const
4245 return IsInsetChar(GetChar(pos));
4249 bool LyXParagraph::IsFloat(size_type pos) const
4251 return IsFloatChar(GetChar(pos));
4255 bool LyXParagraph::IsNewline(size_type pos) const
4259 tmp = IsNewlineChar(GetChar(pos));
4264 bool LyXParagraph::IsSeparator(size_type pos) const
4266 return IsSeparatorChar(GetChar(pos));
4270 bool LyXParagraph::IsLineSeparator(size_type pos) const
4272 return IsLineSeparatorChar(GetChar(pos));
4276 bool LyXParagraph::IsKomma(size_type pos) const
4278 return IsKommaChar(GetChar(pos));
4282 /// Used by the spellchecker
4283 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4285 unsigned char c = GetChar(pos);
4286 if (IsLetterChar(c))
4288 // '\0' is not a letter, allthough every string contains "" (below)
4291 // We want to pass the ' and escape chars to ispell
4292 string extra = lyxrc->isp_esc_chars + '\'';
4296 return contains(extra, ch);
4300 bool LyXParagraph::IsWord(size_type pos ) const
4302 return IsWordChar( GetChar(pos) ) ;