1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
14 #pragma implementation "lyxparagraph.h"
21 #include "lyxparagraph.h"
22 #include "support/textutils.h"
25 #include "tex-strings.h"
26 #include "bufferparams.h"
27 #include "support/FileInfo.h"
29 #include "LaTeXFeatures.h"
30 #include "insets/insetinclude.h"
31 #include "support/filetools.h"
32 #include "lyx_gui_misc.h"
36 extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
37 extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
38 int tex_code_break_column = 72; // needs non-zero initialization. set later.
39 // this is a bad idea, but how can LyXParagraph find its buffer to get
40 // parameters? (JMarc)
41 extern BufferView * current_view;
46 extern string bibitemWidthest();
48 /* this is a minibuffer */
49 static char minibuffer_char;
50 static LyXFont minibuffer_font;
51 static Inset * minibuffer_inset;
54 // Initialization of the counter for the paragraph id's,
55 // declared in lyxparagraph.h
56 unsigned int LyXParagraph::paragraph_id = 0;
59 LyXParagraph::LyXParagraph()
61 text.reserve(500); // is this number too big?
63 for (int i = 0; i < 10; ++i) setCounter(i , 0);
73 footnoteflag = LyXParagraph::NO_FOOTNOTE;
75 align = LYX_ALIGN_BLOCK;
77 /* table stuff -- begin*/
79 /* table stuff -- end*/
81 bibkey = 0; // ale970302
86 /* this konstruktor inserts the new paragraph in a list */
87 LyXParagraph::LyXParagraph(LyXParagraph * par)
90 par->text.resize(par->text.size());
92 for (int i = 0; i < 10; ++i) setCounter(i, 0);
98 next->previous = this;
100 previous->next = this;
105 footnoteflag = LyXParagraph::NO_FOOTNOTE;
106 footnotekind = LyXParagraph::FOOTNOTE;
108 /* table stuff -- begin*/
110 /* table stuff -- end*/
111 id_ = paragraph_id++;
113 bibkey = 0; // ale970302
119 void LyXParagraph::writeFile(ostream & os, BufferParams & params,
120 char footflag, char dth)
122 LyXFont font1, font2;
128 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
130 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
132 /* The beginning or the end of a footnote environment? */
133 if (footflag != footnoteflag) {
134 footflag = footnoteflag;
136 os << "\n\\begin_float "
137 << string_footnotekinds[footnotekind]
141 os << "\n\\end_float ";
145 /* The beginning or end of a deeper (i.e. nested) area? */
148 while (depth > dth) {
149 os << "\n\\begin_deeper ";
154 while (depth < dth) {
155 os << "\n\\end_deeper ";
161 /* First write the layout */
163 << textclasslist.NameOfLayout(params.textclass, layout)
166 /* maybe some vertical spaces */
167 if (added_space_top.kind() != VSpace::NONE)
168 os << "\\added_space_top "
169 << added_space_top.asLyXCommand() << " ";
170 if (added_space_bottom.kind() != VSpace::NONE)
171 os << "\\added_space_bottom "
172 << added_space_bottom.asLyXCommand() << " ";
174 /* The labelwidth string used in lists */
175 if (!labelwidthstring.empty())
176 os << "\\labelwidthstring "
177 << labelwidthstring << '\n';
179 /* Lines above or below? */
183 os << "\\line_bottom ";
185 /* Pagebreaks above or below? */
187 os << "\\pagebreak_top ";
188 if (pagebreak_bottom)
189 os << "\\pagebreak_bottom ";
191 /* Start of appendix? */
192 if (start_of_appendix)
193 os << "\\start_of_appendix ";
200 if (align != LYX_ALIGN_LAYOUT) {
202 case LYX_ALIGN_LEFT: h = 1; break;
203 case LYX_ALIGN_RIGHT: h = 2; break;
204 case LYX_ALIGN_CENTER: h = 3; break;
205 default: h = 0; break;
207 os << "\\align " << string_align[h] << " ";
209 if (pextra_type != PEXTRA_NONE) {
210 os << "\\pextra_type " << pextra_type;
211 if (pextra_type == PEXTRA_MINIPAGE) {
212 os << " \\pextra_alignment "
215 os << " \\pextra_hfill "
217 if (pextra_start_minipage)
218 os << " \\pextra_start_minipage "
219 << pextra_start_minipage;
221 if (!pextra_width.empty()) {
222 os << " \\pextra_width "
223 << VSpace(pextra_width).asLyXCommand();
224 } else if (!pextra_widthp.empty()) {
225 os << " \\pextra_widthp "
232 /* Dummy layout. This means that a footnote ended */
233 os << "\n\\end_float ";
234 footflag = LyXParagraph::NO_FOOTNOTE;
237 /* It might be a table */
239 os << "\\LyXTable\n";
247 font1 = LyXFont(LyXFont::ALL_INHERIT);
250 for (size_type i = 0; i < size(); i++) {
256 // Write font changes
257 font2 = GetFontSettings(i);
258 if (font2 != font1) {
259 font2.lyxWriteChanges(font1, os);
269 if (inset->DirectWrite()) {
270 // international char, let it write
271 // code directly so it's shorter in
275 os << "\n\\begin_inset ";
277 os << "\n\\end_inset \n\n";
282 os << "\n\\newline \n";
286 os << "\n\\hfill \n";
289 case META_PROTECTED_SEPARATOR:
290 os << "\n\\protected_separator \n";
294 os << "\n\\backslash \n";
298 if (i + 1 < size() && GetChar(i + 1) == ' ') {
305 if ((column > 70 && c == ' ')
310 // this check is to amend a bug. LyX sometimes
311 // inserts '\0' this could cause problems.
315 lyxerr << "ERROR (LyXParagraph::writeFile):"
316 " NULL char in structure." << endl;
322 // now write the next paragraph
324 next->writeFile(os, params, footflag, dth);
328 void LyXParagraph::validate(LaTeXFeatures & features)
330 // this will be useful later
331 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
335 if (line_top || line_bottom)
336 features.lyxline = true;
339 features.layout[GetLayout()] = true;
342 for (FontList::const_iterator cit = fontlist.begin();
343 cit != fontlist.end(); ++cit) {
344 if ((*cit).font.noun() == LyXFont::ON) {
345 lyxerr[Debug::LATEX] << "font.noun: "
346 << (*cit).font.noun()
348 features.noun = true;
349 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
350 << (*cit).font.stateText()
353 switch ((*cit).font.color()) {
355 case LyXFont::INHERIT_COLOR:
356 case LyXFont::IGNORE_COLOR: break;
358 features.color = true;
359 lyxerr[Debug::LATEX] << "Color enabled. Font: "
360 << (*cit).font.stateText()
366 FontTable * tmpfonttable = fonttable;
367 while (tmpfonttable) {
368 if (tmpfonttable->font.noun() == LyXFont::ON) {
369 lyxerr[Debug::LATEX] << "font.noun: "
370 << tmpfonttable->font.noun()
372 features.noun = true;
373 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
374 << tmpfonttable->font.stateText()
377 switch (tmpfonttable->font.color()) {
379 case LyXFont::INHERIT_COLOR:
380 case LyXFont::IGNORE_COLOR:
383 features.color = true;
384 lyxerr[Debug::LATEX] << "Color enabled. Font: "
385 << tmpfonttable->font.stateText()
388 tmpfonttable = tmpfonttable->next;
392 for (InsetList::const_iterator cit = insetlist.begin();
393 cit != insetlist.end(); ++cit) {
394 (*cit).inset->Validate(features);
398 InsetTable * tmpinsettable = insettable;
399 while (tmpinsettable) {
400 if (tmpinsettable->inset) {
401 tmpinsettable->inset->Validate(features);
403 tmpinsettable = tmpinsettable->next;
406 if (table && table->IsLongTable())
407 features.longtable = true;
408 if (pextra_type == PEXTRA_INDENT)
409 features.LyXParagraphIndent = true;
410 if (pextra_type == PEXTRA_FLOATFLT)
411 features.floatflt = true;
412 if (layout.needprotect
413 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
414 features.NeedLyXFootnoteCode = true;
415 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
416 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
417 features.NeedLyXMinipageIndent = true;
418 if (table && table->NeedRotating())
419 features.rotating = true;
420 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
421 features.algorithm = true;
425 /* first few functions needed for cut and paste and paragraph breaking */
426 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const
428 minibuffer_char = GetChar(pos);
429 minibuffer_font = GetFontSettings(pos);
430 minibuffer_inset = 0;
431 if (minibuffer_char == LyXParagraph::META_INSET) {
433 minibuffer_inset = GetInset(pos)->Clone();
435 minibuffer_inset = 0;
436 minibuffer_char = ' ';
437 // This reflects what GetInset() does (ARRae)
442 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
444 minibuffer_char = GetChar(pos);
445 minibuffer_font = GetFontSettings(pos);
446 minibuffer_inset = 0;
447 if (minibuffer_char == LyXParagraph::META_INSET) {
449 minibuffer_inset = GetInset(pos);
450 // This is a little hack since I want exactly
451 // the inset, not just a clone. Otherwise
452 // the inset would be deleted when calling Erase(pos)
454 for (InsetList::iterator it = insetlist.begin();
455 it != insetlist.end(); ++it) {
456 if ((*it).pos == pos) {
463 InsetTable * tmpi = insettable;
464 while (tmpi && tmpi->pos != pos) {
467 if (tmpi) { /* This should always be true */
472 minibuffer_inset = 0;
473 minibuffer_char = ' ';
474 // This reflects what GetInset() does (ARRae)
479 /* Erase(pos); now the caller is responsible for that*/
483 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
485 InsertChar(pos, minibuffer_char);
486 SetFont(pos, minibuffer_font);
487 if (minibuffer_char == LyXParagraph::META_INSET)
488 InsertInset(pos, minibuffer_inset);
491 /* end of minibuffer */
495 void LyXParagraph::Clear()
500 pagebreak_top = false;
501 pagebreak_bottom = false;
503 added_space_top = VSpace(VSpace::NONE);
504 added_space_bottom = VSpace(VSpace::NONE);
506 align = LYX_ALIGN_LAYOUT;
510 pextra_type = PEXTRA_NONE;
511 pextra_width.clear();
512 pextra_widthp.clear();
513 pextra_alignment = MINIPAGE_ALIGN_TOP;
514 pextra_hfill = false;
515 pextra_start_minipage = false;
518 labelwidthstring.clear();
522 start_of_appendix = false;
526 /* the destructor removes the new paragraph from the list */
527 LyXParagraph::~LyXParagraph()
530 previous->next = next;
532 next->previous = previous;
535 InsetTable * tmpinset;
537 tmpinset = insettable;
538 insettable = insettable->next;
540 delete tmpinset->inset;
542 if (insettable && insettable->next == insettable) {
543 // somehow this recursion appears occasionally
544 // but I can't find where. This bandaid
545 // helps but isn't the best fix. (ARRae)
546 if (insettable->inset) {
547 delete insettable->inset;
557 fonttable = fonttable->next;
562 /* table stuff -- begin*/
565 /* table stuff -- end*/
573 void LyXParagraph::Erase(LyXParagraph::size_type pos)
575 /* > because last is the next unused position, and you can
576 * use it if you want */
578 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
579 NextAfterFootnote()->Erase(pos - text.size() - 1);
581 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
582 "position does not exist." << endl;
585 if (pos < size()) { // last is free for insertation, but should be empty
587 /* if it is an inset, delete the inset entry */
588 if (text[pos] == LyXParagraph::META_INSET) {
590 for(InsetList::iterator it = insetlist.begin();
591 it != insetlist.end(); ++it) {
592 if ((*it).pos == pos) {
600 /* if it is an inset, delete the inset entry */
601 if (text[pos] == LyXParagraph::META_INSET) {
603 InsetTable *tmpi = insettable;
604 InsetTable *tmpi2 = tmpi;
605 while (tmpi && tmpi->pos != pos) {
609 if (tmpi) { // this should always be true
610 if (tmpi->inset) // delete the inset if it exists
612 if (tmpi == insettable)
613 insettable = tmpi->next;
615 tmpi2->next = tmpi->next;
620 text.erase(text.begin() + pos);
622 /* erase entries in the tables */
623 for(FontList::iterator it = fontlist.begin();
624 it != fontlist.end(); ++it) {
625 if (pos >= (*it).pos && pos <= (*it).pos_end) {
626 if ((*it).pos == (*it).pos_end) {
633 /* update all other entries */
634 for(FontList::iterator it = fontlist.begin();
635 it != fontlist.end(); ++it) {
638 if ((*it).pos_end >= pos)
642 /* update the inset table */
643 for(InsetList::iterator it = insetlist.begin();
644 it != insetlist.end(); ++it) {
649 /* erase entries in the tables */
651 FontTable * tmp = fonttable;
652 FontTable * prev = 0;
653 while (tmp && !found) {
654 if (pos >= tmp->pos && pos <= tmp->pos_end)
662 if (found && tmp->pos == tmp->pos_end) {
663 /* if it is a multi-character font entry, we just make
664 * it smaller (see update below), otherwise we should
667 prev->next = tmp->next;
669 fonttable = tmp->next;
674 /* update all other entries */
680 if (tmp->pos_end >= pos)
685 /* update the inset table */
686 InsetTable * tmpi = insettable;
694 lyxerr << "ERROR (LyXParagraph::Erase): "
695 "can't erase non-existant char." << endl;
700 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
702 /* > because last is the next unused position, and you can
703 * use it if you want */
706 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
707 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
710 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
711 "position does not exist." << endl;
714 text.insert(text.begin() + pos, c);
716 // update the font table
717 for(FontList::iterator it = fontlist.begin();
718 it != fontlist.end(); ++it) {
719 if ((*it).pos >= pos)
721 if ((*it).pos_end >= pos)
724 // update the inset table
725 for(InsetList::iterator it = insetlist.begin();
726 it != insetlist.end(); ++it) {
727 if ((*it).pos >= pos)
731 /* update the font table */
732 FontTable * tmp = fonttable;
736 if (tmp->pos_end >= pos)
741 /* update the inset table */
742 InsetTable * tmpi = insettable;
744 if (tmpi->pos >= pos)
752 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
755 /* > because last is the next unused position, and you can
756 * use it if you want */
759 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
761 ->InsertInset(pos - text.size() - 1, inset);
763 lyxerr << "ERROR (LyXParagraph::InsertInset): "
764 "position does not exist: " << pos << endl;
767 if (text[pos] != LyXParagraph::META_INSET) {
768 lyxerr << "ERROR (LyXParagraph::InsertInset): "
769 "there is no LyXParagraph::META_INSET" << endl;
778 insetlist.push_back(tmp);
783 /* add a new entry in the inset table */
784 InsetTable * tmpi = new InsetTable;
787 tmpi->next = insettable;
794 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
798 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
799 return NextAfterFootnote()
800 ->GetInset(pos - text.size() - 1);
802 lyxerr << "ERROR (LyXParagraph::GetInset): "
803 "position does not exist: "
810 for(InsetList::iterator it = insetlist.begin();
811 it != insetlist.end(); ++it) {
812 if ((*it).pos == pos) {
816 lyxerr << "ERROR (LyXParagraph::GetInset): "
817 "Inset does not exist: " << pos << endl;
818 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
819 // Did this commenting out introduce a bug? So far I have not
820 // seen any, please enlighten me. (Lgb)
821 // My guess is that since the inset does not exist, we might
822 // as well replace it with a space to prevent crashes. (Asger)
826 InsetTable * tmpi = insettable;
828 while (tmpi && tmpi->pos != pos)
834 lyxerr << "ERROR (LyXParagraph::GetInset): "
835 "Inset does not exist: " << pos << endl;
836 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
837 // Did this commenting out introduce a bug? So far I have not
838 // seen any, please enlighten me. (Lgb)
839 // My guess is that since the inset does not exist, we might
840 // as well replace it with a space to prevent crashes. (Asger)
847 Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const
851 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
852 return NextAfterFootnote()
853 ->GetInset(pos - text.size() - 1);
855 lyxerr << "ERROR (LyXParagraph::GetInset): "
856 "position does not exist: "
863 for(InsetList::const_iterator cit = insetlist.begin();
864 cit != insetlist.end(); ++cit) {
865 if ((*cit).pos == pos) {
869 lyxerr << "ERROR (LyXParagraph::GetInset): "
870 "Inset does not exist: " << pos << endl;
871 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
872 // Did this commenting out introduce a bug? So far I have not
873 // seen any, please enlighten me. (Lgb)
874 // My guess is that since the inset does not exist, we might
875 // as well replace it with a space to prevent crashes. (Asger)
879 InsetTable * tmpi = insettable;
881 while (tmpi && tmpi->pos != pos)
887 lyxerr << "ERROR (LyXParagraph::GetInset): "
888 "Inset does not exist: " << pos << endl;
889 // in the const version we need to comment it out anyway...
890 //text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
891 // Did this commenting out introduce a bug? So far I have not
892 // seen any, please enlighten me. (Lgb)
893 // My guess is that since the inset does not exist, we might
894 // as well replace it with a space to prevent crashes. (Asger)
901 // Gets uninstantiated font setting at position.
902 // Optimized after profiling. (Asger)
903 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const
907 for(FontList::iterator it = fontlist.begin();
908 it != fontlist.end(); ++it) {
909 if (pos >= (*it).pos && pos <= (*it).pos_end)
913 FontTable * tmp = fonttable;
915 if (pos >= tmp->pos && pos <= tmp->pos_end)
921 /* > because last is the next unused position, and you can
922 * use it if you want */
923 else if (pos > size()) {
925 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
926 return NextAfterFootnote()
927 ->GetFontSettings(pos - text.size() - 1);
929 // Why is it an error to ask for the font of a
930 // position that does not exist? Would it be
931 // enough for this to be anable on debug?
932 // We want strict error checking, but it's ok to only
933 // have it when debugging. (Asger)
934 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
935 "position does not exist. "
936 << pos << " (" << static_cast<int>(pos)
940 return GetFontSettings(pos - 1);
942 return LyXFont(LyXFont::ALL_INHERIT);
946 // Gets the fully instantiated font at a given position in a paragraph
947 // This is basically the same function as LyXText::GetFont() in text2.C.
948 // The difference is that this one is used for generating the LaTeX file,
949 // and thus cosmetic "improvements" are disallowed: This has to deliver
950 // the true picture of the buffer. (Asger)
951 // If position is -1, we get the layout font of the paragraph.
952 // If position is -2, we get the font of the manual label of the paragraph.
953 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
956 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
958 LyXParagraph::size_type main_body = 0;
959 if (layout.labeltype == LABEL_MANUAL)
960 main_body = BeginningOfMainBody();
965 layoutfont = layout.labelfont;
967 layoutfont = layout.font;
968 tmpfont = GetFontSettings(pos);
969 tmpfont.realize(layoutfont);
971 // process layoutfont for pos == -1 and labelfont for pos < -1
973 tmpfont = layout.font;
975 tmpfont = layout.labelfont;
978 // check for environment font information
979 char par_depth = GetDepth();
980 LyXParagraph const * par = this;
981 while (par && par_depth && !tmpfont.resolved()) {
982 par = par->DepthHook(par_depth - 1);
984 tmpfont.realize(textclasslist.
985 Style(GetCurrentTextClass(),
986 par->GetLayout()).font);
987 par_depth = par->GetDepth();
991 tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
996 /// Returns the height of the highest font in range
997 LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
999 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
1001 for(FontList::const_iterator cit = fontlist.begin();
1002 cit != fontlist.end(); ++cit) {
1003 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
1004 LyXFont::FONT_SIZE size = (*cit).font.size();
1005 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
1010 FontTable * tmp = fonttable;
1012 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
1013 LyXFont::FONT_SIZE size = tmp->font.size();
1014 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
1024 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
1026 #ifdef DEVEL_VERSION
1027 /* a workaround to 'fix' some bugs in text-class */
1029 // This function is important. It should not work around bugs.
1030 // Let's find the bugs instead and fix them. (Asger)
1031 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
1032 " bad position " << pos << endl;
1040 /* > because last is the next unused position, and you can
1041 * use it if you want */
1042 else if (pos > size()) {
1043 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1044 return NextAfterFootnote()
1045 ->GetChar(pos - text.size() - 1);
1047 lyxerr << "ERROR (LyXParagraph::GetChar): "
1048 "position does not exist."
1049 << pos << " (" << static_cast<int>(pos)
1054 /* we should have a footnote environment */
1055 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1056 // Notice that LyX does request the
1057 // last char from time to time. (Asger)
1058 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1059 // "expected footnote." << endl;
1062 switch (next->footnotekind) {
1063 case LyXParagraph::FOOTNOTE:
1064 return LyXParagraph::META_FOOTNOTE;
1065 case LyXParagraph::MARGIN:
1066 return LyXParagraph::META_MARGIN;
1067 case LyXParagraph::FIG:
1068 case LyXParagraph::WIDE_FIG:
1069 return LyXParagraph::META_FIG;
1070 case LyXParagraph::TAB:
1071 case LyXParagraph::WIDE_TAB:
1072 return LyXParagraph::META_TAB;
1073 case LyXParagraph::ALGORITHM:
1074 return LyXParagraph::META_ALGORITHM;
1076 return '\0'; // to shut up gcc
1081 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1083 #ifdef DEVEL_VERSION
1084 /* a workaround to 'fix' some bugs in text-class */
1086 // This function is important. It should not work around bugs.
1087 // Let's find the bugs instead and fix them. (Asger)
1088 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
1089 " bad position " << pos << endl;
1097 /* > because last is the next unused position, and you can
1098 * use it if you want */
1099 else if (pos > size()) {
1100 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1101 return NextAfterFootnote()
1102 ->GetChar(pos - text.size() - 1);
1104 lyxerr << "ERROR (LyXParagraph::GetChar): "
1105 "position does not exist."
1106 << pos << " (" << static_cast<int>(pos)
1111 /* we should have a footnote environment */
1112 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1113 // Notice that LyX does request the
1114 // last char from time to time. (Asger)
1115 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1116 // "expected footnote." << endl;
1119 switch (next->footnotekind) {
1120 case LyXParagraph::FOOTNOTE:
1121 return LyXParagraph::META_FOOTNOTE;
1122 case LyXParagraph::MARGIN:
1123 return LyXParagraph::META_MARGIN;
1124 case LyXParagraph::FIG:
1125 case LyXParagraph::WIDE_FIG:
1126 return LyXParagraph::META_FIG;
1127 case LyXParagraph::TAB:
1128 case LyXParagraph::WIDE_TAB:
1129 return LyXParagraph::META_TAB;
1130 case LyXParagraph::ALGORITHM:
1131 return LyXParagraph::META_ALGORITHM;
1133 return '\0'; // to shut up gcc
1138 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1139 //Added 98/9/21 by REH
1140 // return an string of the current word, and the end of the word
1143 // the current word is defined as starting at the first character from
1144 // the immediate left of lastpospos which meets the definition of IsLetter(),
1145 // continuing to the last character to the right of this meeting
1149 // i just left this in from GetChar()
1151 #ifdef DEVEL_VERSION
1152 /* a workaround to 'fix' some bugs in text-class */
1154 // This function is important. It should not work around bugs.
1155 // Let's find the bugs instead and fix them. (Asger)
1156 lyxerr << "FATAL ERROR (LyXParagraph::GetWord):"
1157 " bad position " << lastpos << endl;
1167 //i think the devcode aborts before this, but why not be
1169 if (lastpos < 0) lastpos= 0;
1172 // move back until we have a letter
1174 //there's no real reason to have firstpos & lastpos as
1175 //separate variables as this is written, but maybe someon
1176 // will want to return firstpos in the future.
1178 //since someone might have typed a punctuation first
1179 int firstpos = lastpos;
1181 while ((firstpos >= 0) && !IsLetter(firstpos))
1184 // now find the beginning by looking for a nonletter
1186 while ((firstpos>= 0) && IsLetter(firstpos))
1189 // the above is now pointing to the preceeding non-letter
1193 // so copy characters into theword until we get a nonletter
1194 // note that this can easily exceed lastpos, wich means
1195 // that if used in the middle of a word, the whole word
1198 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1205 LyXParagraph::size_type LyXParagraph::Last() const
1207 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1208 return text.size() + NextAfterFootnote()->Last() + 1;
1209 /* the 1 is the symbol
1216 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1218 /* > because last is the next unused position, and you can
1219 * use it if you want */
1222 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1223 return NextAfterFootnote()
1224 ->ParFromPos(pos - text.size() - 1);
1226 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1227 "position does not exist." << endl;
1235 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1237 /* > because last is the next unused position, and you can
1238 * use it if you want */
1241 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1242 return NextAfterFootnote()
1243 ->PositionInParFromPos(pos - text.size() - 1);
1246 "ERROR (LyXParagraph::PositionInParFromPos): "
1247 "position does not exist." << endl;
1255 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1256 LyXFont const & font)
1258 /* > because last is the next unused position, and you can
1259 * use it if you want */
1261 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1262 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1265 lyxerr << "ERROR (LyXParagraph::SetFont): "
1266 "position does not exist." << endl;
1270 LyXFont patternfont(LyXFont::ALL_INHERIT);
1272 // First, reduce font against layout/label font
1273 // Update: The SetCharFont() routine in text2.C already reduces font, so
1274 // we don't need to do that here. (Asger)
1275 // No need to simplify this because it will disappear in a new kernel. (Asger)
1277 // Next search font table
1278 for(FontList::iterator it = fontlist.begin();
1279 it != fontlist.end(); ++it) {
1280 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1282 // we found a font entry. maybe we have to
1283 // split it and create a new one
1285 if ((*it).pos != (*it).pos_end) {
1286 // more than one character
1287 if (pos == (*it).pos) {
1288 // maybe we could enlarge
1289 // the left fonttable
1290 for(FontList::iterator fit = fontlist.begin();
1291 fit != fontlist.end(); ++fit) {
1292 if (pos - 1 >= (*fit).pos
1293 && pos - 1 <= (*fit).pos_end
1294 && (*fit).font == font) {
1302 // Add a new entry in the
1303 // fonttable for the position
1306 tmp.pos_end = (*it).pos_end;
1307 tmp.font = (*it).font;
1308 (*it).pos_end = pos;
1309 fontlist.push_back(tmp);
1310 } else if (pos == (*it).pos_end) {
1311 // Add a new entry in the
1312 // fonttable for the position
1314 tmp.pos = (*it).pos;
1315 tmp.pos_end = (*it).pos_end - 1;
1316 tmp.font = (*it).font;
1317 (*it).pos = (*it).pos_end;
1318 fontlist.push_back(tmp);
1320 // Add a new entry in the
1321 // fonttable for the position
1323 tmp.pos = (*it).pos;
1324 tmp.pos_end = pos - 1;
1325 tmp.font = (*it).font;
1326 fontlist.push_back(tmp);
1329 tmp.pos_end = (*it).pos_end;
1330 tmp.font = (*it).font;
1331 fontlist.push_back(tmp);
1334 (*it).pos_end = pos;
1342 // if we did not find a font entry, but if the font at hand
1343 // is the same as default, we just forget it
1344 if (font == patternfont) return;
1346 // ok, we did not find a font entry. But maybe there is exactly
1347 // the needed font entry one position left
1348 for(FontList::iterator it = fontlist.begin();
1349 it != fontlist.end(); ++it) {
1350 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1351 && (*it).font == font) {
1356 // Add a new entry in the
1357 // fonttable for the position
1361 tmp.font = patternfont;
1362 fontlist.push_back(tmp);
1364 // Next search font table
1368 FontTable * tmp = fonttable;
1369 while (tmp && !found) {
1370 if (pos >= tmp->pos && pos <= tmp->pos_end)
1377 /* if we did not find a font entry, but if the font at hand
1378 * is the same as default, we just forget it */
1379 if (font == patternfont)
1382 /* ok, we did not find a font entry. But maybe there is exactly
1383 * the needed font entry one position left */
1386 while (tmp2 && !found) {
1387 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1393 /* ok there is one. maybe it is exactly the needed font */
1394 if (tmp2->font == font) {
1395 /* put the position under the font */
1400 /* Add a new entry in the
1401 * fonttable for the position */
1402 tmp = new FontTable;
1405 tmp->font = patternfont;
1406 tmp->next = fonttable;
1409 /* we found a font entry. maybe we have to split it and create
1412 if (tmp->pos != tmp->pos_end) { /* more than one character */
1414 if (pos == tmp->pos) {
1415 /* maybe we could enlarge the left fonttable */
1419 while (tmp2 && !found) {
1420 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1426 /* Is there is one, and is it exactly the needed font? */
1427 if (found && tmp2->font == font) {
1428 /* put the position under the font */
1434 /* Add a new entry in the
1435 * fonttable for the position */
1436 tmp2 = new FontTable;
1437 tmp2->pos = pos + 1;
1438 tmp2->pos_end = tmp->pos_end;
1439 tmp2->font = tmp->font;
1441 tmp2->next = fonttable;
1444 else if (pos == tmp->pos_end) {
1445 /* Add a new entry in the
1446 * fonttable for the position */
1447 tmp2 = new FontTable;
1448 tmp2->pos = tmp->pos;
1449 tmp2->pos_end = tmp->pos_end - 1;
1450 tmp2->font = tmp->font;
1451 tmp->pos = tmp->pos_end;
1452 tmp2->next = fonttable;
1456 /* Add a new entry in the
1457 * fonttable for the position */
1458 tmp2 = new FontTable;
1459 tmp2->pos = tmp->pos;
1460 tmp2->pos_end = pos - 1;
1461 tmp2->font = tmp->font;
1462 tmp2->next = fonttable;
1465 tmp2 = new FontTable;
1466 tmp2->pos = pos + 1;
1467 tmp2->pos_end = tmp->pos_end;
1468 tmp2->font = tmp->font;
1469 tmp2->next = fonttable;
1482 /* this function is able to hide closed footnotes */
1483 LyXParagraph * LyXParagraph::Next()
1485 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1486 LyXParagraph * tmp = next;
1488 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1490 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1491 return tmp->Next(); /* there can be more than one
1492 footnote in a logical
1495 return next; /* this should never happen! */
1502 LyXParagraph * LyXParagraph::NextAfterFootnote()
1504 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1505 LyXParagraph * tmp = next;
1506 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1508 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1509 return tmp; /* there can be more than one footnote
1510 in a logical paragraph */
1512 return next; /* this should never happen! */
1519 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1521 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1522 LyXParagraph * tmp = next;
1523 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1525 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1526 return tmp; /* there can be more than one footnote
1527 in a logical paragraph */
1529 return next; /* this should never happen! */
1536 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1539 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1541 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1542 tmp = tmp->previous;
1543 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1544 return tmp; /* there can be more than one footnote
1545 in a logical paragraph */
1547 return previous; /* this should never happen! */
1554 LyXParagraph * LyXParagraph::LastPhysicalPar()
1556 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1559 LyXParagraph * tmp = this;
1561 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1562 tmp = tmp->NextAfterFootnote();
1569 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1573 LyXParagraph * tmppar = this;
1575 while (tmppar && (tmppar->IsDummy()
1576 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1577 tmppar = tmppar->previous;
1580 return this; /* this should never happen! */
1586 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1590 LyXParagraph const * tmppar = this;
1592 while (tmppar && (tmppar->IsDummy()
1593 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1594 tmppar = tmppar->previous;
1597 return this; /* this should never happen! */
1603 /* this function is able to hide closed footnotes */
1604 LyXParagraph * LyXParagraph::Previous()
1606 LyXParagraph * tmp = previous;
1611 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1612 tmp = tmp->previous;
1614 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1615 tmp = tmp->previous;
1616 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1617 return tmp->next->Previous();
1627 /* this function is able to hide closed footnotes */
1628 LyXParagraph const * LyXParagraph::Previous() const
1630 LyXParagraph * tmp = previous;
1635 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1636 tmp = tmp->previous;
1638 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1639 tmp = tmp->previous;
1640 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1641 return tmp->next->Previous();
1651 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1654 size_type i, pos_end, pos_first;
1655 /* create a new paragraph */
1656 LyXParagraph * par = ParFromPos(pos);
1657 LyXParagraph * firstpar = FirstPhysicalPar();
1659 LyXParagraph * tmp = new LyXParagraph(par);
1661 tmp->footnoteflag = footnoteflag;
1662 tmp->footnotekind = footnotekind;
1664 /* this is an idea for a more userfriendly layout handling, I will
1665 * see what the users say */
1667 /* layout stays the same with latex-environments */
1669 tmp->SetOnlyLayout(firstpar->layout);
1670 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1673 if (Last() > pos || !Last() || flag == 2) {
1674 tmp->SetOnlyLayout(firstpar->layout);
1675 tmp->align = firstpar->align;
1676 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1678 tmp->line_bottom = firstpar->line_bottom;
1679 firstpar->line_bottom = false;
1680 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1681 firstpar->pagebreak_bottom = false;
1682 tmp->added_space_bottom = firstpar->added_space_bottom;
1683 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1685 tmp->depth = firstpar->depth;
1686 tmp->noindent = firstpar->noindent;
1688 /* copy everything behind the break-position
1689 to the new paragraph
1692 while (ParFromPos(pos_first) != par)
1695 pos_end = pos_first + par->text.size() - 1;
1696 tmp->text.reserve(pos_end - pos);
1698 for (i = pos; i <= pos_end; i++) {
1699 par->CutIntoMinibuffer(i - pos_first);
1700 tmp->InsertFromMinibuffer(i - pos);
1703 for (i = pos_end; i >= pos; i--)
1704 par->Erase(i - pos_first);
1706 par->text.resize(par->text.size());
1709 /* just an idea of me */
1711 tmp->line_top = firstpar->line_top;
1712 tmp->pagebreak_top = firstpar->pagebreak_top;
1713 tmp->added_space_top = firstpar->added_space_top;
1714 tmp->bibkey = firstpar->bibkey;
1716 /* layout stays the same with latex-environments */
1718 firstpar->SetOnlyLayout(tmp->layout);
1719 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1720 firstpar->depth = tmp->depth;
1726 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1728 par = par->FirstPhysicalPar();
1729 footnoteflag = par->footnoteflag;
1730 footnotekind = par->footnotekind;
1732 layout = par->layout;
1733 align = par-> align;
1734 SetLabelWidthString(par->labelwidthstring);
1736 line_bottom = par->line_bottom;
1737 pagebreak_bottom = par->pagebreak_bottom;
1738 added_space_bottom = par->added_space_bottom;
1740 line_top = par->line_top;
1741 pagebreak_top = par->pagebreak_top;
1742 added_space_top = par->added_space_top;
1744 pextra_type = par->pextra_type;
1745 pextra_width = par->pextra_width;
1746 pextra_widthp = par->pextra_widthp;
1747 pextra_alignment = par->pextra_alignment;
1748 pextra_hfill = par->pextra_hfill;
1749 pextra_start_minipage = par->pextra_start_minipage;
1751 noindent = par->noindent;
1756 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1758 LyXParagraph * tmppar = this;
1761 && tmppar->previous->footnoteflag ==
1762 LyXParagraph::CLOSED_FOOTNOTE)
1763 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1764 tmppar = tmppar->previous;
1767 return this; /* this should never happen! */
1773 LyXParagraph * LyXParagraph::Clone() const
1775 /* create a new paragraph */
1776 LyXParagraph * result = new LyXParagraph;
1778 result->MakeSameLayout(this);
1780 /* this is because of the dummy layout of the paragraphs that
1782 result->layout = layout;
1784 /* table stuff -- begin*/
1786 result->table = table->Clone();
1789 /* table stuff -- end*/
1792 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1795 /* copy everything behind the break-position to the new paragraph */
1797 for (size_type i = 0; i < size(); i++) {
1798 CopyIntoMinibuffer(i);
1799 result->InsertFromMinibuffer(i);
1801 result->text.resize(result->text.size());
1806 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1808 par = par->FirstPhysicalPar();
1811 par->footnoteflag == footnoteflag &&
1812 par->footnotekind == footnotekind &&
1814 par->layout == layout &&
1816 par->align == align &&
1818 par->line_bottom == line_bottom &&
1819 par->pagebreak_bottom == pagebreak_bottom &&
1820 par->added_space_bottom == added_space_bottom &&
1822 par->line_top == line_top &&
1823 par->pagebreak_top == pagebreak_top &&
1824 par->added_space_top == added_space_top &&
1826 par->pextra_type == pextra_type &&
1827 par->pextra_width == pextra_width &&
1828 par->pextra_widthp == pextra_widthp &&
1829 par->pextra_alignment == pextra_alignment &&
1830 par->pextra_hfill == pextra_hfill &&
1831 par->pextra_start_minipage == pextra_start_minipage &&
1833 par->table == table && // what means: NO TABLE AT ALL
1835 par->noindent == noindent &&
1836 par->depth == depth);
1840 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1842 size_type i, pos_end, pos_first;
1844 /* create a new paragraph */
1845 LyXParagraph * par = ParFromPos(pos);
1847 LyXParagraph * tmp = new LyXParagraph(par);
1849 tmp->MakeSameLayout(par);
1852 /* copy everything behind the break-position to the new
1855 while (ParFromPos(pos_first) != par)
1857 pos_end = pos_first + par->text.size() - 1;
1858 /* make shure there is enough memory for the now larger
1859 paragraph. This is not neccessary, because
1860 InsertFromMinibuffer will enlarge the memory (it uses
1861 InsertChar of course). But doing it by hand
1862 is MUCH faster! (only one time, not thousend times!!) */
1863 tmp->text.reserve(pos_end - pos);
1865 for (i = pos; i <= pos_end; i++) {
1867 par->CutIntoMinibuffer(i - pos_first);
1868 tmp->InsertFromMinibuffer(i - pos);
1870 for (i = pos_end; i >= pos; i--)
1871 par->Erase(i - pos_first);
1873 par->text.resize(par->text.size());
1878 /* be carefull, this does not make any check at all */
1879 void LyXParagraph::PasteParagraph()
1881 /* copy the next paragraph to this one */
1882 LyXParagraph * the_next = Next();
1884 LyXParagraph * firstpar = FirstPhysicalPar();
1886 /* first the DTP-stuff */
1887 firstpar->line_bottom = the_next->line_bottom;
1888 firstpar->added_space_bottom = the_next->added_space_bottom;
1889 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1891 size_type pos_end = the_next->text.size() - 1;
1892 size_type pos_insert = Last();
1895 /* ok, now copy the paragraph */
1896 for (i = 0; i <= pos_end; i++) {
1897 the_next->CutIntoMinibuffer(i);
1898 InsertFromMinibuffer(pos_insert + i);
1901 /* delete the next paragraph */
1906 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1908 LyXParagraph * par = ParFromPos(pos);
1910 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1911 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1917 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1919 LyXParagraph * par = ParFromPos(pos);
1921 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1922 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1928 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1930 return FirstPhysicalPar()->layout;
1934 char LyXParagraph::GetDepth() const
1936 return FirstPhysicalPar()->depth;
1940 char LyXParagraph::GetAlign() const
1942 return FirstPhysicalPar()->align;
1946 string LyXParagraph::GetLabestring() const
1948 return FirstPhysicalPar()->labelstring;
1952 int LyXParagraph::GetFirstCounter(int i) const
1954 return FirstPhysicalPar()->counter_[i];
1958 /* the next two functions are for the manual labels */
1959 string LyXParagraph::GetLabelWidthString() const
1961 if (!FirstPhysicalPar()->labelwidthstring.empty())
1962 return FirstPhysicalPar()->labelwidthstring;
1964 return _("Senseless with this layout!");
1968 void LyXParagraph::SetLabelWidthString(string const & s)
1970 LyXParagraph * par = FirstPhysicalPar();
1972 par->labelwidthstring = s;
1976 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1978 LyXParagraph * par = FirstPhysicalPar();
1979 LyXParagraph * ppar = 0;
1980 LyXParagraph * npar = 0;
1982 par->layout = new_layout;
1983 /* table stuff -- begin*/
1986 /* table stuff -- end*/
1987 if (par->pextra_type == PEXTRA_NONE) {
1988 if (par->Previous()) {
1989 ppar = par->Previous()->FirstPhysicalPar();
1992 && (ppar->depth > par->depth))
1993 ppar = ppar->Previous()->FirstPhysicalPar();
1996 npar = par->Next()->NextAfterFootnote();
1999 && (npar->depth > par->depth))
2000 npar = npar->Next()->NextAfterFootnote();
2002 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2004 p1 = ppar->pextra_width,
2005 p2 = ppar->pextra_widthp;
2006 ppar->SetPExtraType(ppar->pextra_type,
2007 p1.c_str(), p2.c_str());
2009 if ((par->pextra_type == PEXTRA_NONE) &&
2010 npar && (npar->pextra_type != PEXTRA_NONE)) {
2012 p1 = npar->pextra_width,
2013 p2 = npar->pextra_widthp;
2014 npar->SetPExtraType(npar->pextra_type,
2015 p1.c_str(), p2.c_str());
2021 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
2024 * par = FirstPhysicalPar(),
2028 par->layout = new_layout;
2029 par->labelwidthstring.clear();
2030 par->align = LYX_ALIGN_LAYOUT;
2031 par->added_space_top = VSpace(VSpace::NONE);
2032 par->added_space_bottom = VSpace(VSpace::NONE);
2033 /* table stuff -- begin*/
2036 /* table stuff -- end*/
2037 if (par->pextra_type == PEXTRA_NONE) {
2038 if (par->Previous()) {
2039 ppar = par->Previous()->FirstPhysicalPar();
2042 && (ppar->depth > par->depth))
2043 ppar = ppar->Previous()->FirstPhysicalPar();
2046 npar = par->Next()->NextAfterFootnote();
2049 && (npar->depth > par->depth))
2050 npar = npar->Next()->NextAfterFootnote();
2052 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2054 p1 = ppar->pextra_width,
2055 p2 = ppar->pextra_widthp;
2056 ppar->SetPExtraType(ppar->pextra_type,
2057 p1.c_str(), p2.c_str());
2059 if ((par->pextra_type == PEXTRA_NONE) &&
2060 npar && (npar->pextra_type != PEXTRA_NONE)) {
2062 p1 = npar->pextra_width,
2063 p2 = npar->pextra_widthp;
2064 npar->SetPExtraType(npar->pextra_type,
2065 p1.c_str(), p2.c_str());
2071 /* if the layout of a paragraph contains a manual label, the beginning of the
2072 * main body is the beginning of the second word. This is what the par-
2073 * function returns. If the layout does not contain a label, the main
2074 * body always starts with position 0. This differentiation is necessary,
2075 * because there cannot be a newline or a blank <= the beginning of the
2076 * main body in TeX. */
2078 int LyXParagraph::BeginningOfMainBody() const
2080 if (FirstPhysicalPar() != this)
2083 // Unroll the first two cycles of the loop
2084 // and remember the previous character to
2085 // remove unnecessary GetChar() calls
2088 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2090 char previous_char, temp;
2092 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2093 // Yes, this ^ is supposed to be "= " not "=="
2096 && previous_char != ' '
2097 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2099 previous_char = temp;
2104 if (i == 0 && i == size() &&
2105 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2106 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2107 i++; /* the cursor should not jump
2108 * to the main body if there
2114 LyXParagraph * LyXParagraph::DepthHook(int deth)
2116 LyXParagraph * newpar = this;
2121 newpar = newpar->FirstPhysicalPar()->Previous();
2122 } while (newpar && newpar->GetDepth() > deth
2123 && newpar->footnoteflag == footnoteflag);
2126 if (Previous() || GetDepth())
2127 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2131 return newpar->FirstPhysicalPar();
2135 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2137 LyXParagraph const * newpar = this;
2142 newpar = newpar->FirstPhysicalPar()->Previous();
2143 } while (newpar && newpar->GetDepth() > deth
2144 && newpar->footnoteflag == footnoteflag);
2147 if (Previous() || GetDepth())
2148 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2152 return newpar->FirstPhysicalPar();
2156 int LyXParagraph::AutoDeleteInsets()
2160 for (InsetList::iterator it = insetlist.begin();
2161 it != insetlist.end(); ++it) {
2162 if ((*it).inset->AutoDelete()) {
2169 InsetTable * tmpi = insettable;
2170 InsetTable * tmpi2 = tmpi;
2176 if (tmpi2->inset->AutoDelete()) {
2181 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2182 "cannot auto-delete insets" << endl;
2189 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2192 InsetTable * tmp = 0;
2193 for (InsetList::iterator it = insetlist.begin();
2194 it != insetlist.end(); ++it) {
2195 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2206 InsetTable * tmpi = insettable;
2207 InsetTable * tmpi2 = 0;
2209 if (tmpi->pos >= pos) {
2210 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2217 return tmpi2->inset;
2225 /* returns -1 if inset not found */
2226 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2229 for (InsetList::iterator it = insetlist.begin();
2230 it != insetlist.end(); ++it) {
2231 if ((*it).inset == inset) {
2235 // Think about footnotes
2236 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2237 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2238 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2240 return size() + 1 + further;
2244 /* find the entry */
2245 InsetTable * tmpi = insettable;
2246 while (tmpi && tmpi->inset != inset) {
2249 if (tmpi && tmpi->inset)
2252 /* think about footnotes */
2253 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2254 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2256 NextAfterFootnote()->GetPositionOfInset(inset);
2258 return text.size() + 1 + further;
2266 void LyXParagraph::readSimpleWholeFile(FILE * myfile)
2270 if (!feof(myfile)) {
2274 InsertChar(text.size(), c);
2275 } while (!feof(myfile));
2281 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2282 string & foot, TexRow & foot_texrow,
2285 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2286 LyXParagraph * par = next;
2287 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2290 bool further_blank_line = false;
2292 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2294 if (start_of_appendix) {
2295 file += "\\appendix\n";
2299 if (tex_code_break_column && style.isCommand()){
2304 if (pagebreak_top) {
2305 file += "\\newpage";
2306 further_blank_line = true;
2308 if (added_space_top.kind() != VSpace::NONE) {
2309 file += added_space_top.asLatexCommand();
2310 further_blank_line = true;
2314 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2315 file += "\\vspace{-1\\parskip}";
2316 further_blank_line = true;
2319 if (further_blank_line){
2324 switch (style.latextype) {
2327 file += style.latexname();
2328 file += style.latexparam();
2330 case LATEX_ITEM_ENVIRONMENT:
2332 bibkey->Latex(file, false);
2336 case LATEX_LIST_ENVIRONMENT:
2343 bool need_par = SimpleTeXOnePar(file, texrow);
2345 // Spit out footnotes
2346 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2347 && par->footnoteflag != footnoteflag) {
2348 par = par->TeXFootnote(file, texrow,
2349 foot, foot_texrow, foot_count);
2350 par->SimpleTeXOnePar(file, texrow);
2354 // Make sure that \\par is done with the font of the last
2355 // character if this has another size as the default.
2356 // This is necessary because LaTeX (and LyX on the screen)
2357 // calculates the space between the baselines according
2358 // to this font. (Matthias)
2359 LyXFont font = getFont(Last()-1);
2361 if (style.resfont.size() != font.size()) {
2363 file += font.latexSize();
2367 } else if (textclasslist.Style(GetCurrentTextClass(),
2368 GetLayout()).isCommand()){
2369 if (style.resfont.size() != font.size()) {
2371 file += font.latexSize();
2375 } else if (style.resfont.size() != font.size()){
2376 file += "{\\" + font.latexSize() + " \\par}";
2379 switch (style.latextype) {
2380 case LATEX_ITEM_ENVIRONMENT:
2381 case LATEX_LIST_ENVIRONMENT:
2382 if (par && (depth < par->depth)) {
2387 case LATEX_ENVIRONMENT:
2388 // if its the last paragraph of the current environment
2389 // skip it otherwise fall through
2391 && (par->layout != layout
2392 || par->depth != depth
2393 || par->pextra_type != pextra_type))
2396 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2397 && footnotekind != LyXParagraph::FOOTNOTE
2398 && footnotekind != LyXParagraph::MARGIN
2402 // don't insert this if we would be adding it
2403 // before or after a table in a float. This
2404 // little trick is needed in order to allow
2405 // use of tables in \subfigures or \subtables.
2411 further_blank_line = false;
2413 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2414 further_blank_line = true;
2417 if (added_space_bottom.kind() != VSpace::NONE) {
2418 file += added_space_bottom.asLatexCommand();
2419 further_blank_line = true;
2422 if (pagebreak_bottom) {
2423 file += "\\newpage";
2424 further_blank_line = true;
2427 if (further_blank_line){
2432 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2433 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2438 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2443 // This one spits out the text of the paragraph
2444 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2446 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2449 return SimpleTeXOneTablePar(file, texrow);
2452 size_type main_body;
2454 bool return_value = false;
2456 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2459 /* maybe we have to create a optional argument */
2460 if (style.labeltype != LABEL_MANUAL)
2463 main_body = BeginningOfMainBody();
2465 if (main_body > 0) {
2467 basefont = getFont(-2); // Get label font
2469 basefont = getFont(-1); // Get layout font
2477 if (style.isCommand()) {
2480 } else if (align != LYX_ALIGN_LAYOUT) {
2483 return_value = true;
2487 // Which font is currently active?
2488 LyXFont running_font = basefont;
2489 // Do we have an open font change?
2490 bool open_font = false;
2492 texrow.start(this, 0);
2494 for (size_type i = 0; i < size(); ++i) {
2496 // First char in paragraph or after label?
2497 if (i == main_body && !IsDummy()) {
2498 if (main_body > 0) {
2500 column += running_font.latexWriteEndChanges(file, basefont);
2503 basefont = getFont(-1); // Now use the layout font
2504 running_font = basefont;
2508 if (style.isCommand()) {
2511 } else if (align != LYX_ALIGN_LAYOUT) {
2514 return_value = true;
2518 file += "\\noindent ";
2522 case LYX_ALIGN_NONE:
2523 case LYX_ALIGN_BLOCK:
2524 case LYX_ALIGN_LAYOUT:
2525 case LYX_ALIGN_SPECIAL: break;
2526 case LYX_ALIGN_LEFT:
2527 file += "\\raggedright ";
2530 case LYX_ALIGN_RIGHT:
2531 file += "\\raggedleft ";
2534 case LYX_ALIGN_CENTER:
2535 file += "\\centering ";
2543 // Fully instantiated font
2544 LyXFont font = getFont(i);
2546 // Spaces at end of font change are simulated to be
2547 // outside font change, i.e. we write "\textXX{text} "
2548 // rather than "\textXX{text }". (Asger)
2549 if (open_font && c == ' ' && i <= size() - 2
2550 && !getFont(i+1).equalExceptLatex(running_font)
2551 && !getFont(i+1).equalExceptLatex(font)) {
2552 font = getFont(i+1);
2554 // We end font definition before blanks
2555 if (!font.equalExceptLatex(running_font) && open_font) {
2556 column += running_font.latexWriteEndChanges(file,
2558 running_font = basefont;
2562 // Blanks are printed before start of fontswitch
2564 // Do not print the separation of the optional argument
2565 if (i != main_body - 1) {
2566 SimpleTeXBlanks(file, texrow, i,
2567 column, font, style);
2571 // Do we need to change font?
2572 if (!font.equalExceptLatex(running_font)
2573 && i != main_body-1) {
2574 column += font.latexWriteStartChanges(file, basefont);
2575 running_font = font;
2579 if (c == LyXParagraph::META_NEWLINE) {
2580 // newlines are handled differently here than
2581 // the default in SimpleTeXSpecialChars().
2582 if (!style.newline_allowed
2583 || font.latex() == LyXFont::ON) {
2587 column += running_font.latexWriteEndChanges(file, basefont);
2590 basefont = getFont(-1);
2591 running_font = basefont;
2592 if (font.family() ==
2593 LyXFont::TYPEWRITER_FAMILY) {
2599 texrow.start(this, i+1);
2602 SimpleTeXSpecialChars(file, texrow,
2603 font, running_font, basefont,
2604 open_font, style, i, column, c);
2608 // If we have an open font definition, we have to close it
2610 running_font.latexWriteEndChanges(file, basefont);
2613 /* needed if there is an optional argument but no contents */
2614 if (main_body > 0 && main_body == size()) {
2616 return_value = false;
2619 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2620 return return_value;
2624 // This one spits out the text of a table paragraph
2625 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2627 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2631 bool return_value = false;
2632 int current_cell_number = -1;
2634 LyXLayout const & style =
2635 textclasslist.Style(GetCurrentTextClass(), GetLayout());
2636 LyXFont basefont = getFont(-1); // Get layout font
2637 // Which font is currently active?
2638 LyXFont running_font = basefont;
2639 // Do we have an open font change?
2640 bool open_font = false;
2643 if (!IsDummy()) { // it is dummy if it is in a float!!!
2644 if (style.isCommand()) {
2647 } else if (align != LYX_ALIGN_LAYOUT) {
2650 return_value = true;
2653 file += "\\noindent ";
2657 case LYX_ALIGN_NONE:
2658 case LYX_ALIGN_BLOCK:
2659 case LYX_ALIGN_LAYOUT:
2660 case LYX_ALIGN_SPECIAL: break;
2661 case LYX_ALIGN_LEFT:
2662 file += "\\raggedright ";
2665 case LYX_ALIGN_RIGHT:
2666 file += "\\raggedleft ";
2669 case LYX_ALIGN_CENTER:
2670 file += "\\centering ";
2675 current_cell_number = -1;
2676 tmp = table->TexEndOfCell(file, current_cell_number);
2677 for (; tmp > 0 ; --tmp)
2680 texrow.start(this, 0);
2682 for (size_type i = 0; i < size(); ++i) {
2684 if (table->IsContRow(current_cell_number+1)) {
2685 if (c == LyXParagraph::META_NEWLINE)
2686 current_cell_number++;
2691 // Fully instantiated font
2692 LyXFont font = getFont(i);
2694 // Spaces at end of font change are simulated to be
2695 // outside font change.
2696 // i.e. we write "\textXX{text} " rather than
2697 // "\textXX{text }". (Asger)
2698 if (open_font && c == ' ' && i <= size() - 2
2699 && getFont(i+1) != running_font && getFont(i+1) != font) {
2700 font = getFont(i+1);
2703 // We end font definition before blanks
2704 if (font != running_font && open_font) {
2705 column += running_font.latexWriteEndChanges(file,
2707 running_font = basefont;
2710 // Blanks are printed before start of fontswitch
2712 SimpleTeXBlanks(file, texrow, i, column, font, style);
2714 // Do we need to change font?
2715 if (font != running_font) {
2716 column += font.latexWriteStartChanges(file, basefont);
2717 running_font = font;
2720 // Do we need to turn on LaTeX mode?
2721 if (font.latex() != running_font.latex()) {
2722 if (font.latex() == LyXFont::ON
2723 && style.needprotect) {
2724 file += "\\protect ";
2728 if (c == LyXParagraph::META_NEWLINE) {
2729 // special case for inside a table
2730 // different from default case in
2731 // SimpleTeXSpecialChars()
2733 column += running_font
2734 .latexWriteEndChanges(file, basefont);
2737 basefont = getFont(-1);
2738 running_font = basefont;
2739 current_cell_number++;
2740 if (table->CellHasContRow(current_cell_number) >= 0) {
2741 TeXContTableRows(file, i+1,
2742 current_cell_number,
2745 // if this cell follow only ContRows till end don't
2746 // put the EndOfCell because it is put after the
2748 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2749 current_cell_number--;
2752 int tmp = table->TexEndOfCell(file,
2753 current_cell_number);
2756 } else if (tmp < 0) {
2762 texrow.start(this, i+1);
2764 SimpleTeXSpecialChars(file, texrow,
2765 font, running_font, basefont,
2766 open_font, style, i, column, c);
2770 // If we have an open font definition, we have to close it
2772 running_font.latexWriteEndChanges(file, basefont);
2774 current_cell_number++;
2775 tmp = table->TexEndOfCell(file, current_cell_number);
2776 for (; tmp > 0; --tmp)
2778 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2779 return return_value;
2783 // This one spits out the text off ContRows in tables
2784 bool LyXParagraph::TeXContTableRows(string & file,
2785 LyXParagraph::size_type i,
2786 int current_cell_number,
2787 int & column, TexRow & texrow)
2789 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2795 bool return_value = false;
2796 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2800 basefont = getFont(-1); // Get layout font
2801 // Which font is currently active?
2802 LyXFont running_font = basefont;
2803 // Do we have an open font change?
2804 bool open_font = false;
2806 size_type lastpos = i;
2807 int cell = table->CellHasContRow(current_cell_number);
2808 ++current_cell_number;
2810 // first find the right position
2812 for (; (i < size()) && (current_cell_number<cell); ++i) {
2814 if (c == LyXParagraph::META_NEWLINE)
2815 current_cell_number++;
2819 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2823 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2828 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2832 // Fully instantiated font
2833 LyXFont font = getFont(i);
2835 // Spaces at end of font change are simulated to
2836 // be outside font change. i.e. we write
2837 // "\textXX{text} " rather than "\textXX{text }".
2839 if (open_font && c == ' ' && i <= size() - 2
2840 && getFont(i + 1) != running_font
2841 && getFont(i + 1) != font) {
2842 font = getFont(i + 1);
2845 // We end font definition before blanks
2846 if (font != running_font && open_font) {
2847 column += running_font.latexWriteEndChanges(file, basefont);
2848 running_font = basefont;
2851 // Blanks are printed before start of fontswitch
2853 SimpleTeXBlanks(file, texrow, i,
2854 column, font, style);
2856 // Do we need to change font?
2857 if (font != running_font) {
2859 font.latexWriteStartChanges(file,
2861 running_font = font;
2864 // Do we need to turn on LaTeX mode?
2865 if (font.latex() != running_font.latex()) {
2866 if (font.latex() == LyXFont::ON
2867 && style.needprotect)
2869 file += "\\protect ";
2873 SimpleTeXSpecialChars(file, texrow, font,
2874 running_font, basefont,
2875 open_font, style, i, column, c);
2877 // If we have an open font definition, we have to close it
2879 running_font.latexWriteEndChanges(file, basefont);
2882 basefont = getFont(-1);
2883 running_font = basefont;
2884 cell = table->CellHasContRow(current_cell_number);
2886 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2887 return return_value;
2891 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2893 bool retval = false;
2895 case LyXParagraph::META_HFILL:
2896 sgml_string.clear();
2898 case LyXParagraph::META_PROTECTED_SEPARATOR:
2901 case LyXParagraph::META_NEWLINE:
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 = "}";
2935 sgml_string = "˜";
2938 sgml_string = """;
2941 sgml_string = "\";
2947 case '\0': /* Ignore :-) */
2948 sgml_string.clear();
2958 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2959 int & desc_on, int depth)
2962 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2964 LyXFont font1, font2;
2967 size_type main_body;
2968 string emph = "emphasis";
2969 bool emph_flag = false;
2971 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2974 if (style.labeltype != LABEL_MANUAL)
2977 main_body = BeginningOfMainBody();
2979 /* gets paragraph main font */
2981 font1 = style.labelfont;
2985 int char_line_count = depth;
2986 addNewlineAndDepth(file, depth);
2987 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2988 file += "<INFORMALTABLE>";
2989 addNewlineAndDepth(file, ++depth);
2991 int current_cell_number = -1;
2992 int tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2994 /* parsing main loop */
2995 for (size_type i = 0; i < size(); ++i) {
2997 if (table->IsContRow(current_cell_number+1)) {
2998 if (c == LyXParagraph::META_NEWLINE)
2999 ++current_cell_number;
3004 // Fully instantiated font
3007 /* handle <emphasis> tag */
3008 if (font1.emph() != font2.emph() && i) {
3009 if (font2.emph() == LyXFont::ON) {
3010 file += "<emphasis>";
3012 } else if (emph_flag) {
3013 file += "</emphasis>";
3017 if (c == LyXParagraph::META_NEWLINE) {
3018 // we have only to control for emphasis open here!
3020 file += "</emphasis>";
3023 font1 = font2 = getFont(-1);
3024 current_cell_number++;
3025 if (table->CellHasContRow(current_cell_number) >= 0) {
3026 DocBookContTableRows(file, extra, desc_on, i+1,
3027 current_cell_number,
3030 // if this cell follow only ContRows till end don't
3031 // put the EndOfCell because it is put after the
3033 if (table->ShouldBeVeryLastCell(current_cell_number)) {
3034 current_cell_number--;
3037 tmp= table->DocBookEndOfCell(file, current_cell_number,
3042 } else if (c == LyXParagraph::META_INSET) {
3043 inset = GetInset(i);
3045 inset->DocBook(tmp_out);
3047 // This code needs some explanation:
3048 // Two insets are treated specially
3049 // label if it is the first element in a
3050 // command paragraph
3052 // graphics inside tables or figure floats
3054 // title (the equivalente in latex for this
3056 // and title should come first
3059 if(desc_on != 3 || i != 0) {
3060 if(tmp_out[0] == '@') {
3062 extra += frontStrip(tmp_out,
3065 file += frontStrip(tmp_out,
3070 } else if (font2.latex() == LyXFont::ON) {
3071 // "TeX"-Mode on == > SGML-Mode on.
3077 if (linuxDocConvertChar(c, sgml_string)
3078 && !style.free_spacing) {
3079 // in freespacing mode, spaces are
3080 // non-breaking characters
3085 file += "</term><listitem><para>";
3091 file += sgml_string;
3097 /* needed if there is an optional argument but no contents */
3098 if (main_body > 0 && main_body == size()) {
3103 file += "</emphasis>";
3106 current_cell_number++;
3107 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3108 /* resets description flag correctly */
3111 /* <term> not closed... */
3115 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3116 file += "</INFORMALTABLE>";
3118 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3123 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3125 LyXParagraph::size_type i,
3126 int current_cell_number, int &column)
3131 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3134 LyXFont font1, font2;
3137 size_type main_body;
3139 string emph= "emphasis";
3140 bool emph_flag= false;
3141 int char_line_count= 0;
3143 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3146 if (style.labeltype != LABEL_MANUAL)
3149 main_body = BeginningOfMainBody();
3151 /* gets paragraph main font */
3153 font1 = style.labelfont;
3158 cell = table->CellHasContRow(current_cell_number);
3159 ++current_cell_number;
3161 // first find the right position
3163 for (; i < size() && current_cell_number < cell; ++i) {
3165 if (c == LyXParagraph::META_NEWLINE)
3166 current_cell_number++;
3170 // I don't know how to handle this so I comment it
3171 // for the moment (Jug)
3172 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3173 // file += " \\\\\n";
3176 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3181 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3185 // Fully instantiated font
3188 /* handle <emphasis> tag */
3189 if (font1.emph() != font2.emph() && i) {
3190 if (font2.emph() == LyXFont::ON) {
3191 file += "<emphasis>";
3193 } else if (emph_flag) {
3194 file += "</emphasis>";
3198 if (c == LyXParagraph::META_INSET) {
3199 inset = GetInset(i);
3201 inset->DocBook(tmp_out);
3203 // This code needs some explanation:
3204 // Two insets are treated specially
3205 // label if it is the first element in a command paragraph
3207 // graphics inside tables or figure floats can't go on
3208 // title (the equivalente in latex for this case is caption
3209 // and title should come first
3212 if(desc_on != 3 || i != 0) {
3213 if(tmp_out[0] == '@') {
3215 extra += frontStrip(tmp_out, '@');
3217 file += frontStrip(tmp_out, '@');
3221 } else if (font2.latex() == LyXFont::ON) {
3222 // "TeX"-Mode on == > SGML-Mode on.
3228 if (linuxDocConvertChar(c, sgml_string)
3229 && !style.free_spacing) {
3230 // in freespacing mode, spaces are
3231 // non-breaking characters
3236 file += "</term><listitem><para>";
3242 file += sgml_string;
3246 // we have only to control for emphasis open here!
3248 file += "</emphasis>";
3251 font1 = font2 = getFont(-1);
3252 cell = table->CellHasContRow(current_cell_number);
3254 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3258 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3259 LyXParagraph::size_type const i,
3260 int & column, LyXFont const & font,
3261 LyXLayout const & style)
3263 if (column > tex_code_break_column
3265 && GetChar(i - 1) != ' '
3267 // In LaTeX mode, we don't want to
3268 // break lines since some commands
3270 && ! (font.latex() == LyXFont::ON)
3271 // same in FreeSpacing mode
3272 && !style.free_spacing
3273 // In typewriter mode, we want to avoid
3274 // ! . ? : at the end of a line
3275 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3276 && (GetChar(i-1) == '.'
3277 || GetChar(i-1) == '?'
3278 || GetChar(i-1) == ':'
3279 || GetChar(i-1) == '!'))) {
3280 if (tex_code_break_column == 0) {
3281 // in batchmode we need LaTeX to still
3282 // see it as a space not as an extra '\n'
3288 texrow.start(this, i+1);
3290 } else if (font.latex() == LyXFont::OFF) {
3291 if (style.free_spacing) {
3300 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3302 LyXFont & running_font,
3305 LyXLayout const & style,
3306 LyXParagraph::size_type & i,
3307 int & column, char const c)
3309 // Two major modes: LaTeX or plain
3310 // Handle here those cases common to both modes
3311 // and then split to handle the two modes separately.
3313 case LyXParagraph::META_INSET: {
3314 Inset * inset = GetInset(i);
3316 int len = file.length();
3317 int tmp = inset->Latex(file, style.isCommand());
3322 column += file.length() - len;
3331 case LyXParagraph::META_NEWLINE:
3333 column += running_font.latexWriteEndChanges(file,
3337 basefont = getFont(-1);
3338 running_font = basefont;
3341 case LyXParagraph::META_HFILL:
3342 file += "\\hfill{}";
3347 // And now for the special cases within each mode
3348 // Are we in LaTeX mode?
3349 if (font.latex() == LyXFont::ON) {
3350 // at present we only have one option
3351 // but I'll leave it as a switch statement
3352 // so its simpler to extend. (ARRae)
3354 case LyXParagraph::META_PROTECTED_SEPARATOR:
3359 // make sure that we will not print
3360 // error generating chars to the tex
3361 // file. This test would not be needed
3362 // if it were done in the buffer
3370 // Plain mode (i.e. not LaTeX)
3372 case LyXParagraph::META_PROTECTED_SEPARATOR:
3377 file += "\\textbackslash{}";
3381 case '°': case '±': case '²': case '³':
3382 case '×': case '÷': case '¹': case 'ª':
3383 case 'º': case '¬': case 'µ':
3384 if (current_view->buffer()->params.inputenc == "latin1") {
3385 file += "\\ensuremath{";
3394 case '|': case '<': case '>':
3395 // In T1 encoding, these characters exist
3396 if (lyxrc->fontenc == "T1") {
3398 //... but we should avoid ligatures
3399 if ((c == '>' || c == '<')
3401 && GetChar(i+1) == c){
3402 file += "\\textcompwordmark{}";
3407 // Typewriter font also has them
3408 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3412 // Otherwise, we use what LaTeX
3416 file += "\\textless{}";
3420 file += "\\textgreater{}";
3424 file += "\\textbar{}";
3430 case '-': // "--" in Typewriter mode -> "-{}-"
3432 && GetChar(i + 1) == '-'
3433 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3442 file += "\\char`\\\"{}";
3447 if (current_view->buffer()->params.inputenc == "default") {
3448 file += "\\pounds{}";
3456 case '%': case '#': case '{':
3464 file += "\\textasciitilde{}";
3469 file += "\\textasciicircum{}";
3473 case '*': case '[': case ']':
3474 // avoid being mistaken for optional arguments
3482 /* blanks are printed before font switching */
3483 // Sure? I am not! (try nice-latex)
3484 // I am sure it's correct. LyX might be smarter
3485 // in the future, but for now, nothing wrong is
3490 /* idea for labels --- begin*/
3494 && font.family() != LyXFont::TYPEWRITER_FAMILY
3495 && GetChar(i + 1) == 'y'
3496 && GetChar(i + 2) == 'X') {
3504 && font.family() != LyXFont::TYPEWRITER_FAMILY
3505 && GetChar(i + 1) == 'e'
3506 && GetChar(i + 2) == 'X') {
3511 /* check for LaTeX2e */
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 && GetChar(i + 5) == '2'
3520 && GetChar(i + 6) == 'e') {
3521 file += "\\LaTeXe{}";
3525 /* check for LaTeX */
3528 && font.family() != LyXFont::TYPEWRITER_FAMILY
3529 && GetChar(i + 1) == 'a'
3530 && GetChar(i + 2) == 'T'
3531 && GetChar(i + 3) == 'e'
3532 && GetChar(i + 4) == 'X') {
3533 file += "\\LaTeX{}";
3536 /* idea for labels --- end*/
3537 } else if (c != '\0') {
3547 bool LyXParagraph::RoffContTableRows(ostream & os,
3548 LyXParagraph::size_type i,
3554 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3559 string fname2 = TmpFileName(string(), "RAT2");
3561 int cell = table->CellHasContRow(actcell);
3564 // first find the right position
3566 for (; i < size() && actcell < cell; ++i) {
3568 if (c == LyXParagraph::META_NEWLINE)
3573 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3576 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3578 font2 = GetFontSettings(i);
3579 if (font1.latex() != font2.latex()) {
3580 if (font2.latex() != LyXFont::OFF)
3585 case LyXParagraph::META_INSET:
3586 if ((inset = GetInset(i))) {
3587 fstream fs(fname2.c_str(),
3590 WriteAlert(_("LYX_ERROR:"),
3591 _("Cannot open temporary file:"),
3595 inset->Latex(fs, -1);
3608 case LyXParagraph::META_NEWLINE:
3610 case LyXParagraph::META_HFILL:
3612 case LyXParagraph::META_PROTECTED_SEPARATOR:
3621 lyxerr.debug() << "RoffAsciiTable: "
3622 "NULL char in structure."
3627 cell = table->CellHasContRow(actcell);
3633 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3634 string & foot, TexRow & foot_texrow,
3637 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3638 LyXParagraph * par = this;
3640 while (par && par->depth == depth) {
3642 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3643 if (textclasslist.Style(GetCurrentTextClass(),
3644 par->layout).isEnvironment()
3645 || par->pextra_type != PEXTRA_NONE)
3647 par = par->TeXEnvironment(file, texrow,
3651 par = par->TeXOnePar(file, texrow,
3656 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3662 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3663 string & foot, TexRow & foot_texrow,
3666 bool eindent_open = false;
3667 bool foot_this_level = false;
3668 // flags when footnotetext should be appended to file.
3669 static bool minipage_open = false;
3670 static int minipage_open_depth = 0;
3671 char par_sep = current_view->buffer()->params.paragraph_separation;
3673 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3675 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3677 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3680 if (pextra_type == PEXTRA_INDENT) {
3681 if (!pextra_width.empty()) {
3682 file += "\\begin{LyXParagraphIndent}{"
3683 + pextra_width + "}\n";
3685 //float ib = atof(pextra_widthp.c_str())/100;
3686 // string can't handle floats at present (971109)
3687 // so I'll do a conversion by hand knowing that
3688 // the limits are 0.0 to 1.0. ARRae.
3689 file += "\\begin{LyXParagraphIndent}{";
3690 switch (pextra_widthp.length()) {
3696 file += pextra_widthp;
3700 file += pextra_widthp;
3702 file += "\\columnwidth}\n";
3705 eindent_open = true;
3707 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3708 if (pextra_hfill && Previous() &&
3709 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3710 file += "\\hfill{}\n";
3713 if (par_sep == BufferParams::PARSEP_INDENT) {
3714 file += "{\\setlength\\parindent{0pt}\n";
3717 file += "\\begin{minipage}";
3718 switch(pextra_alignment) {
3719 case MINIPAGE_ALIGN_TOP:
3722 case MINIPAGE_ALIGN_MIDDLE:
3725 case MINIPAGE_ALIGN_BOTTOM:
3729 if (!pextra_width.empty()) {
3731 file += pextra_width + "}\n";
3733 //float ib = atof(par->pextra_width.c_str())/100;
3734 // string can't handle floats at present
3735 // so I'll do a conversion by hand knowing that
3736 // the limits are 0.0 to 1.0. ARRae.
3738 switch (pextra_widthp.length()) {
3744 file += pextra_widthp;
3748 file += pextra_widthp;
3750 file += "\\columnwidth}\n";
3753 if (par_sep == BufferParams::PARSEP_INDENT) {
3754 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3757 minipage_open = true;
3758 minipage_open_depth = depth;
3761 #ifdef WITH_WARNINGS
3762 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3763 //I disabled it because it breaks when lists span on several
3766 if (style.isEnvironment()){
3767 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3768 #ifdef FANCY_FOOTNOTE_CODE
3769 if (foot_count < 0) {
3770 // flag that footnote[mark][text] should be
3771 // used for any footnotes from now on
3773 foot_this_level = true;
3776 file += "\\begin{" + style.latexname() + "}{"
3777 + labelwidthstring + "}\n";
3778 } else if (style.labeltype == LABEL_BIBLIO) {
3780 file += "\\begin{" + style.latexname() + "}{"
3781 + bibitemWidthest() + "}\n";
3782 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3783 #ifdef FANCY_FOOTNOTE_CODE
3784 if (foot_count < 0) {
3785 // flag that footnote[mark][text] should be
3786 // used for any footnotes from now on
3788 foot_this_level = true;
3791 file += "\\begin{" + style.latexname() + '}'
3792 + style.latexparam() + '\n';
3794 file += "\\begin{" + style.latexname() + '}'
3795 + style.latexparam() + '\n';
3798 LyXParagraph * par = this;
3800 par = par->TeXOnePar(file, texrow,
3801 foot, foot_texrow, foot_count);
3803 if (minipage_open && par && !style.isEnvironment() &&
3804 (par->pextra_type == PEXTRA_MINIPAGE) &&
3805 par->pextra_start_minipage) {
3806 file += "\\end{minipage}\n";
3808 if (par_sep == BufferParams::PARSEP_INDENT) {
3812 minipage_open = false;
3814 if (par && par->depth > depth) {
3815 if (textclasslist.Style(GetCurrentTextClass(),
3816 par->layout).isParagraph()
3818 && !suffixIs(file, "\n\n")) {
3819 // There should be at least one '\n' already
3820 // but we need there to be two for Standard
3821 // paragraphs that are depth-increment'ed to be
3822 // output correctly. However, tables can
3823 // also be paragraphs so don't adjust them.
3828 par = par->TeXDeeper(file, texrow,
3829 foot, foot_texrow, foot_count);
3831 if (par && par->layout == layout && par->depth == depth &&
3832 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3833 if (par->pextra_hfill && par->Previous() &&
3834 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3835 file += "\\hfill{}\n";
3838 if (par_sep == BufferParams::PARSEP_INDENT) {
3839 file += "{\\setlength\\parindent{0pt}\n";
3842 file += "\\begin{minipage}";
3843 switch(par->pextra_alignment) {
3844 case MINIPAGE_ALIGN_TOP:
3847 case MINIPAGE_ALIGN_MIDDLE:
3850 case MINIPAGE_ALIGN_BOTTOM:
3854 if (!par->pextra_width.empty()) {
3856 file += par->pextra_width;
3859 //float ib = atof(par->pextra_widthp.c_str())/100;
3860 // string can't handle floats at present
3861 // so I'll do a conversion by hand knowing that
3862 // the limits are 0.0 to 1.0. ARRae.
3864 switch (par->pextra_widthp.length()) {
3870 file += par->pextra_widthp;
3874 file += par->pextra_widthp;
3876 file += "\\columnwidth}\n";
3879 if (par_sep == BufferParams::PARSEP_INDENT) {
3880 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3883 minipage_open = true;
3884 minipage_open_depth = par->depth;
3887 && par->layout == layout
3888 && par->depth == depth
3889 && par->pextra_type == pextra_type);
3891 if (style.isEnvironment()) {
3892 file += "\\end{" + style.latexname() + '}';
3893 // maybe this should go after the minipage closes?
3894 if (foot_this_level) {
3895 if (foot_count >= 1) {
3896 if (foot_count > 1) {
3897 file += "\\addtocounter{footnote}{-";
3898 file += tostr(foot_count - 1);
3902 texrow += foot_texrow;
3904 foot_texrow.reset();
3909 if (minipage_open && (minipage_open_depth == depth) &&
3910 (!par || par->pextra_start_minipage ||
3911 par->pextra_type != PEXTRA_MINIPAGE)) {
3912 file += "\\end{minipage}\n";
3914 if (par_sep == BufferParams::PARSEP_INDENT) {
3918 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3919 file += "\\medskip\n\n";
3923 minipage_open = false;
3926 file += "\\end{LyXParagraphIndent}\n";
3929 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3930 && par->pextra_hfill)) {
3934 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3935 return par; // ale970302
3939 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3940 string & foot, TexRow & foot_texrow,
3943 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3944 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3945 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3946 "No footnote!" << endl;
3948 LyXParagraph * par = this;
3949 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3950 previous->GetLayout());
3952 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3953 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3954 "Float other than footnote in command"
3955 " with moving argument is illegal" << endl;
3958 if (footnotekind != LyXParagraph::FOOTNOTE
3959 && footnotekind != LyXParagraph::MARGIN
3961 && !suffixIs(file, '\n')) {
3962 // we need to ensure that real floats like tables and figures
3963 // have their \begin{} on a new line otherwise we can get
3964 // incorrect results when using the endfloat.sty package
3965 // especially if two floats follow one another. ARRae 981022
3966 // NOTE: if the file is length 0 it must have just been
3967 // written out so we assume it ended with a '\n'
3972 BufferParams * params = ¤t_view->buffer()->params;
3973 bool footer_in_body = true;
3974 switch (footnotekind) {
3975 case LyXParagraph::FOOTNOTE:
3976 if (style.intitle) {
3977 file += "\\thanks{\n";
3978 footer_in_body = false;
3980 if (foot_count == -1) {
3981 // we're at depth 0 so we can use:
3982 file += "\\footnote{%\n";
3983 footer_in_body = false;
3985 file += "\\footnotemark{}%\n";
3987 // we only need this when there are
3988 // multiple footnotes
3989 foot += "\\stepcounter{footnote}";
3991 foot += "\\footnotetext{%\n";
3992 foot_texrow.start(this, 0);
3993 foot_texrow.newline();
3998 case LyXParagraph::MARGIN:
3999 file += "\\marginpar{\n";
4001 case LyXParagraph::FIG:
4002 if (pextra_type == PEXTRA_FLOATFLT
4003 && (!pextra_width.empty()
4004 || !pextra_widthp.empty())) {
4006 if (!pextra_width.empty())
4007 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
4008 pextra_width.c_str());
4011 "\\begin{floatingfigure}{%f\\textwidth}\n",
4012 atoi(pextra_widthp.c_str())/100.0);
4015 file += "\\begin{figure}";
4016 if (!params->float_placement.empty()) {
4018 file += params->float_placement;
4025 case LyXParagraph::TAB:
4026 file += "\\begin{table}";
4027 if (!params->float_placement.empty()) {
4029 file += params->float_placement;
4035 case LyXParagraph::WIDE_FIG:
4036 file += "\\begin{figure*}";
4037 if (!params->float_placement.empty()) {
4039 file += params->float_placement;
4045 case LyXParagraph::WIDE_TAB:
4046 file += "\\begin{table*}";
4047 if (!params->float_placement.empty()) {
4049 file += params->float_placement;
4055 case LyXParagraph::ALGORITHM:
4056 file += "\\begin{algorithm}\n";
4061 if (footnotekind != LyXParagraph::FOOTNOTE
4062 || !footer_in_body) {
4063 // Process text for all floats except footnotes in body
4065 LyXLayout const & style =
4066 textclasslist.Style(GetCurrentTextClass(),
4069 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4071 if (style.isEnvironment()
4072 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4073 // Allows the use of minipages within float
4074 // environments. Shouldn't be circular because
4075 // we don't support footnotes inside
4076 // floats (yet). ARRae
4077 par = par->TeXEnvironment(file, texrow,
4081 par = par->TeXOnePar(file, texrow,
4086 if (par && !par->IsDummy() && par->depth > depth) {
4087 par = par->TeXDeeper(file, texrow,
4091 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4093 // process footnotes > depth 0 or in environments separately
4094 // NOTE: Currently don't support footnotes within footnotes
4095 // even though that is possible using the \footnotemark
4097 TexRow dummy_texrow;
4098 int dummy_count = 0;
4100 LyXLayout const & style =
4101 textclasslist.Style(GetCurrentTextClass(),
4104 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4106 if (style.isEnvironment()
4107 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4108 // Allows the use of minipages within float
4109 // environments. Shouldn't be circular because
4110 // we don't support footnotes inside
4111 // floats (yet). ARRae
4112 par = par->TeXEnvironment(foot, foot_texrow,
4113 dummy, dummy_texrow,
4116 par = par->TeXOnePar(foot, foot_texrow,
4117 dummy, dummy_texrow,
4121 if (par && !par->IsDummy() && par->depth > depth) {
4122 par = par->TeXDeeper(foot, foot_texrow,
4123 dummy, dummy_texrow,
4127 && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4129 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4130 "Footnote in a Footnote -- not supported"
4135 switch (footnotekind) {
4136 case LyXParagraph::FOOTNOTE:
4137 if (footer_in_body) {
4138 // This helps tell which of the multiple
4139 // footnotetexts an error was in.
4141 foot_texrow.newline();
4146 case LyXParagraph::MARGIN:
4149 case LyXParagraph::FIG:
4150 if (pextra_type == PEXTRA_FLOATFLT
4151 && (!pextra_width.empty()
4152 || !pextra_widthp.empty()))
4153 file += "\\end{floatingfigure}";
4155 file += "\\end{figure}";
4157 case LyXParagraph::TAB:
4158 file += "\\end{table}";
4160 case LyXParagraph::WIDE_FIG:
4161 file += "\\end{figure*}";
4163 case LyXParagraph::WIDE_TAB:
4164 file += "\\end{table*}";
4166 case LyXParagraph::ALGORITHM:
4167 file += "\\end{algorithm}";
4171 if (footnotekind != LyXParagraph::FOOTNOTE
4172 && footnotekind != LyXParagraph::MARGIN) {
4173 // we need to ensure that real floats like tables and figures
4174 // have their \end{} on a line of their own otherwise we can
4175 // get incorrect results when using the endfloat.sty package.
4180 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4185 void LyXParagraph::SetPExtraType(int type, char const * width,
4186 char const * widthp)
4189 pextra_width = width;
4190 pextra_widthp = widthp;
4192 if (textclasslist.Style(GetCurrentTextClass(),
4193 layout).isEnvironment()) {
4198 while (par && (par->layout == layout)
4199 && (par->depth == depth)) {
4201 par = par->Previous();
4203 par = par->FirstPhysicalPar();
4204 while (par && par->depth > depth) {
4205 par = par->Previous();
4207 par = par->FirstPhysicalPar();
4211 while (par && (par->layout == layout)
4212 && (par->depth == depth)) {
4213 par->pextra_type = type;
4214 par->pextra_width = width;
4215 par->pextra_widthp = widthp;
4216 par = par->NextAfterFootnote();
4217 if (par && (par->depth > depth))
4218 par->SetPExtraType(type, width, widthp);
4219 while (par && ((par->depth > depth) || par->IsDummy()))
4220 par = par->NextAfterFootnote();
4226 void LyXParagraph::UnsetPExtraType()
4228 if (pextra_type == PEXTRA_NONE)
4231 pextra_type = PEXTRA_NONE;
4232 pextra_width.clear();
4233 pextra_widthp.clear();
4235 if (textclasslist.Style(GetCurrentTextClass(),
4236 layout).isEnvironment()) {
4241 while (par && (par->layout == layout)
4242 && (par->depth == depth)) {
4244 par = par->Previous();
4246 par = par->FirstPhysicalPar();
4247 while (par && par->depth > depth) {
4248 par = par->Previous();
4250 par = par->FirstPhysicalPar();
4254 while (par && (par->layout == layout)
4255 && (par->depth == depth)) {
4256 par->pextra_type = PEXTRA_NONE;
4257 par->pextra_width.clear();
4258 par->pextra_widthp.clear();
4259 par = par->NextAfterFootnote();
4260 if (par && (par->depth > depth))
4261 par->UnsetPExtraType();
4262 while (par && ((par->depth > depth) || par->IsDummy()))
4263 par = par->NextAfterFootnote();
4269 bool LyXParagraph::IsHfill(size_type pos) const
4271 return IsHfillChar(GetChar(pos));
4275 bool LyXParagraph::IsInset(size_type pos) const
4277 return IsInsetChar(GetChar(pos));
4281 bool LyXParagraph::IsFloat(size_type pos) const
4283 return IsFloatChar(GetChar(pos));
4287 bool LyXParagraph::IsNewline(size_type pos) const
4291 tmp = IsNewlineChar(GetChar(pos));
4296 bool LyXParagraph::IsSeparator(size_type pos) const
4298 return IsSeparatorChar(GetChar(pos));
4302 bool LyXParagraph::IsLineSeparator(size_type pos) const
4304 return IsLineSeparatorChar(GetChar(pos));
4308 bool LyXParagraph::IsKomma(size_type pos) const
4310 return IsKommaChar(GetChar(pos));
4314 /// Used by the spellchecker
4315 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4317 unsigned char c = GetChar(pos);
4318 if (IsLetterChar(c))
4320 // '\0' is not a letter, allthough every string contains "" (below)
4323 // We want to pass the ' and escape chars to ispell
4324 string extra = lyxrc->isp_esc_chars + '\'';
4328 return contains(extra, ch);
4332 bool LyXParagraph::IsWord(size_type pos ) const
4334 return IsWordChar(GetChar(pos)) ;