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 outside font change.
2695 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2696 if (open_font && c == ' ' && i <= size() - 2
2697 && getFont(i+1) != running_font && getFont(i+1) != font) {
2698 font = getFont(i+1);
2701 // We end font definition before blanks
2702 if (font != running_font && open_font) {
2703 column += running_font.latexWriteEndChanges(file,
2705 running_font = basefont;
2708 // Blanks are printed before start of fontswitch
2710 SimpleTeXBlanks(file, texrow, i, column, font, style);
2712 // Do we need to change font?
2713 if (font != running_font) {
2714 column += font.latexWriteStartChanges(file, basefont);
2715 running_font = font;
2718 // Do we need to turn on LaTeX mode?
2719 if (font.latex() != running_font.latex()) {
2720 if (font.latex() == LyXFont::ON
2721 && style.needprotect) {
2722 file += "\\protect ";
2726 if (c == LyXParagraph::META_NEWLINE) {
2727 // special case for inside a table
2728 // different from default case in SimpleTeXSpecialChars()
2730 column += running_font.latexWriteEndChanges(file, basefont);
2733 basefont = getFont(-1);
2734 running_font = basefont;
2735 current_cell_number++;
2736 if (table->CellHasContRow(current_cell_number) >= 0) {
2737 TeXContTableRows(file, i+1,
2738 current_cell_number,
2741 // if this cell follow only ContRows till end don't
2742 // put the EndOfCell because it is put after the
2744 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2745 current_cell_number--;
2748 int tmp = table->TexEndOfCell(file,
2749 current_cell_number);
2752 } else if (tmp < 0) {
2758 texrow.start(this, i+1);
2760 SimpleTeXSpecialChars(file, texrow,
2761 font, running_font, basefont,
2762 open_font, style, i, column, c);
2766 // If we have an open font definition, we have to close it
2768 running_font.latexWriteEndChanges(file, basefont);
2770 current_cell_number++;
2771 tmp = table->TexEndOfCell(file, current_cell_number);
2772 for (; tmp > 0; --tmp)
2774 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2775 return return_value;
2779 // This one spits out the text off ContRows in tables
2780 bool LyXParagraph::TeXContTableRows(string & file,
2781 LyXParagraph::size_type i,
2782 int current_cell_number,
2783 int & column, TexRow & texrow)
2785 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2791 bool return_value = false;
2792 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2796 basefont = getFont(-1); // Get layout font
2797 // Which font is currently active?
2798 LyXFont running_font = basefont;
2799 // Do we have an open font change?
2800 bool open_font = false;
2802 size_type lastpos = i;
2803 int cell = table->CellHasContRow(current_cell_number);
2804 current_cell_number++;
2806 // first find the right position
2808 for (; (i < size()) && (current_cell_number<cell); ++i) {
2810 if (c == LyXParagraph::META_NEWLINE)
2811 current_cell_number++;
2815 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2819 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2823 for (; i < size() && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2827 // Fully instantiated font
2828 LyXFont font = getFont(i);
2830 // Spaces at end of font change are simulated to be outside font change.
2831 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2832 if (open_font && c == ' ' && i <= size() - 2
2833 && getFont(i + 1) != running_font
2834 && getFont(i + 1) != font) {
2835 font = getFont(i + 1);
2838 // We end font definition before blanks
2839 if (font != running_font && open_font) {
2840 column += running_font.latexWriteEndChanges(file, basefont);
2841 running_font = basefont;
2844 // Blanks are printed before start of fontswitch
2846 SimpleTeXBlanks(file, texrow, i,
2847 column, font, style);
2849 // Do we need to change font?
2850 if (font != running_font) {
2852 font.latexWriteStartChanges(file,
2854 running_font = font;
2857 // Do we need to turn on LaTeX mode?
2858 if (font.latex() != running_font.latex()) {
2859 if (font.latex() == LyXFont::ON
2860 && style.needprotect)
2862 file += "\\protect ";
2866 SimpleTeXSpecialChars(file, texrow, font,
2867 running_font, basefont,
2868 open_font, style, i, column, c);
2870 // If we have an open font definition, we have to close it
2872 running_font.latexWriteEndChanges(file, basefont);
2875 basefont = getFont(-1);
2876 running_font = basefont;
2877 cell = table->CellHasContRow(current_cell_number);
2879 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2880 return return_value;
2884 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2886 bool retval = false;
2888 case LyXParagraph::META_HFILL:
2889 sgml_string.clear();
2891 case LyXParagraph::META_PROTECTED_SEPARATOR:
2894 case LyXParagraph::META_NEWLINE:
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 = """;
2934 sgml_string = "\";
2940 case '\0': /* Ignore :-) */
2941 sgml_string.clear();
2950 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2951 int & desc_on, int depth)
2955 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2957 int current_cell_number = -1;
2958 LyXFont font1, font2;
2961 size_type main_body;
2962 string emph = "emphasis";
2963 bool emph_flag= false;
2964 int char_line_count= 0;
2966 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2968 if (style.labeltype != LABEL_MANUAL)
2971 main_body = BeginningOfMainBody();
2973 /* gets paragraph main font */
2975 font1 = style.labelfont;
2979 char_line_count = depth;
2980 addNewlineAndDepth(file, depth);
2981 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2982 file += "<INFORMALTABLE>";
2983 addNewlineAndDepth(file, ++depth);
2985 current_cell_number = -1;
2986 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2988 /* parsing main loop */
2989 for (size_type i = 0; i < size(); ++i) {
2991 if (table->IsContRow(current_cell_number+1)) {
2992 if (c == LyXParagraph::META_NEWLINE)
2993 current_cell_number++;
2998 // Fully instantiated font
3001 /* handle <emphasis> tag */
3002 if (font1.emph() != font2.emph() && i) {
3003 if (font2.emph() == LyXFont::ON) {
3004 file += "<emphasis>";
3006 } else if (emph_flag) {
3007 file += "</emphasis>";
3011 if (c == LyXParagraph::META_NEWLINE) {
3012 // we have only to control for emphasis open here!
3014 file += "</emphasis>";
3017 font1 = font2 = getFont(-1);
3018 current_cell_number++;
3019 if (table->CellHasContRow(current_cell_number) >= 0) {
3020 DocBookContTableRows(file, extra, desc_on, i+1,
3021 current_cell_number,
3024 // if this cell follow only ContRows till end don't
3025 // put the EndOfCell because it is put after the
3027 if (table->ShouldBeVeryLastCell(current_cell_number)) {
3028 current_cell_number--;
3031 tmp= table->DocBookEndOfCell(file, current_cell_number,
3036 } else if (c == LyXParagraph::META_INSET) {
3037 inset = GetInset(i);
3039 inset->DocBook(tmp_out);
3041 // This code needs some explanation:
3042 // Two insets are treated specially
3043 // label if it is the first element in a command paragraph
3045 // graphics inside tables or figure floats can't go on
3046 // title (the equivalente in latex for this case is caption
3047 // and title should come first
3050 if(desc_on != 3 || i != 0) {
3051 if(tmp_out[0] == '@') {
3053 extra += frontStrip(tmp_out, '@');
3055 file += frontStrip(tmp_out, '@');
3059 } else if (font2.latex() == LyXFont::ON) {
3060 // "TeX"-Mode on == > SGML-Mode on.
3066 if (linuxDocConvertChar(c, sgml_string)
3067 && !style.free_spacing) {
3068 // in freespacing mode, spaces are
3069 // non-breaking characters
3074 file += "</term><listitem><para>";
3080 file += sgml_string;
3086 /* needed if there is an optional argument but no contents */
3087 if (main_body > 0 && main_body == size()) {
3092 file += "</emphasis>";
3095 current_cell_number++;
3096 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3097 /* resets description flag correctly */
3100 /* <term> not closed... */
3104 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3105 file += "</INFORMALTABLE>";
3107 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3112 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3113 int & desc_on, LyXParagraph::size_type i,
3114 int current_cell_number, int &column)
3120 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3123 LyXFont font1, font2;
3126 size_type main_body;
3128 string emph= "emphasis";
3129 bool emph_flag= false;
3130 int char_line_count= 0;
3132 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3135 if (style.labeltype != LABEL_MANUAL)
3138 main_body = BeginningOfMainBody();
3140 /* gets paragraph main font */
3142 font1 = style.labelfont;
3147 cell = table->CellHasContRow(current_cell_number);
3148 current_cell_number++;
3150 // first find the right position
3152 for (; i < size() && current_cell_number < cell; ++i) {
3154 if (c == LyXParagraph::META_NEWLINE)
3155 current_cell_number++;
3159 // I don't know how to handle this so I comment it
3160 // for the moment (Jug)
3161 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3162 // file += " \\\\\n";
3165 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3170 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3174 // Fully instantiated font
3177 /* handle <emphasis> tag */
3178 if (font1.emph() != font2.emph() && i) {
3179 if (font2.emph() == LyXFont::ON) {
3180 file += "<emphasis>";
3182 } else if (emph_flag) {
3183 file += "</emphasis>";
3187 if (c == LyXParagraph::META_INSET) {
3188 inset = GetInset(i);
3190 inset->DocBook(tmp_out);
3192 // This code needs some explanation:
3193 // Two insets are treated specially
3194 // label if it is the first element in a command paragraph
3196 // graphics inside tables or figure floats can't go on
3197 // title (the equivalente in latex for this case is caption
3198 // and title should come first
3201 if(desc_on != 3 || i != 0) {
3202 if(tmp_out[0] == '@') {
3204 extra += frontStrip(tmp_out, '@');
3206 file += frontStrip(tmp_out, '@');
3210 } else if (font2.latex() == LyXFont::ON) {
3211 // "TeX"-Mode on == > SGML-Mode on.
3217 if (linuxDocConvertChar(c, sgml_string)
3218 && !style.free_spacing) {
3219 // in freespacing mode, spaces are
3220 // non-breaking characters
3225 file += "</term><listitem><para>";
3231 file += sgml_string;
3235 // we have only to control for emphasis open here!
3237 file += "</emphasis>";
3240 font1 = font2 = getFont(-1);
3241 cell = table->CellHasContRow(current_cell_number);
3243 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3246 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3247 LyXParagraph::size_type const i,
3248 int & column, LyXFont const & font,
3249 LyXLayout const & style)
3251 if (column > tex_code_break_column
3253 && GetChar(i - 1) != ' '
3255 // In LaTeX mode, we don't want to
3256 // break lines since some commands
3258 && ! (font.latex() == LyXFont::ON)
3259 // same in FreeSpacing mode
3260 && !style.free_spacing
3261 // In typewriter mode, we want to avoid
3262 // ! . ? : at the end of a line
3263 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3264 && (GetChar(i-1) == '.'
3265 || GetChar(i-1) == '?'
3266 || GetChar(i-1) == ':'
3267 || GetChar(i-1) == '!'))) {
3268 if (tex_code_break_column == 0) {
3269 // in batchmode we need LaTeX to still
3270 // see it as a space not as an extra '\n'
3276 texrow.start(this, i+1);
3278 } else if (font.latex() == LyXFont::OFF) {
3279 if (style.free_spacing) {
3288 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3290 LyXFont & running_font,
3293 LyXLayout const & style,
3294 LyXParagraph::size_type & i,
3295 int & column, char const c)
3297 // Two major modes: LaTeX or plain
3298 // Handle here those cases common to both modes
3299 // and then split to handle the two modes separately.
3301 case LyXParagraph::META_INSET: {
3302 Inset * inset = GetInset(i);
3304 int len = file.length();
3305 int tmp = inset->Latex(file, style.isCommand());
3310 column += file.length() - len;
3319 case LyXParagraph::META_NEWLINE:
3321 column += running_font.latexWriteEndChanges(file,
3325 basefont = getFont(-1);
3326 running_font = basefont;
3329 case LyXParagraph::META_HFILL:
3330 file += "\\hfill{}";
3335 // And now for the special cases within each mode
3336 // Are we in LaTeX mode?
3337 if (font.latex() == LyXFont::ON) {
3338 // at present we only have one option
3339 // but I'll leave it as a switch statement
3340 // so its simpler to extend. (ARRae)
3342 case LyXParagraph::META_PROTECTED_SEPARATOR:
3347 // make sure that we will not print
3348 // error generating chars to the tex
3349 // file. This test would not be needed
3350 // if it were done in the buffer
3358 // Plain mode (i.e. not LaTeX)
3360 case LyXParagraph::META_PROTECTED_SEPARATOR:
3365 file += "\\textbackslash{}";
3369 case '°': case '±': case '²': case '³':
3370 case '×': case '÷': case '¹': case 'ª':
3371 case 'º': case '¬': case 'µ':
3372 if (current_view->buffer()->params.inputenc == "latin1") {
3373 file += "\\ensuremath{";
3382 case '|': case '<': case '>':
3383 // In T1 encoding, these characters exist
3384 if (lyxrc->fontenc == "T1") {
3386 //... but we should avoid ligatures
3387 if ((c == '>' || c == '<')
3389 && GetChar(i+1) == c){
3390 file += "\\textcompwordmark{}";
3395 // Typewriter font also has them
3396 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3400 // Otherwise, we use what LaTeX
3404 file += "\\textless{}";
3408 file += "\\textgreater{}";
3412 file += "\\textbar{}";
3418 case '-': // "--" in Typewriter mode -> "-{}-"
3420 && GetChar(i + 1) == '-'
3421 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3430 file += "\\char`\\\"{}";
3435 if (current_view->buffer()->params.inputenc == "default") {
3436 file += "\\pounds{}";
3444 case '%': case '#': case '{':
3452 file += "\\textasciitilde{}";
3457 file += "\\textasciicircum{}";
3461 case '*': case '[': case ']':
3462 // avoid being mistaken for optional arguments
3470 /* blanks are printed before font switching */
3471 // Sure? I am not! (try nice-latex)
3472 // I am sure it's correct. LyX might be smarter
3473 // in the future, but for now, nothing wrong is
3478 /* idea for labels --- begin*/
3482 && font.family() != LyXFont::TYPEWRITER_FAMILY
3483 && GetChar(i + 1) == 'y'
3484 && GetChar(i + 2) == 'X') {
3492 && font.family() != LyXFont::TYPEWRITER_FAMILY
3493 && GetChar(i + 1) == 'e'
3494 && GetChar(i + 2) == 'X') {
3499 /* check for LaTeX2e */
3502 && font.family() != LyXFont::TYPEWRITER_FAMILY
3503 && GetChar(i + 1) == 'a'
3504 && GetChar(i + 2) == 'T'
3505 && GetChar(i + 3) == 'e'
3506 && GetChar(i + 4) == 'X'
3507 && GetChar(i + 5) == '2'
3508 && GetChar(i + 6) == 'e') {
3509 file += "\\LaTeXe{}";
3513 /* check for LaTeX */
3516 && font.family() != LyXFont::TYPEWRITER_FAMILY
3517 && GetChar(i + 1) == 'a'
3518 && GetChar(i + 2) == 'T'
3519 && GetChar(i + 3) == 'e'
3520 && GetChar(i + 4) == 'X') {
3521 file += "\\LaTeX{}";
3524 /* idea for labels --- end*/
3525 } else if (c != '\0') {
3535 bool LyXParagraph::RoffContTableRows(ostream & os,
3536 LyXParagraph::size_type i,
3542 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3547 string fname2 = TmpFileName(string(), "RAT2");
3549 int cell = table->CellHasContRow(actcell);
3552 // first find the right position
3554 for (; i < size() && actcell < cell; ++i) {
3556 if (c == LyXParagraph::META_NEWLINE)
3561 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3564 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3566 font2 = GetFontSettings(i);
3567 if (font1.latex() != font2.latex()) {
3568 if (font2.latex() != LyXFont::OFF)
3573 case LyXParagraph::META_INSET:
3574 if ((inset = GetInset(i))) {
3575 fstream fs(fname2.c_str(), ios::in|ios::out);
3577 WriteAlert(_("LYX_ERROR:"),
3578 _("Cannot open temporary file:"),
3582 inset->Latex(fs, -1);
3595 case LyXParagraph::META_NEWLINE:
3597 case LyXParagraph::META_HFILL:
3599 case LyXParagraph::META_PROTECTED_SEPARATOR:
3608 lyxerr.debug() << "RoffAsciiTable: NULL char in structure." << endl;
3612 cell = table->CellHasContRow(actcell);
3618 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3619 string & foot, TexRow & foot_texrow,
3622 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3623 LyXParagraph * par = this;
3625 while (par && par->depth == depth) {
3627 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3628 if (textclasslist.Style(GetCurrentTextClass(),
3629 par->layout).isEnvironment()
3630 || par->pextra_type != PEXTRA_NONE)
3632 par = par->TeXEnvironment(file, texrow,
3636 par = par->TeXOnePar(file, texrow,
3641 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3647 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3648 string & foot, TexRow & foot_texrow,
3651 bool eindent_open = false;
3652 bool foot_this_level = false;
3653 // flags when footnotetext should be appended to file.
3654 static bool minipage_open = false;
3655 static int minipage_open_depth = 0;
3656 char par_sep = current_view->buffer()->params.paragraph_separation;
3658 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3660 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3662 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3665 if (pextra_type == PEXTRA_INDENT) {
3666 if (!pextra_width.empty()) {
3667 file += "\\begin{LyXParagraphIndent}{"
3668 + pextra_width + "}\n";
3670 //float ib = atof(pextra_widthp.c_str())/100;
3671 // string can't handle floats at present (971109)
3672 // so I'll do a conversion by hand knowing that
3673 // the limits are 0.0 to 1.0. ARRae.
3674 file += "\\begin{LyXParagraphIndent}{";
3675 switch (pextra_widthp.length()) {
3681 file += pextra_widthp;
3685 file += pextra_widthp;
3687 file += "\\columnwidth}\n";
3690 eindent_open = true;
3692 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3693 if (pextra_hfill && Previous() &&
3694 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3695 file += "\\hfill{}\n";
3698 if (par_sep == BufferParams::PARSEP_INDENT) {
3699 file += "{\\setlength\\parindent{0pt}\n";
3702 file += "\\begin{minipage}";
3703 switch(pextra_alignment) {
3704 case MINIPAGE_ALIGN_TOP:
3707 case MINIPAGE_ALIGN_MIDDLE:
3710 case MINIPAGE_ALIGN_BOTTOM:
3714 if (!pextra_width.empty()) {
3716 file += pextra_width + "}\n";
3718 //float ib = atof(par->pextra_width.c_str())/100;
3719 // string can't handle floats at present
3720 // so I'll do a conversion by hand knowing that
3721 // the limits are 0.0 to 1.0. ARRae.
3723 switch (pextra_widthp.length()) {
3729 file += pextra_widthp;
3733 file += pextra_widthp;
3735 file += "\\columnwidth}\n";
3738 if (par_sep == BufferParams::PARSEP_INDENT) {
3739 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3742 minipage_open = true;
3743 minipage_open_depth = depth;
3746 #ifdef WITH_WARNINGS
3747 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3748 //I disabled it because it breaks when lists span on several
3751 if (style.isEnvironment()){
3752 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3753 #ifdef FANCY_FOOTNOTE_CODE
3754 if (foot_count < 0) {
3755 // flag that footnote[mark][text] should be
3756 // used for any footnotes from now on
3758 foot_this_level = true;
3761 file += "\\begin{" + style.latexname() + "}{"
3762 + labelwidthstring + "}\n";
3763 } else if (style.labeltype == LABEL_BIBLIO) {
3765 file += "\\begin{" + style.latexname() + "}{"
3766 + bibitemWidthest() + "}\n";
3767 } else if (style.latextype == LATEX_ITEM_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 + style.latexparam() + '\n';
3779 file += "\\begin{" + style.latexname() + '}'
3780 + style.latexparam() + '\n';
3783 LyXParagraph * par = this;
3785 par = par->TeXOnePar(file, texrow,
3786 foot, foot_texrow, foot_count);
3788 if (minipage_open && par && !style.isEnvironment() &&
3789 (par->pextra_type == PEXTRA_MINIPAGE) &&
3790 par->pextra_start_minipage) {
3791 file += "\\end{minipage}\n";
3793 if (par_sep == BufferParams::PARSEP_INDENT) {
3797 minipage_open = false;
3799 if (par && par->depth > depth) {
3800 if (textclasslist.Style(GetCurrentTextClass(),
3801 par->layout).isParagraph()
3803 && !suffixIs(file, "\n\n")) {
3804 // There should be at least one '\n' already
3805 // but we need there to be two for Standard
3806 // paragraphs that are depth-increment'ed to be
3807 // output correctly. However, tables can also be
3808 // paragraphs so don't adjust them. ARRae
3812 par = par->TeXDeeper(file, texrow,
3813 foot, foot_texrow, foot_count);
3815 if (par && par->layout == layout && par->depth == depth &&
3816 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3817 if (par->pextra_hfill && par->Previous() &&
3818 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3819 file += "\\hfill{}\n";
3822 if (par_sep == BufferParams::PARSEP_INDENT) {
3823 file += "{\\setlength\\parindent{0pt}\n";
3826 file += "\\begin{minipage}";
3827 switch(par->pextra_alignment) {
3828 case MINIPAGE_ALIGN_TOP:
3831 case MINIPAGE_ALIGN_MIDDLE:
3834 case MINIPAGE_ALIGN_BOTTOM:
3838 if (!par->pextra_width.empty()) {
3840 file += par->pextra_width;
3843 //float ib = atof(par->pextra_widthp.c_str())/100;
3844 // string can't handle floats at present
3845 // so I'll do a conversion by hand knowing that
3846 // the limits are 0.0 to 1.0. ARRae.
3848 switch (par->pextra_widthp.length()) {
3854 file += par->pextra_widthp;
3858 file += par->pextra_widthp;
3860 file += "\\columnwidth}\n";
3863 if (par_sep == BufferParams::PARSEP_INDENT) {
3864 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3867 minipage_open = true;
3868 minipage_open_depth = par->depth;
3871 && par->layout == layout
3872 && par->depth == depth
3873 && par->pextra_type == pextra_type);
3875 if (style.isEnvironment()) {
3876 file += "\\end{" + style.latexname() + '}';
3877 // maybe this should go after the minipage closes?
3878 if (foot_this_level) {
3879 if (foot_count >= 1) {
3880 if (foot_count > 1) {
3881 file += "\\addtocounter{footnote}{-";
3882 file += tostr(foot_count - 1);
3886 texrow += foot_texrow;
3888 foot_texrow.reset();
3893 if (minipage_open && (minipage_open_depth == depth) &&
3894 (!par || par->pextra_start_minipage ||
3895 par->pextra_type != PEXTRA_MINIPAGE)) {
3896 file += "\\end{minipage}\n";
3898 if (par_sep == BufferParams::PARSEP_INDENT) {
3902 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3903 file += "\\medskip\n\n";
3907 minipage_open = false;
3910 file += "\\end{LyXParagraphIndent}\n";
3913 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3914 && par->pextra_hfill)) {
3918 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3919 return par; // ale970302
3923 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3924 string & foot, TexRow & foot_texrow,
3927 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3928 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3929 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3930 "No footnote!" << endl;
3932 LyXParagraph * par = this;
3933 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3934 previous->GetLayout());
3936 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3937 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3938 "Float other than footnote in command"
3939 " with moving argument is illegal" << endl;
3942 if (footnotekind != LyXParagraph::FOOTNOTE
3943 && footnotekind != LyXParagraph::MARGIN
3945 && !suffixIs(file, '\n')) {
3946 // we need to ensure that real floats like tables and figures
3947 // have their \begin{} on a new line otherwise we can get
3948 // incorrect results when using the endfloat.sty package
3949 // especially if two floats follow one another. ARRae 981022
3950 // NOTE: if the file is length 0 it must have just been
3951 // written out so we assume it ended with a '\n'
3956 BufferParams * params = ¤t_view->buffer()->params;
3957 bool footer_in_body = true;
3958 switch (footnotekind) {
3959 case LyXParagraph::FOOTNOTE:
3960 if (style.intitle) {
3961 file += "\\thanks{\n";
3962 footer_in_body = false;
3964 if (foot_count == -1) {
3965 // we're at depth 0 so we can use:
3966 file += "\\footnote{%\n";
3967 footer_in_body = false;
3969 file += "\\footnotemark{}%\n";
3971 // we only need this when there are
3972 // multiple footnotes
3973 foot += "\\stepcounter{footnote}";
3975 foot += "\\footnotetext{%\n";
3976 foot_texrow.start(this, 0);
3977 foot_texrow.newline();
3982 case LyXParagraph::MARGIN:
3983 file += "\\marginpar{\n";
3985 case LyXParagraph::FIG:
3986 if (pextra_type == PEXTRA_FLOATFLT
3987 && (!pextra_width.empty()
3988 || !pextra_widthp.empty())) {
3990 if (!pextra_width.empty())
3991 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3992 pextra_width.c_str());
3994 sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
3995 atoi(pextra_widthp.c_str())/100.0);
3998 file += "\\begin{figure}";
3999 if (!params->float_placement.empty()) {
4001 file += params->float_placement;
4008 case LyXParagraph::TAB:
4009 file += "\\begin{table}";
4010 if (!params->float_placement.empty()) {
4012 file += params->float_placement;
4018 case LyXParagraph::WIDE_FIG:
4019 file += "\\begin{figure*}";
4020 if (!params->float_placement.empty()) {
4022 file += params->float_placement;
4028 case LyXParagraph::WIDE_TAB:
4029 file += "\\begin{table*}";
4030 if (!params->float_placement.empty()) {
4032 file += params->float_placement;
4038 case LyXParagraph::ALGORITHM:
4039 file += "\\begin{algorithm}\n";
4044 if (footnotekind != LyXParagraph::FOOTNOTE
4045 || !footer_in_body) {
4046 // Process text for all floats except footnotes in body
4048 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
4051 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4053 if (style.isEnvironment()
4054 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4055 // Allows the use of minipages within float environments.
4056 // Shouldn't be circular because we don't support
4057 // footnotes inside floats (yet). ARRae
4058 par = par->TeXEnvironment(file, texrow,
4062 par = par->TeXOnePar(file, texrow,
4067 if (par && !par->IsDummy() && par->depth > depth) {
4068 par = par->TeXDeeper(file, texrow,
4072 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4074 // process footnotes > depth 0 or in environments separately
4075 // NOTE: Currently don't support footnotes within footnotes
4076 // even though that is possible using the \footnotemark
4078 TexRow dummy_texrow;
4079 int dummy_count = 0;
4081 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
4084 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4086 if (style.isEnvironment()
4087 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4088 // Allows the use of minipages within float environments.
4089 // Shouldn't be circular because we don't support
4090 // footnotes inside floats (yet). ARRae
4091 par = par->TeXEnvironment(foot, foot_texrow,
4092 dummy, dummy_texrow,
4095 par = par->TeXOnePar(foot, foot_texrow,
4096 dummy, dummy_texrow,
4100 if (par && !par->IsDummy() && par->depth > depth) {
4101 par = par->TeXDeeper(foot, foot_texrow,
4102 dummy, dummy_texrow,
4105 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4107 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4108 "Footnote in a Footnote -- not supported"
4113 switch (footnotekind) {
4114 case LyXParagraph::FOOTNOTE:
4115 if (footer_in_body) {
4116 // This helps tell which of the multiple
4117 // footnotetexts an error was in.
4119 foot_texrow.newline();
4124 case LyXParagraph::MARGIN:
4127 case LyXParagraph::FIG:
4128 if (pextra_type == PEXTRA_FLOATFLT
4129 && (!pextra_width.empty()
4130 || !pextra_widthp.empty()))
4131 file += "\\end{floatingfigure}";
4133 file += "\\end{figure}";
4135 case LyXParagraph::TAB:
4136 file += "\\end{table}";
4138 case LyXParagraph::WIDE_FIG:
4139 file += "\\end{figure*}";
4141 case LyXParagraph::WIDE_TAB:
4142 file += "\\end{table*}";
4144 case LyXParagraph::ALGORITHM:
4145 file += "\\end{algorithm}";
4149 if (footnotekind != LyXParagraph::FOOTNOTE
4150 && footnotekind != LyXParagraph::MARGIN) {
4151 // we need to ensure that real floats like tables and figures
4152 // have their \end{} on a line of their own otherwise we can
4153 // get incorrect results when using the endfloat.sty package.
4158 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4163 void LyXParagraph::SetPExtraType(int type, char const * width,
4164 char const * widthp)
4167 pextra_width = width;
4168 pextra_widthp = widthp;
4170 if (textclasslist.Style(GetCurrentTextClass(),
4171 layout).isEnvironment()) {
4176 while (par && (par->layout == layout) && (par->depth == depth)) {
4178 par = par->Previous();
4180 par = par->FirstPhysicalPar();
4181 while (par && par->depth > depth) {
4182 par = par->Previous();
4184 par = par->FirstPhysicalPar();
4188 while (par && (par->layout == layout) && (par->depth == depth)) {
4189 par->pextra_type = type;
4190 par->pextra_width = width;
4191 par->pextra_widthp = widthp;
4192 par = par->NextAfterFootnote();
4193 if (par && (par->depth > depth))
4194 par->SetPExtraType(type, width, widthp);
4195 while (par && ((par->depth > depth) || par->IsDummy()))
4196 par = par->NextAfterFootnote();
4202 void LyXParagraph::UnsetPExtraType()
4204 if (pextra_type == PEXTRA_NONE)
4207 pextra_type = PEXTRA_NONE;
4208 pextra_width.clear();
4209 pextra_widthp.clear();
4211 if (textclasslist.Style(GetCurrentTextClass(),
4212 layout).isEnvironment()) {
4217 while (par && (par->layout == layout) && (par->depth == depth)) {
4219 par = par->Previous();
4221 par = par->FirstPhysicalPar();
4222 while (par && par->depth > depth) {
4223 par = par->Previous();
4225 par = par->FirstPhysicalPar();
4229 while (par && (par->layout == layout) && (par->depth == depth)) {
4230 par->pextra_type = PEXTRA_NONE;
4231 par->pextra_width.clear();
4232 par->pextra_widthp.clear();
4233 par = par->NextAfterFootnote();
4234 if (par && (par->depth > depth))
4235 par->UnsetPExtraType();
4236 while (par && ((par->depth > depth) || par->IsDummy()))
4237 par = par->NextAfterFootnote();
4243 bool LyXParagraph::IsHfill(size_type pos) const
4245 return IsHfillChar(GetChar(pos));
4249 bool LyXParagraph::IsInset(size_type pos) const
4251 return IsInsetChar(GetChar(pos));
4255 bool LyXParagraph::IsFloat(size_type pos) const
4257 return IsFloatChar(GetChar(pos));
4261 bool LyXParagraph::IsNewline(size_type pos) const
4265 tmp = IsNewlineChar(GetChar(pos));
4270 bool LyXParagraph::IsSeparator(size_type pos) const
4272 return IsSeparatorChar(GetChar(pos));
4276 bool LyXParagraph::IsLineSeparator(size_type pos) const
4278 return IsLineSeparatorChar(GetChar(pos));
4282 bool LyXParagraph::IsKomma(size_type pos) const
4284 return IsKommaChar(GetChar(pos));
4288 /// Used by the spellchecker
4289 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4291 unsigned char c = GetChar(pos);
4292 if (IsLetterChar(c))
4294 // '\0' is not a letter, allthough every string contains "" (below)
4297 // We want to pass the ' and escape chars to ispell
4298 string extra = lyxrc->isp_esc_chars + '\'';
4302 return contains(extra, ch);
4306 bool LyXParagraph::IsWord(size_type pos ) const
4308 return IsWordChar( GetChar(pos) ) ;