1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
14 #pragma implementation "lyxparagraph.h"
21 #include "lyxparagraph.h"
22 #include "support/textutils.h"
25 #include "tex-strings.h"
26 #include "bufferparams.h"
27 #include "support/FileInfo.h"
28 #include "support/LAssert.h"
30 #include "LaTeXFeatures.h"
31 #include "insets/insetinclude.h"
32 #include "support/filetools.h"
33 #include "lyx_gui_misc.h"
37 extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
38 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(current_view->buffer()->params.textclass,
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(current_view->buffer()->params.textclass,
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(current_view->buffer()->params.textclass,
986 par->GetLayout()).font);
987 par_depth = par->GetDepth();
991 tmpfont.realize(textclasslist.TextClass(current_view->buffer()->params.textclass).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)
1031 /* > because last is the next unused position, and you can
1032 * use it if you want */
1033 else if (pos > size()) {
1034 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1035 return NextAfterFootnote()
1036 ->GetChar(pos - text.size() - 1);
1038 lyxerr << "ERROR (LyXParagraph::GetChar): "
1039 "position does not exist."
1040 << pos << " (" << static_cast<int>(pos)
1045 /* we should have a footnote environment */
1046 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1047 // Notice that LyX does request the
1048 // last char from time to time. (Asger)
1049 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1050 // "expected footnote." << endl;
1053 switch (next->footnotekind) {
1054 case LyXParagraph::FOOTNOTE:
1055 return LyXParagraph::META_FOOTNOTE;
1056 case LyXParagraph::MARGIN:
1057 return LyXParagraph::META_MARGIN;
1058 case LyXParagraph::FIG:
1059 case LyXParagraph::WIDE_FIG:
1060 return LyXParagraph::META_FIG;
1061 case LyXParagraph::TAB:
1062 case LyXParagraph::WIDE_TAB:
1063 return LyXParagraph::META_TAB;
1064 case LyXParagraph::ALGORITHM:
1065 return LyXParagraph::META_ALGORITHM;
1067 return '\0'; // to shut up gcc
1072 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1079 /* > because last is the next unused position, and you can
1080 * use it if you want */
1081 else if (pos > size()) {
1082 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1083 return NextAfterFootnote()
1084 ->GetChar(pos - text.size() - 1);
1086 lyxerr << "ERROR (LyXParagraph::GetChar): "
1087 "position does not exist."
1088 << pos << " (" << static_cast<int>(pos)
1093 /* we should have a footnote environment */
1094 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1095 // Notice that LyX does request the
1096 // last char from time to time. (Asger)
1097 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1098 // "expected footnote." << endl;
1101 switch (next->footnotekind) {
1102 case LyXParagraph::FOOTNOTE:
1103 return LyXParagraph::META_FOOTNOTE;
1104 case LyXParagraph::MARGIN:
1105 return LyXParagraph::META_MARGIN;
1106 case LyXParagraph::FIG:
1107 case LyXParagraph::WIDE_FIG:
1108 return LyXParagraph::META_FIG;
1109 case LyXParagraph::TAB:
1110 case LyXParagraph::WIDE_TAB:
1111 return LyXParagraph::META_TAB;
1112 case LyXParagraph::ALGORITHM:
1113 return LyXParagraph::META_ALGORITHM;
1115 return '\0'; // to shut up gcc
1120 // return an string of the current word, and the end of the word in lastpos.
1121 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1125 // the current word is defined as starting at the first character from
1126 // the immediate left of lastpospos which meets the definition of IsLetter(),
1127 // continuing to the last character to the right of this meeting
1134 // move back until we have a letter
1136 //there's no real reason to have firstpos & lastpos as
1137 //separate variables as this is written, but maybe someon
1138 // will want to return firstpos in the future.
1140 //since someone might have typed a punctuation first
1141 int firstpos = lastpos;
1143 while ((firstpos >= 0) && !IsLetter(firstpos))
1146 // now find the beginning by looking for a nonletter
1148 while ((firstpos>= 0) && IsLetter(firstpos))
1151 // the above is now pointing to the preceeding non-letter
1155 // so copy characters into theword until we get a nonletter
1156 // note that this can easily exceed lastpos, wich means
1157 // that if used in the middle of a word, the whole word
1160 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1167 LyXParagraph::size_type LyXParagraph::Last() const
1169 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1170 return text.size() + NextAfterFootnote()->Last() + 1;
1171 /* the 1 is the symbol
1178 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1180 /* > because last is the next unused position, and you can
1181 * use it if you want */
1184 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1185 return NextAfterFootnote()
1186 ->ParFromPos(pos - text.size() - 1);
1188 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1189 "position does not exist." << endl;
1197 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1199 /* > because last is the next unused position, and you can
1200 * use it if you want */
1203 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1204 return NextAfterFootnote()
1205 ->PositionInParFromPos(pos - text.size() - 1);
1208 "ERROR (LyXParagraph::PositionInParFromPos): "
1209 "position does not exist." << endl;
1217 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1218 LyXFont const & font)
1220 /* > because last is the next unused position, and you can
1221 * use it if you want */
1223 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1224 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1227 lyxerr << "ERROR (LyXParagraph::SetFont): "
1228 "position does not exist." << endl;
1232 LyXFont patternfont(LyXFont::ALL_INHERIT);
1234 // First, reduce font against layout/label font
1235 // Update: The SetCharFont() routine in text2.C already reduces font, so
1236 // we don't need to do that here. (Asger)
1237 // No need to simplify this because it will disappear in a new kernel. (Asger)
1239 // Next search font table
1240 for(FontList::iterator it = fontlist.begin();
1241 it != fontlist.end(); ++it) {
1242 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1244 // we found a font entry. maybe we have to
1245 // split it and create a new one
1247 if ((*it).pos != (*it).pos_end) {
1248 // more than one character
1249 if (pos == (*it).pos) {
1250 // maybe we could enlarge
1251 // the left fonttable
1252 for(FontList::iterator fit = fontlist.begin();
1253 fit != fontlist.end(); ++fit) {
1254 if (pos - 1 >= (*fit).pos
1255 && pos - 1 <= (*fit).pos_end
1256 && (*fit).font == font) {
1264 // Add a new entry in the
1265 // fonttable for the position
1268 tmp.pos_end = (*it).pos_end;
1269 tmp.font = (*it).font;
1270 (*it).pos_end = pos;
1271 fontlist.push_back(tmp);
1272 } else if (pos == (*it).pos_end) {
1273 // Add a new entry in the
1274 // fonttable for the position
1276 tmp.pos = (*it).pos;
1277 tmp.pos_end = (*it).pos_end - 1;
1278 tmp.font = (*it).font;
1279 (*it).pos = (*it).pos_end;
1280 fontlist.push_back(tmp);
1282 // Add a new entry in the
1283 // fonttable for the position
1285 tmp.pos = (*it).pos;
1286 tmp.pos_end = pos - 1;
1287 tmp.font = (*it).font;
1288 fontlist.push_back(tmp);
1291 tmp.pos_end = (*it).pos_end;
1292 tmp.font = (*it).font;
1293 fontlist.push_back(tmp);
1296 (*it).pos_end = pos;
1304 // if we did not find a font entry, but if the font at hand
1305 // is the same as default, we just forget it
1306 if (font == patternfont) return;
1308 // ok, we did not find a font entry. But maybe there is exactly
1309 // the needed font entry one position left
1310 for(FontList::iterator it = fontlist.begin();
1311 it != fontlist.end(); ++it) {
1312 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1313 && (*it).font == font) {
1318 // Add a new entry in the
1319 // fonttable for the position
1323 tmp.font = patternfont;
1324 fontlist.push_back(tmp);
1326 // Next search font table
1330 FontTable * tmp = fonttable;
1331 while (tmp && !found) {
1332 if (pos >= tmp->pos && pos <= tmp->pos_end)
1339 /* if we did not find a font entry, but if the font at hand
1340 * is the same as default, we just forget it */
1341 if (font == patternfont)
1344 /* ok, we did not find a font entry. But maybe there is exactly
1345 * the needed font entry one position left */
1348 while (tmp2 && !found) {
1349 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1355 /* ok there is one. maybe it is exactly the needed font */
1356 if (tmp2->font == font) {
1357 /* put the position under the font */
1362 /* Add a new entry in the
1363 * fonttable for the position */
1364 tmp = new FontTable;
1367 tmp->font = patternfont;
1368 tmp->next = fonttable;
1371 /* we found a font entry. maybe we have to split it and create
1374 if (tmp->pos != tmp->pos_end) { /* more than one character */
1376 if (pos == tmp->pos) {
1377 /* maybe we could enlarge the left fonttable */
1381 while (tmp2 && !found) {
1382 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1388 /* Is there is one, and is it exactly the needed font? */
1389 if (found && tmp2->font == font) {
1390 /* put the position under the font */
1396 /* Add a new entry in the
1397 * fonttable for the position */
1398 tmp2 = new FontTable;
1399 tmp2->pos = pos + 1;
1400 tmp2->pos_end = tmp->pos_end;
1401 tmp2->font = tmp->font;
1403 tmp2->next = fonttable;
1406 else if (pos == tmp->pos_end) {
1407 /* Add a new entry in the
1408 * fonttable for the position */
1409 tmp2 = new FontTable;
1410 tmp2->pos = tmp->pos;
1411 tmp2->pos_end = tmp->pos_end - 1;
1412 tmp2->font = tmp->font;
1413 tmp->pos = tmp->pos_end;
1414 tmp2->next = fonttable;
1418 /* Add a new entry in the
1419 * fonttable for the position */
1420 tmp2 = new FontTable;
1421 tmp2->pos = tmp->pos;
1422 tmp2->pos_end = pos - 1;
1423 tmp2->font = tmp->font;
1424 tmp2->next = fonttable;
1427 tmp2 = new FontTable;
1428 tmp2->pos = pos + 1;
1429 tmp2->pos_end = tmp->pos_end;
1430 tmp2->font = tmp->font;
1431 tmp2->next = fonttable;
1444 /* this function is able to hide closed footnotes */
1445 LyXParagraph * LyXParagraph::Next()
1447 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1448 LyXParagraph * tmp = next;
1450 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1452 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1453 return tmp->Next(); /* there can be more than one
1454 footnote in a logical
1457 return next; /* this should never happen! */
1464 LyXParagraph * LyXParagraph::NextAfterFootnote()
1466 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1467 LyXParagraph * tmp = next;
1468 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1470 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1471 return tmp; /* there can be more than one footnote
1472 in a logical paragraph */
1474 return next; /* this should never happen! */
1481 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1483 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1484 LyXParagraph * tmp = next;
1485 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1487 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1488 return tmp; /* there can be more than one footnote
1489 in a logical paragraph */
1491 return next; /* this should never happen! */
1498 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1501 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1503 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1504 tmp = tmp->previous;
1505 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1506 return tmp; /* there can be more than one footnote
1507 in a logical paragraph */
1509 return previous; /* this should never happen! */
1516 LyXParagraph * LyXParagraph::LastPhysicalPar()
1518 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1521 LyXParagraph * tmp = this;
1523 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1524 tmp = tmp->NextAfterFootnote();
1531 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1535 LyXParagraph * tmppar = this;
1537 while (tmppar && (tmppar->IsDummy()
1538 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1539 tmppar = tmppar->previous;
1542 return this; /* this should never happen! */
1548 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1552 LyXParagraph const * tmppar = this;
1554 while (tmppar && (tmppar->IsDummy()
1555 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1556 tmppar = tmppar->previous;
1559 return this; /* this should never happen! */
1565 /* this function is able to hide closed footnotes */
1566 LyXParagraph * LyXParagraph::Previous()
1568 LyXParagraph * tmp = previous;
1573 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1574 tmp = tmp->previous;
1576 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1577 tmp = tmp->previous;
1578 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1579 return tmp->next->Previous();
1589 /* this function is able to hide closed footnotes */
1590 LyXParagraph const * LyXParagraph::Previous() const
1592 LyXParagraph * tmp = previous;
1597 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1598 tmp = tmp->previous;
1600 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1601 tmp = tmp->previous;
1602 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1603 return tmp->next->Previous();
1613 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1616 size_type i, pos_end, pos_first;
1617 /* create a new paragraph */
1618 LyXParagraph * par = ParFromPos(pos);
1619 LyXParagraph * firstpar = FirstPhysicalPar();
1621 LyXParagraph * tmp = new LyXParagraph(par);
1623 tmp->footnoteflag = footnoteflag;
1624 tmp->footnotekind = footnotekind;
1626 /* this is an idea for a more userfriendly layout handling, I will
1627 * see what the users say */
1629 /* layout stays the same with latex-environments */
1631 tmp->SetOnlyLayout(firstpar->layout);
1632 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1635 if (Last() > pos || !Last() || flag == 2) {
1636 tmp->SetOnlyLayout(firstpar->layout);
1637 tmp->align = firstpar->align;
1638 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1640 tmp->line_bottom = firstpar->line_bottom;
1641 firstpar->line_bottom = false;
1642 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1643 firstpar->pagebreak_bottom = false;
1644 tmp->added_space_bottom = firstpar->added_space_bottom;
1645 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1647 tmp->depth = firstpar->depth;
1648 tmp->noindent = firstpar->noindent;
1650 /* copy everything behind the break-position
1651 to the new paragraph
1654 while (ParFromPos(pos_first) != par)
1657 pos_end = pos_first + par->text.size() - 1;
1658 tmp->text.reserve(pos_end - pos);
1660 for (i = pos; i <= pos_end; i++) {
1661 par->CutIntoMinibuffer(i - pos_first);
1662 tmp->InsertFromMinibuffer(i - pos);
1665 for (i = pos_end; i >= pos; i--)
1666 par->Erase(i - pos_first);
1668 par->text.resize(par->text.size());
1671 /* just an idea of me */
1673 tmp->line_top = firstpar->line_top;
1674 tmp->pagebreak_top = firstpar->pagebreak_top;
1675 tmp->added_space_top = firstpar->added_space_top;
1676 tmp->bibkey = firstpar->bibkey;
1678 /* layout stays the same with latex-environments */
1680 firstpar->SetOnlyLayout(tmp->layout);
1681 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1682 firstpar->depth = tmp->depth;
1688 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1690 par = par->FirstPhysicalPar();
1691 footnoteflag = par->footnoteflag;
1692 footnotekind = par->footnotekind;
1694 layout = par->layout;
1695 align = par-> align;
1696 SetLabelWidthString(par->labelwidthstring);
1698 line_bottom = par->line_bottom;
1699 pagebreak_bottom = par->pagebreak_bottom;
1700 added_space_bottom = par->added_space_bottom;
1702 line_top = par->line_top;
1703 pagebreak_top = par->pagebreak_top;
1704 added_space_top = par->added_space_top;
1706 pextra_type = par->pextra_type;
1707 pextra_width = par->pextra_width;
1708 pextra_widthp = par->pextra_widthp;
1709 pextra_alignment = par->pextra_alignment;
1710 pextra_hfill = par->pextra_hfill;
1711 pextra_start_minipage = par->pextra_start_minipage;
1713 noindent = par->noindent;
1718 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1720 LyXParagraph * tmppar = this;
1723 && tmppar->previous->footnoteflag ==
1724 LyXParagraph::CLOSED_FOOTNOTE)
1725 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1726 tmppar = tmppar->previous;
1729 return this; /* this should never happen! */
1735 LyXParagraph * LyXParagraph::Clone() const
1737 /* create a new paragraph */
1738 LyXParagraph * result = new LyXParagraph;
1740 result->MakeSameLayout(this);
1742 /* this is because of the dummy layout of the paragraphs that
1744 result->layout = layout;
1746 /* table stuff -- begin*/
1748 result->table = table->Clone();
1751 /* table stuff -- end*/
1754 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1757 /* copy everything behind the break-position to the new paragraph */
1759 for (size_type i = 0; i < size(); i++) {
1760 CopyIntoMinibuffer(i);
1761 result->InsertFromMinibuffer(i);
1763 result->text.resize(result->text.size());
1768 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1770 par = par->FirstPhysicalPar();
1773 par->footnoteflag == footnoteflag &&
1774 par->footnotekind == footnotekind &&
1776 par->layout == layout &&
1778 par->align == align &&
1780 par->line_bottom == line_bottom &&
1781 par->pagebreak_bottom == pagebreak_bottom &&
1782 par->added_space_bottom == added_space_bottom &&
1784 par->line_top == line_top &&
1785 par->pagebreak_top == pagebreak_top &&
1786 par->added_space_top == added_space_top &&
1788 par->pextra_type == pextra_type &&
1789 par->pextra_width == pextra_width &&
1790 par->pextra_widthp == pextra_widthp &&
1791 par->pextra_alignment == pextra_alignment &&
1792 par->pextra_hfill == pextra_hfill &&
1793 par->pextra_start_minipage == pextra_start_minipage &&
1795 par->table == table && // what means: NO TABLE AT ALL
1797 par->noindent == noindent &&
1798 par->depth == depth);
1802 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1804 size_type i, pos_end, pos_first;
1806 /* create a new paragraph */
1807 LyXParagraph * par = ParFromPos(pos);
1809 LyXParagraph * tmp = new LyXParagraph(par);
1811 tmp->MakeSameLayout(par);
1814 /* copy everything behind the break-position to the new
1817 while (ParFromPos(pos_first) != par)
1819 pos_end = pos_first + par->text.size() - 1;
1820 /* make shure there is enough memory for the now larger
1821 paragraph. This is not neccessary, because
1822 InsertFromMinibuffer will enlarge the memory (it uses
1823 InsertChar of course). But doing it by hand
1824 is MUCH faster! (only one time, not thousend times!!) */
1825 tmp->text.reserve(pos_end - pos);
1827 for (i = pos; i <= pos_end; i++) {
1829 par->CutIntoMinibuffer(i - pos_first);
1830 tmp->InsertFromMinibuffer(i - pos);
1832 for (i = pos_end; i >= pos; i--)
1833 par->Erase(i - pos_first);
1835 par->text.resize(par->text.size());
1840 /* be carefull, this does not make any check at all */
1841 void LyXParagraph::PasteParagraph()
1843 /* copy the next paragraph to this one */
1844 LyXParagraph * the_next = Next();
1846 LyXParagraph * firstpar = FirstPhysicalPar();
1848 /* first the DTP-stuff */
1849 firstpar->line_bottom = the_next->line_bottom;
1850 firstpar->added_space_bottom = the_next->added_space_bottom;
1851 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1853 size_type pos_end = the_next->text.size() - 1;
1854 size_type pos_insert = Last();
1857 /* ok, now copy the paragraph */
1858 for (i = 0; i <= pos_end; i++) {
1859 the_next->CutIntoMinibuffer(i);
1860 InsertFromMinibuffer(pos_insert + i);
1863 /* delete the next paragraph */
1868 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1870 LyXParagraph * par = ParFromPos(pos);
1872 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1873 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1879 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1881 LyXParagraph * par = ParFromPos(pos);
1883 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1884 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1890 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1892 return FirstPhysicalPar()->layout;
1896 char LyXParagraph::GetDepth() const
1898 return FirstPhysicalPar()->depth;
1902 char LyXParagraph::GetAlign() const
1904 return FirstPhysicalPar()->align;
1908 string LyXParagraph::GetLabestring() const
1910 return FirstPhysicalPar()->labelstring;
1914 int LyXParagraph::GetFirstCounter(int i) const
1916 return FirstPhysicalPar()->counter_[i];
1920 /* the next two functions are for the manual labels */
1921 string LyXParagraph::GetLabelWidthString() const
1923 if (!FirstPhysicalPar()->labelwidthstring.empty())
1924 return FirstPhysicalPar()->labelwidthstring;
1926 return _("Senseless with this layout!");
1930 void LyXParagraph::SetLabelWidthString(string const & s)
1932 LyXParagraph * par = FirstPhysicalPar();
1934 par->labelwidthstring = s;
1938 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1940 LyXParagraph * par = FirstPhysicalPar();
1941 LyXParagraph * ppar = 0;
1942 LyXParagraph * npar = 0;
1944 par->layout = new_layout;
1945 /* table stuff -- begin*/
1948 /* table stuff -- end*/
1949 if (par->pextra_type == PEXTRA_NONE) {
1950 if (par->Previous()) {
1951 ppar = par->Previous()->FirstPhysicalPar();
1954 && (ppar->depth > par->depth))
1955 ppar = ppar->Previous()->FirstPhysicalPar();
1958 npar = par->Next()->NextAfterFootnote();
1961 && (npar->depth > par->depth))
1962 npar = npar->Next()->NextAfterFootnote();
1964 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1966 p1 = ppar->pextra_width,
1967 p2 = ppar->pextra_widthp;
1968 ppar->SetPExtraType(ppar->pextra_type,
1969 p1.c_str(), p2.c_str());
1971 if ((par->pextra_type == PEXTRA_NONE) &&
1972 npar && (npar->pextra_type != PEXTRA_NONE)) {
1974 p1 = npar->pextra_width,
1975 p2 = npar->pextra_widthp;
1976 npar->SetPExtraType(npar->pextra_type,
1977 p1.c_str(), p2.c_str());
1983 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
1986 * par = FirstPhysicalPar(),
1990 par->layout = new_layout;
1991 par->labelwidthstring.clear();
1992 par->align = LYX_ALIGN_LAYOUT;
1993 par->added_space_top = VSpace(VSpace::NONE);
1994 par->added_space_bottom = VSpace(VSpace::NONE);
1995 /* table stuff -- begin*/
1998 /* table stuff -- end*/
1999 if (par->pextra_type == PEXTRA_NONE) {
2000 if (par->Previous()) {
2001 ppar = par->Previous()->FirstPhysicalPar();
2004 && (ppar->depth > par->depth))
2005 ppar = ppar->Previous()->FirstPhysicalPar();
2008 npar = par->Next()->NextAfterFootnote();
2011 && (npar->depth > par->depth))
2012 npar = npar->Next()->NextAfterFootnote();
2014 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2016 p1 = ppar->pextra_width,
2017 p2 = ppar->pextra_widthp;
2018 ppar->SetPExtraType(ppar->pextra_type,
2019 p1.c_str(), p2.c_str());
2021 if ((par->pextra_type == PEXTRA_NONE) &&
2022 npar && (npar->pextra_type != PEXTRA_NONE)) {
2024 p1 = npar->pextra_width,
2025 p2 = npar->pextra_widthp;
2026 npar->SetPExtraType(npar->pextra_type,
2027 p1.c_str(), p2.c_str());
2033 /* if the layout of a paragraph contains a manual label, the beginning of the
2034 * main body is the beginning of the second word. This is what the par-
2035 * function returns. If the layout does not contain a label, the main
2036 * body always starts with position 0. This differentiation is necessary,
2037 * because there cannot be a newline or a blank <= the beginning of the
2038 * main body in TeX. */
2040 int LyXParagraph::BeginningOfMainBody() const
2042 if (FirstPhysicalPar() != this)
2045 // Unroll the first two cycles of the loop
2046 // and remember the previous character to
2047 // remove unnecessary GetChar() calls
2050 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2052 char previous_char, temp;
2054 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2055 // Yes, this ^ is supposed to be "= " not "=="
2058 && previous_char != ' '
2059 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2061 previous_char = temp;
2066 if (i == 0 && i == size() &&
2067 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2068 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2069 i++; /* the cursor should not jump
2070 * to the main body if there
2076 LyXParagraph * LyXParagraph::DepthHook(int deth)
2078 LyXParagraph * newpar = this;
2083 newpar = newpar->FirstPhysicalPar()->Previous();
2084 } while (newpar && newpar->GetDepth() > deth
2085 && newpar->footnoteflag == footnoteflag);
2088 if (Previous() || GetDepth())
2089 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2093 return newpar->FirstPhysicalPar();
2097 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2099 LyXParagraph const * newpar = this;
2104 newpar = newpar->FirstPhysicalPar()->Previous();
2105 } while (newpar && newpar->GetDepth() > deth
2106 && newpar->footnoteflag == footnoteflag);
2109 if (Previous() || GetDepth())
2110 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2114 return newpar->FirstPhysicalPar();
2118 int LyXParagraph::AutoDeleteInsets()
2122 for (InsetList::iterator it = insetlist.begin();
2123 it != insetlist.end(); ++it) {
2124 if ((*it).inset->AutoDelete()) {
2131 InsetTable * tmpi = insettable;
2132 InsetTable * tmpi2 = tmpi;
2138 if (tmpi2->inset->AutoDelete()) {
2143 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2144 "cannot auto-delete insets" << endl;
2151 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2154 InsetTable * tmp = 0;
2155 for (InsetList::iterator it = insetlist.begin();
2156 it != insetlist.end(); ++it) {
2157 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2168 InsetTable * tmpi = insettable;
2169 InsetTable * tmpi2 = 0;
2171 if (tmpi->pos >= pos) {
2172 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2179 return tmpi2->inset;
2187 /* returns -1 if inset not found */
2188 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2191 for (InsetList::iterator it = insetlist.begin();
2192 it != insetlist.end(); ++it) {
2193 if ((*it).inset == inset) {
2197 // Think about footnotes
2198 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2199 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2200 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2202 return size() + 1 + further;
2206 /* find the entry */
2207 InsetTable * tmpi = insettable;
2208 while (tmpi && tmpi->inset != inset) {
2211 if (tmpi && tmpi->inset)
2214 /* think about footnotes */
2215 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2216 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2218 NextAfterFootnote()->GetPositionOfInset(inset);
2220 return text.size() + 1 + further;
2228 void LyXParagraph::readSimpleWholeFile(istream & is)
2234 InsertChar(text.size(), c);
2239 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2240 string & foot, TexRow & foot_texrow,
2243 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2244 LyXParagraph * par = next;
2245 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2248 bool further_blank_line = false;
2250 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2252 if (start_of_appendix) {
2253 file += "\\appendix\n";
2257 if (tex_code_break_column && style.isCommand()){
2262 if (pagebreak_top) {
2263 file += "\\newpage";
2264 further_blank_line = true;
2266 if (added_space_top.kind() != VSpace::NONE) {
2267 file += added_space_top.asLatexCommand();
2268 further_blank_line = true;
2272 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2273 file += "\\vspace{-1\\parskip}";
2274 further_blank_line = true;
2277 if (further_blank_line){
2282 switch (style.latextype) {
2285 file += style.latexname();
2286 file += style.latexparam();
2288 case LATEX_ITEM_ENVIRONMENT:
2290 bibkey->Latex(file, false);
2294 case LATEX_LIST_ENVIRONMENT:
2301 bool need_par = SimpleTeXOnePar(file, texrow);
2303 // Spit out footnotes
2304 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2305 && par->footnoteflag != footnoteflag) {
2306 par = par->TeXFootnote(file, texrow,
2307 foot, foot_texrow, foot_count);
2308 par->SimpleTeXOnePar(file, texrow);
2312 // Make sure that \\par is done with the font of the last
2313 // character if this has another size as the default.
2314 // This is necessary because LaTeX (and LyX on the screen)
2315 // calculates the space between the baselines according
2316 // to this font. (Matthias)
2317 LyXFont font = getFont(Last()-1);
2319 if (style.resfont.size() != font.size()) {
2321 file += font.latexSize();
2325 } else if (textclasslist.Style(current_view->buffer()->params.textclass,
2326 GetLayout()).isCommand()){
2327 if (style.resfont.size() != font.size()) {
2329 file += font.latexSize();
2333 } else if (style.resfont.size() != font.size()){
2334 file += "{\\" + font.latexSize() + " \\par}";
2337 switch (style.latextype) {
2338 case LATEX_ITEM_ENVIRONMENT:
2339 case LATEX_LIST_ENVIRONMENT:
2340 if (par && (depth < par->depth)) {
2345 case LATEX_ENVIRONMENT:
2346 // if its the last paragraph of the current environment
2347 // skip it otherwise fall through
2349 && (par->layout != layout
2350 || par->depth != depth
2351 || par->pextra_type != pextra_type))
2354 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2355 && footnotekind != LyXParagraph::FOOTNOTE
2356 && footnotekind != LyXParagraph::MARGIN
2360 // don't insert this if we would be adding it
2361 // before or after a table in a float. This
2362 // little trick is needed in order to allow
2363 // use of tables in \subfigures or \subtables.
2369 further_blank_line = false;
2371 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2372 further_blank_line = true;
2375 if (added_space_bottom.kind() != VSpace::NONE) {
2376 file += added_space_bottom.asLatexCommand();
2377 further_blank_line = true;
2380 if (pagebreak_bottom) {
2381 file += "\\newpage";
2382 further_blank_line = true;
2385 if (further_blank_line){
2390 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2391 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2396 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2401 // This one spits out the text of the paragraph
2402 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2404 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2407 return SimpleTeXOneTablePar(file, texrow);
2410 size_type main_body;
2412 bool return_value = false;
2414 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
2417 /* maybe we have to create a optional argument */
2418 if (style.labeltype != LABEL_MANUAL)
2421 main_body = BeginningOfMainBody();
2423 if (main_body > 0) {
2425 basefont = getFont(-2); // Get label font
2427 basefont = getFont(-1); // Get layout font
2435 if (style.isCommand()) {
2438 } else if (align != LYX_ALIGN_LAYOUT) {
2441 return_value = true;
2445 // Which font is currently active?
2446 LyXFont running_font = basefont;
2447 // Do we have an open font change?
2448 bool open_font = false;
2450 texrow.start(this, 0);
2452 for (size_type i = 0; i < size(); ++i) {
2454 // First char in paragraph or after label?
2455 if (i == main_body && !IsDummy()) {
2456 if (main_body > 0) {
2458 column += running_font.latexWriteEndChanges(file, basefont);
2461 basefont = getFont(-1); // Now use the layout font
2462 running_font = basefont;
2466 if (style.isCommand()) {
2469 } else if (align != LYX_ALIGN_LAYOUT) {
2472 return_value = true;
2476 file += "\\noindent ";
2480 case LYX_ALIGN_NONE:
2481 case LYX_ALIGN_BLOCK:
2482 case LYX_ALIGN_LAYOUT:
2483 case LYX_ALIGN_SPECIAL: break;
2484 case LYX_ALIGN_LEFT:
2485 file += "\\raggedright ";
2488 case LYX_ALIGN_RIGHT:
2489 file += "\\raggedleft ";
2492 case LYX_ALIGN_CENTER:
2493 file += "\\centering ";
2501 // Fully instantiated font
2502 LyXFont font = getFont(i);
2504 // Spaces at end of font change are simulated to be
2505 // outside font change, i.e. we write "\textXX{text} "
2506 // rather than "\textXX{text }". (Asger)
2507 if (open_font && c == ' ' && i <= size() - 2
2508 && !getFont(i+1).equalExceptLatex(running_font)
2509 && !getFont(i+1).equalExceptLatex(font)) {
2510 font = getFont(i+1);
2512 // We end font definition before blanks
2513 if (!font.equalExceptLatex(running_font) && open_font) {
2514 column += running_font.latexWriteEndChanges(file,
2516 running_font = basefont;
2520 // Blanks are printed before start of fontswitch
2522 // Do not print the separation of the optional argument
2523 if (i != main_body - 1) {
2524 SimpleTeXBlanks(file, texrow, i,
2525 column, font, style);
2529 // Do we need to change font?
2530 if (!font.equalExceptLatex(running_font)
2531 && i != main_body-1) {
2532 column += font.latexWriteStartChanges(file, basefont);
2533 running_font = font;
2537 if (c == LyXParagraph::META_NEWLINE) {
2538 // newlines are handled differently here than
2539 // the default in SimpleTeXSpecialChars().
2540 if (!style.newline_allowed
2541 || font.latex() == LyXFont::ON) {
2545 column += running_font.latexWriteEndChanges(file, basefont);
2548 basefont = getFont(-1);
2549 running_font = basefont;
2550 if (font.family() ==
2551 LyXFont::TYPEWRITER_FAMILY) {
2557 texrow.start(this, i+1);
2560 SimpleTeXSpecialChars(file, texrow,
2561 font, running_font, basefont,
2562 open_font, style, i, column, c);
2566 // If we have an open font definition, we have to close it
2568 running_font.latexWriteEndChanges(file, basefont);
2571 /* needed if there is an optional argument but no contents */
2572 if (main_body > 0 && main_body == size()) {
2574 return_value = false;
2577 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2578 return return_value;
2582 // This one spits out the text of a table paragraph
2583 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2585 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2589 bool return_value = false;
2590 int current_cell_number = -1;
2592 LyXLayout const & style =
2593 textclasslist.Style(current_view->buffer()->params.textclass, GetLayout());
2594 LyXFont basefont = getFont(-1); // Get layout font
2595 // Which font is currently active?
2596 LyXFont running_font = basefont;
2597 // Do we have an open font change?
2598 bool open_font = false;
2601 if (!IsDummy()) { // it is dummy if it is in a float!!!
2602 if (style.isCommand()) {
2605 } else if (align != LYX_ALIGN_LAYOUT) {
2608 return_value = true;
2611 file += "\\noindent ";
2615 case LYX_ALIGN_NONE:
2616 case LYX_ALIGN_BLOCK:
2617 case LYX_ALIGN_LAYOUT:
2618 case LYX_ALIGN_SPECIAL: break;
2619 case LYX_ALIGN_LEFT:
2620 file += "\\raggedright ";
2623 case LYX_ALIGN_RIGHT:
2624 file += "\\raggedleft ";
2627 case LYX_ALIGN_CENTER:
2628 file += "\\centering ";
2633 current_cell_number = -1;
2634 tmp = table->TexEndOfCell(file, current_cell_number);
2635 for (; tmp > 0 ; --tmp)
2638 texrow.start(this, 0);
2640 for (size_type i = 0; i < size(); ++i) {
2642 if (table->IsContRow(current_cell_number+1)) {
2643 if (c == LyXParagraph::META_NEWLINE)
2644 current_cell_number++;
2649 // Fully instantiated font
2650 LyXFont font = getFont(i);
2652 // Spaces at end of font change are simulated to be
2653 // outside font change.
2654 // i.e. we write "\textXX{text} " rather than
2655 // "\textXX{text }". (Asger)
2656 if (open_font && c == ' ' && i <= size() - 2
2657 && getFont(i+1) != running_font && getFont(i+1) != font) {
2658 font = getFont(i+1);
2661 // We end font definition before blanks
2662 if (font != running_font && open_font) {
2663 column += running_font.latexWriteEndChanges(file,
2665 running_font = basefont;
2668 // Blanks are printed before start of fontswitch
2670 SimpleTeXBlanks(file, texrow, i, column, font, style);
2672 // Do we need to change font?
2673 if (font != running_font) {
2674 column += font.latexWriteStartChanges(file, basefont);
2675 running_font = font;
2678 // Do we need to turn on LaTeX mode?
2679 if (font.latex() != running_font.latex()) {
2680 if (font.latex() == LyXFont::ON
2681 && style.needprotect) {
2682 file += "\\protect ";
2686 if (c == LyXParagraph::META_NEWLINE) {
2687 // special case for inside a table
2688 // different from default case in
2689 // SimpleTeXSpecialChars()
2691 column += running_font
2692 .latexWriteEndChanges(file, basefont);
2695 basefont = getFont(-1);
2696 running_font = basefont;
2697 current_cell_number++;
2698 if (table->CellHasContRow(current_cell_number) >= 0) {
2699 TeXContTableRows(file, i+1,
2700 current_cell_number,
2703 // if this cell follow only ContRows till end don't
2704 // put the EndOfCell because it is put after the
2706 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2707 current_cell_number--;
2710 int tmp = table->TexEndOfCell(file,
2711 current_cell_number);
2714 } else if (tmp < 0) {
2720 texrow.start(this, i+1);
2722 SimpleTeXSpecialChars(file, texrow,
2723 font, running_font, basefont,
2724 open_font, style, i, column, c);
2728 // If we have an open font definition, we have to close it
2730 running_font.latexWriteEndChanges(file, basefont);
2732 current_cell_number++;
2733 tmp = table->TexEndOfCell(file, current_cell_number);
2734 for (; tmp > 0; --tmp)
2736 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2737 return return_value;
2741 // This one spits out the text off ContRows in tables
2742 bool LyXParagraph::TeXContTableRows(string & file,
2743 LyXParagraph::size_type i,
2744 int current_cell_number,
2745 int & column, TexRow & texrow)
2747 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2753 bool return_value = false;
2754 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2758 basefont = getFont(-1); // Get layout font
2759 // Which font is currently active?
2760 LyXFont running_font = basefont;
2761 // Do we have an open font change?
2762 bool open_font = false;
2764 size_type lastpos = i;
2765 int cell = table->CellHasContRow(current_cell_number);
2766 ++current_cell_number;
2768 // first find the right position
2770 for (; (i < size()) && (current_cell_number<cell); ++i) {
2772 if (c == LyXParagraph::META_NEWLINE)
2773 current_cell_number++;
2777 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2781 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2786 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2790 // Fully instantiated font
2791 LyXFont font = getFont(i);
2793 // Spaces at end of font change are simulated to
2794 // be outside font change. i.e. we write
2795 // "\textXX{text} " rather than "\textXX{text }".
2797 if (open_font && c == ' ' && i <= size() - 2
2798 && getFont(i + 1) != running_font
2799 && getFont(i + 1) != font) {
2800 font = getFont(i + 1);
2803 // We end font definition before blanks
2804 if (font != running_font && open_font) {
2805 column += running_font.latexWriteEndChanges(file, basefont);
2806 running_font = basefont;
2809 // Blanks are printed before start of fontswitch
2811 SimpleTeXBlanks(file, texrow, i,
2812 column, font, style);
2814 // Do we need to change font?
2815 if (font != running_font) {
2817 font.latexWriteStartChanges(file,
2819 running_font = font;
2822 // Do we need to turn on LaTeX mode?
2823 if (font.latex() != running_font.latex()) {
2824 if (font.latex() == LyXFont::ON
2825 && style.needprotect)
2827 file += "\\protect ";
2831 SimpleTeXSpecialChars(file, texrow, font,
2832 running_font, basefont,
2833 open_font, style, i, column, c);
2835 // If we have an open font definition, we have to close it
2837 running_font.latexWriteEndChanges(file, basefont);
2840 basefont = getFont(-1);
2841 running_font = basefont;
2842 cell = table->CellHasContRow(current_cell_number);
2844 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2845 return return_value;
2849 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2851 bool retval = false;
2853 case LyXParagraph::META_HFILL:
2854 sgml_string.clear();
2856 case LyXParagraph::META_PROTECTED_SEPARATOR:
2859 case LyXParagraph::META_NEWLINE:
2863 sgml_string = "&";
2866 sgml_string = "<";
2869 sgml_string = ">";
2872 sgml_string = "$";
2875 sgml_string = "#";
2878 sgml_string = "%";
2881 sgml_string = "[";
2884 sgml_string = "]";
2887 sgml_string = "{";
2890 sgml_string = "}";
2893 sgml_string = "˜";
2896 sgml_string = """;
2899 sgml_string = "\";
2905 case '\0': /* Ignore :-) */
2906 sgml_string.clear();
2916 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2917 int & desc_on, int depth)
2920 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2922 LyXFont font1, font2;
2925 size_type main_body;
2926 string emph = "emphasis";
2927 bool emph_flag = false;
2929 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
2932 if (style.labeltype != LABEL_MANUAL)
2935 main_body = BeginningOfMainBody();
2937 /* gets paragraph main font */
2939 font1 = style.labelfont;
2943 int char_line_count = depth;
2944 addNewlineAndDepth(file, depth);
2945 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2946 file += "<INFORMALTABLE>";
2947 addNewlineAndDepth(file, ++depth);
2949 int current_cell_number = -1;
2950 int tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2952 /* parsing main loop */
2953 for (size_type i = 0; i < size(); ++i) {
2955 if (table->IsContRow(current_cell_number+1)) {
2956 if (c == LyXParagraph::META_NEWLINE)
2957 ++current_cell_number;
2962 // Fully instantiated font
2965 /* handle <emphasis> tag */
2966 if (font1.emph() != font2.emph() && i) {
2967 if (font2.emph() == LyXFont::ON) {
2968 file += "<emphasis>";
2970 } else if (emph_flag) {
2971 file += "</emphasis>";
2975 if (c == LyXParagraph::META_NEWLINE) {
2976 // we have only to control for emphasis open here!
2978 file += "</emphasis>";
2981 font1 = font2 = getFont(-1);
2982 current_cell_number++;
2983 if (table->CellHasContRow(current_cell_number) >= 0) {
2984 DocBookContTableRows(file, extra, desc_on, i+1,
2985 current_cell_number,
2988 // if this cell follow only ContRows till end don't
2989 // put the EndOfCell because it is put after the
2991 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2992 current_cell_number--;
2995 tmp= table->DocBookEndOfCell(file, current_cell_number,
3000 } else if (c == LyXParagraph::META_INSET) {
3001 inset = GetInset(i);
3003 inset->DocBook(tmp_out);
3005 // This code needs some explanation:
3006 // Two insets are treated specially
3007 // label if it is the first element in a
3008 // command paragraph
3010 // graphics inside tables or figure floats
3012 // title (the equivalente in latex for this
3014 // and title should come first
3017 if(desc_on != 3 || i != 0) {
3018 if(tmp_out[0] == '@') {
3020 extra += frontStrip(tmp_out,
3023 file += frontStrip(tmp_out,
3028 } else if (font2.latex() == LyXFont::ON) {
3029 // "TeX"-Mode on == > SGML-Mode on.
3035 if (linuxDocConvertChar(c, sgml_string)
3036 && !style.free_spacing) {
3037 // in freespacing mode, spaces are
3038 // non-breaking characters
3043 file += "</term><listitem><para>";
3049 file += sgml_string;
3055 /* needed if there is an optional argument but no contents */
3056 if (main_body > 0 && main_body == size()) {
3061 file += "</emphasis>";
3064 current_cell_number++;
3065 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3066 /* resets description flag correctly */
3069 /* <term> not closed... */
3073 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3074 file += "</INFORMALTABLE>";
3076 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3081 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3083 LyXParagraph::size_type i,
3084 int current_cell_number, int &column)
3089 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3092 LyXFont font1, font2;
3095 size_type main_body;
3097 string emph= "emphasis";
3098 bool emph_flag= false;
3099 int char_line_count= 0;
3101 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3104 if (style.labeltype != LABEL_MANUAL)
3107 main_body = BeginningOfMainBody();
3109 /* gets paragraph main font */
3111 font1 = style.labelfont;
3116 cell = table->CellHasContRow(current_cell_number);
3117 ++current_cell_number;
3119 // first find the right position
3121 for (; i < size() && current_cell_number < cell; ++i) {
3123 if (c == LyXParagraph::META_NEWLINE)
3124 current_cell_number++;
3128 // I don't know how to handle this so I comment it
3129 // for the moment (Jug)
3130 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3131 // file += " \\\\\n";
3134 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3139 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3143 // Fully instantiated font
3146 /* handle <emphasis> tag */
3147 if (font1.emph() != font2.emph() && i) {
3148 if (font2.emph() == LyXFont::ON) {
3149 file += "<emphasis>";
3151 } else if (emph_flag) {
3152 file += "</emphasis>";
3156 if (c == LyXParagraph::META_INSET) {
3157 inset = GetInset(i);
3159 inset->DocBook(tmp_out);
3161 // This code needs some explanation:
3162 // Two insets are treated specially
3163 // label if it is the first element in a command paragraph
3165 // graphics inside tables or figure floats can't go on
3166 // title (the equivalente in latex for this case is caption
3167 // and title should come first
3170 if(desc_on != 3 || i != 0) {
3171 if(tmp_out[0] == '@') {
3173 extra += frontStrip(tmp_out, '@');
3175 file += frontStrip(tmp_out, '@');
3179 } else if (font2.latex() == LyXFont::ON) {
3180 // "TeX"-Mode on == > SGML-Mode on.
3186 if (linuxDocConvertChar(c, sgml_string)
3187 && !style.free_spacing) {
3188 // in freespacing mode, spaces are
3189 // non-breaking characters
3194 file += "</term><listitem><para>";
3200 file += sgml_string;
3204 // we have only to control for emphasis open here!
3206 file += "</emphasis>";
3209 font1 = font2 = getFont(-1);
3210 cell = table->CellHasContRow(current_cell_number);
3212 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3216 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3217 LyXParagraph::size_type const i,
3218 int & column, LyXFont const & font,
3219 LyXLayout const & style)
3221 if (column > tex_code_break_column
3223 && GetChar(i - 1) != ' '
3225 // In LaTeX mode, we don't want to
3226 // break lines since some commands
3228 && ! (font.latex() == LyXFont::ON)
3229 // same in FreeSpacing mode
3230 && !style.free_spacing
3231 // In typewriter mode, we want to avoid
3232 // ! . ? : at the end of a line
3233 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3234 && (GetChar(i-1) == '.'
3235 || GetChar(i-1) == '?'
3236 || GetChar(i-1) == ':'
3237 || GetChar(i-1) == '!'))) {
3238 if (tex_code_break_column == 0) {
3239 // in batchmode we need LaTeX to still
3240 // see it as a space not as an extra '\n'
3246 texrow.start(this, i+1);
3248 } else if (font.latex() == LyXFont::OFF) {
3249 if (style.free_spacing) {
3258 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3260 LyXFont & running_font,
3263 LyXLayout const & style,
3264 LyXParagraph::size_type & i,
3265 int & column, char const c)
3267 // Two major modes: LaTeX or plain
3268 // Handle here those cases common to both modes
3269 // and then split to handle the two modes separately.
3271 case LyXParagraph::META_INSET: {
3272 Inset * inset = GetInset(i);
3274 int len = file.length();
3275 int tmp = inset->Latex(file, style.isCommand());
3280 column += file.length() - len;
3289 case LyXParagraph::META_NEWLINE:
3291 column += running_font.latexWriteEndChanges(file,
3295 basefont = getFont(-1);
3296 running_font = basefont;
3299 case LyXParagraph::META_HFILL:
3300 file += "\\hfill{}";
3305 // And now for the special cases within each mode
3306 // Are we in LaTeX mode?
3307 if (font.latex() == LyXFont::ON) {
3308 // at present we only have one option
3309 // but I'll leave it as a switch statement
3310 // so its simpler to extend. (ARRae)
3312 case LyXParagraph::META_PROTECTED_SEPARATOR:
3317 // make sure that we will not print
3318 // error generating chars to the tex
3319 // file. This test would not be needed
3320 // if it were done in the buffer
3328 // Plain mode (i.e. not LaTeX)
3330 case LyXParagraph::META_PROTECTED_SEPARATOR:
3335 file += "\\textbackslash{}";
3339 case '°': case '±': case '²': case '³':
3340 case '×': case '÷': case '¹': case 'ª':
3341 case 'º': case '¬': case 'µ':
3342 if (current_view->buffer()->params.inputenc == "latin1") {
3343 file += "\\ensuremath{";
3352 case '|': case '<': case '>':
3353 // In T1 encoding, these characters exist
3354 if (lyxrc->fontenc == "T1") {
3356 //... but we should avoid ligatures
3357 if ((c == '>' || c == '<')
3359 && GetChar(i+1) == c){
3360 file += "\\textcompwordmark{}";
3365 // Typewriter font also has them
3366 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3370 // Otherwise, we use what LaTeX
3374 file += "\\textless{}";
3378 file += "\\textgreater{}";
3382 file += "\\textbar{}";
3388 case '-': // "--" in Typewriter mode -> "-{}-"
3390 && GetChar(i + 1) == '-'
3391 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3400 file += "\\char`\\\"{}";
3405 if (current_view->buffer()->params.inputenc == "default") {
3406 file += "\\pounds{}";
3414 case '%': case '#': case '{':
3422 file += "\\textasciitilde{}";
3427 file += "\\textasciicircum{}";
3431 case '*': case '[': case ']':
3432 // avoid being mistaken for optional arguments
3440 /* blanks are printed before font switching */
3441 // Sure? I am not! (try nice-latex)
3442 // I am sure it's correct. LyX might be smarter
3443 // in the future, but for now, nothing wrong is
3448 /* idea for labels --- begin*/
3452 && font.family() != LyXFont::TYPEWRITER_FAMILY
3453 && GetChar(i + 1) == 'y'
3454 && GetChar(i + 2) == 'X') {
3462 && font.family() != LyXFont::TYPEWRITER_FAMILY
3463 && GetChar(i + 1) == 'e'
3464 && GetChar(i + 2) == 'X') {
3469 /* check for LaTeX2e */
3472 && font.family() != LyXFont::TYPEWRITER_FAMILY
3473 && GetChar(i + 1) == 'a'
3474 && GetChar(i + 2) == 'T'
3475 && GetChar(i + 3) == 'e'
3476 && GetChar(i + 4) == 'X'
3477 && GetChar(i + 5) == '2'
3478 && GetChar(i + 6) == 'e') {
3479 file += "\\LaTeXe{}";
3483 /* check for LaTeX */
3486 && font.family() != LyXFont::TYPEWRITER_FAMILY
3487 && GetChar(i + 1) == 'a'
3488 && GetChar(i + 2) == 'T'
3489 && GetChar(i + 3) == 'e'
3490 && GetChar(i + 4) == 'X') {
3491 file += "\\LaTeX{}";
3494 /* idea for labels --- end*/
3495 } else if (c != '\0') {
3505 bool LyXParagraph::RoffContTableRows(ostream & os,
3506 LyXParagraph::size_type i,
3512 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3517 string fname2 = TmpFileName(string(), "RAT2");
3519 int cell = table->CellHasContRow(actcell);
3522 // first find the right position
3524 for (; i < size() && actcell < cell; ++i) {
3526 if (c == LyXParagraph::META_NEWLINE)
3531 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3534 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3536 font2 = GetFontSettings(i);
3537 if (font1.latex() != font2.latex()) {
3538 if (font2.latex() != LyXFont::OFF)
3543 case LyXParagraph::META_INSET:
3544 if ((inset = GetInset(i))) {
3545 fstream fs(fname2.c_str(),
3548 WriteAlert(_("LYX_ERROR:"),
3549 _("Cannot open temporary file:"),
3553 inset->Latex(fs, -1);
3566 case LyXParagraph::META_NEWLINE:
3568 case LyXParagraph::META_HFILL:
3570 case LyXParagraph::META_PROTECTED_SEPARATOR:
3579 lyxerr.debug() << "RoffAsciiTable: "
3580 "NULL char in structure."
3585 cell = table->CellHasContRow(actcell);
3591 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3592 string & foot, TexRow & foot_texrow,
3595 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3596 LyXParagraph * par = this;
3598 while (par && par->depth == depth) {
3600 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3601 if (textclasslist.Style(current_view->buffer()->params.textclass,
3602 par->layout).isEnvironment()
3603 || par->pextra_type != PEXTRA_NONE)
3605 par = par->TeXEnvironment(file, texrow,
3609 par = par->TeXOnePar(file, texrow,
3614 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3620 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3621 string & foot, TexRow & foot_texrow,
3624 bool eindent_open = false;
3625 bool foot_this_level = false;
3626 // flags when footnotetext should be appended to file.
3627 static bool minipage_open = false;
3628 static int minipage_open_depth = 0;
3629 char par_sep = current_view->buffer()->params.paragraph_separation;
3631 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3633 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3635 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3638 if (pextra_type == PEXTRA_INDENT) {
3639 if (!pextra_width.empty()) {
3640 file += "\\begin{LyXParagraphIndent}{"
3641 + pextra_width + "}\n";
3643 //float ib = atof(pextra_widthp.c_str())/100;
3644 // string can't handle floats at present (971109)
3645 // so I'll do a conversion by hand knowing that
3646 // the limits are 0.0 to 1.0. ARRae.
3647 file += "\\begin{LyXParagraphIndent}{";
3648 switch (pextra_widthp.length()) {
3654 file += pextra_widthp;
3658 file += pextra_widthp;
3660 file += "\\columnwidth}\n";
3663 eindent_open = true;
3665 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3666 if (pextra_hfill && Previous() &&
3667 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3668 file += "\\hfill{}\n";
3671 if (par_sep == BufferParams::PARSEP_INDENT) {
3672 file += "{\\setlength\\parindent{0pt}\n";
3675 file += "\\begin{minipage}";
3676 switch(pextra_alignment) {
3677 case MINIPAGE_ALIGN_TOP:
3680 case MINIPAGE_ALIGN_MIDDLE:
3683 case MINIPAGE_ALIGN_BOTTOM:
3687 if (!pextra_width.empty()) {
3689 file += pextra_width + "}\n";
3691 //float ib = atof(par->pextra_width.c_str())/100;
3692 // string can't handle floats at present
3693 // so I'll do a conversion by hand knowing that
3694 // the limits are 0.0 to 1.0. ARRae.
3696 switch (pextra_widthp.length()) {
3702 file += pextra_widthp;
3706 file += pextra_widthp;
3708 file += "\\columnwidth}\n";
3711 if (par_sep == BufferParams::PARSEP_INDENT) {
3712 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3715 minipage_open = true;
3716 minipage_open_depth = depth;
3719 #ifdef WITH_WARNINGS
3720 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3721 //I disabled it because it breaks when lists span on several
3724 if (style.isEnvironment()){
3725 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3726 #ifdef FANCY_FOOTNOTE_CODE
3727 if (foot_count < 0) {
3728 // flag that footnote[mark][text] should be
3729 // used for any footnotes from now on
3731 foot_this_level = true;
3734 file += "\\begin{" + style.latexname() + "}{"
3735 + labelwidthstring + "}\n";
3736 } else if (style.labeltype == LABEL_BIBLIO) {
3738 file += "\\begin{" + style.latexname() + "}{"
3739 + bibitemWidthest() + "}\n";
3740 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3741 #ifdef FANCY_FOOTNOTE_CODE
3742 if (foot_count < 0) {
3743 // flag that footnote[mark][text] should be
3744 // used for any footnotes from now on
3746 foot_this_level = true;
3749 file += "\\begin{" + style.latexname() + '}'
3750 + style.latexparam() + '\n';
3752 file += "\\begin{" + style.latexname() + '}'
3753 + style.latexparam() + '\n';
3756 LyXParagraph * par = this;
3758 par = par->TeXOnePar(file, texrow,
3759 foot, foot_texrow, foot_count);
3761 if (minipage_open && par && !style.isEnvironment() &&
3762 (par->pextra_type == PEXTRA_MINIPAGE) &&
3763 par->pextra_start_minipage) {
3764 file += "\\end{minipage}\n";
3766 if (par_sep == BufferParams::PARSEP_INDENT) {
3770 minipage_open = false;
3772 if (par && par->depth > depth) {
3773 if (textclasslist.Style(current_view->buffer()->params.textclass,
3774 par->layout).isParagraph()
3776 && !suffixIs(file, "\n\n")) {
3777 // There should be at least one '\n' already
3778 // but we need there to be two for Standard
3779 // paragraphs that are depth-increment'ed to be
3780 // output correctly. However, tables can
3781 // also be paragraphs so don't adjust them.
3786 par = par->TeXDeeper(file, texrow,
3787 foot, foot_texrow, foot_count);
3789 if (par && par->layout == layout && par->depth == depth &&
3790 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3791 if (par->pextra_hfill && par->Previous() &&
3792 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3793 file += "\\hfill{}\n";
3796 if (par_sep == BufferParams::PARSEP_INDENT) {
3797 file += "{\\setlength\\parindent{0pt}\n";
3800 file += "\\begin{minipage}";
3801 switch(par->pextra_alignment) {
3802 case MINIPAGE_ALIGN_TOP:
3805 case MINIPAGE_ALIGN_MIDDLE:
3808 case MINIPAGE_ALIGN_BOTTOM:
3812 if (!par->pextra_width.empty()) {
3814 file += par->pextra_width;
3817 //float ib = atof(par->pextra_widthp.c_str())/100;
3818 // string can't handle floats at present
3819 // so I'll do a conversion by hand knowing that
3820 // the limits are 0.0 to 1.0. ARRae.
3822 switch (par->pextra_widthp.length()) {
3828 file += par->pextra_widthp;
3832 file += par->pextra_widthp;
3834 file += "\\columnwidth}\n";
3837 if (par_sep == BufferParams::PARSEP_INDENT) {
3838 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3841 minipage_open = true;
3842 minipage_open_depth = par->depth;
3845 && par->layout == layout
3846 && par->depth == depth
3847 && par->pextra_type == pextra_type);
3849 if (style.isEnvironment()) {
3850 file += "\\end{" + style.latexname() + '}';
3851 // maybe this should go after the minipage closes?
3852 if (foot_this_level) {
3853 if (foot_count >= 1) {
3854 if (foot_count > 1) {
3855 file += "\\addtocounter{footnote}{-";
3856 file += tostr(foot_count - 1);
3860 texrow += foot_texrow;
3862 foot_texrow.reset();
3867 if (minipage_open && (minipage_open_depth == depth) &&
3868 (!par || par->pextra_start_minipage ||
3869 par->pextra_type != PEXTRA_MINIPAGE)) {
3870 file += "\\end{minipage}\n";
3872 if (par_sep == BufferParams::PARSEP_INDENT) {
3876 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3877 file += "\\medskip\n\n";
3881 minipage_open = false;
3884 file += "\\end{LyXParagraphIndent}\n";
3887 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3888 && par->pextra_hfill)) {
3892 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3893 return par; // ale970302
3897 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3898 string & foot, TexRow & foot_texrow,
3901 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3902 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3903 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3904 "No footnote!" << endl;
3906 LyXParagraph * par = this;
3907 LyXLayout const & style = textclasslist.Style(current_view->buffer()->params.textclass,
3908 previous->GetLayout());
3910 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3911 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3912 "Float other than footnote in command"
3913 " with moving argument is illegal" << endl;
3916 if (footnotekind != LyXParagraph::FOOTNOTE
3917 && footnotekind != LyXParagraph::MARGIN
3919 && !suffixIs(file, '\n')) {
3920 // we need to ensure that real floats like tables and figures
3921 // have their \begin{} on a new line otherwise we can get
3922 // incorrect results when using the endfloat.sty package
3923 // especially if two floats follow one another. ARRae 981022
3924 // NOTE: if the file is length 0 it must have just been
3925 // written out so we assume it ended with a '\n'
3930 BufferParams * params = ¤t_view->buffer()->params;
3931 bool footer_in_body = true;
3932 switch (footnotekind) {
3933 case LyXParagraph::FOOTNOTE:
3934 if (style.intitle) {
3935 file += "\\thanks{\n";
3936 footer_in_body = false;
3938 if (foot_count == -1) {
3939 // we're at depth 0 so we can use:
3940 file += "\\footnote{%\n";
3941 footer_in_body = false;
3943 file += "\\footnotemark{}%\n";
3945 // we only need this when there are
3946 // multiple footnotes
3947 foot += "\\stepcounter{footnote}";
3949 foot += "\\footnotetext{%\n";
3950 foot_texrow.start(this, 0);
3951 foot_texrow.newline();
3956 case LyXParagraph::MARGIN:
3957 file += "\\marginpar{\n";
3959 case LyXParagraph::FIG:
3960 if (pextra_type == PEXTRA_FLOATFLT
3961 && (!pextra_width.empty()
3962 || !pextra_widthp.empty())) {
3964 if (!pextra_width.empty())
3965 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3966 pextra_width.c_str());
3969 "\\begin{floatingfigure}{%f\\textwidth}\n",
3970 atoi(pextra_widthp.c_str())/100.0);
3973 file += "\\begin{figure}";
3974 if (!params->float_placement.empty()) {
3976 file += params->float_placement;
3983 case LyXParagraph::TAB:
3984 file += "\\begin{table}";
3985 if (!params->float_placement.empty()) {
3987 file += params->float_placement;
3993 case LyXParagraph::WIDE_FIG:
3994 file += "\\begin{figure*}";
3995 if (!params->float_placement.empty()) {
3997 file += params->float_placement;
4003 case LyXParagraph::WIDE_TAB:
4004 file += "\\begin{table*}";
4005 if (!params->float_placement.empty()) {
4007 file += params->float_placement;
4013 case LyXParagraph::ALGORITHM:
4014 file += "\\begin{algorithm}\n";
4019 if (footnotekind != LyXParagraph::FOOTNOTE
4020 || !footer_in_body) {
4021 // Process text for all floats except footnotes in body
4023 LyXLayout const & style =
4024 textclasslist.Style(current_view->buffer()->params.textclass,
4027 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4029 if (style.isEnvironment()
4030 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4031 // Allows the use of minipages within float
4032 // environments. Shouldn't be circular because
4033 // we don't support footnotes inside
4034 // floats (yet). ARRae
4035 par = par->TeXEnvironment(file, texrow,
4039 par = par->TeXOnePar(file, texrow,
4044 if (par && !par->IsDummy() && par->depth > depth) {
4045 par = par->TeXDeeper(file, texrow,
4049 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4051 // process footnotes > depth 0 or in environments separately
4052 // NOTE: Currently don't support footnotes within footnotes
4053 // even though that is possible using the \footnotemark
4055 TexRow dummy_texrow;
4056 int dummy_count = 0;
4058 LyXLayout const & style =
4059 textclasslist.Style(current_view->buffer()->params.textclass,
4062 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4064 if (style.isEnvironment()
4065 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4066 // Allows the use of minipages within float
4067 // environments. Shouldn't be circular because
4068 // we don't support footnotes inside
4069 // floats (yet). ARRae
4070 par = par->TeXEnvironment(foot, foot_texrow,
4071 dummy, dummy_texrow,
4074 par = par->TeXOnePar(foot, foot_texrow,
4075 dummy, dummy_texrow,
4079 if (par && !par->IsDummy() && par->depth > depth) {
4080 par = par->TeXDeeper(foot, foot_texrow,
4081 dummy, dummy_texrow,
4085 && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4087 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4088 "Footnote in a Footnote -- not supported"
4093 switch (footnotekind) {
4094 case LyXParagraph::FOOTNOTE:
4095 if (footer_in_body) {
4096 // This helps tell which of the multiple
4097 // footnotetexts an error was in.
4099 foot_texrow.newline();
4104 case LyXParagraph::MARGIN:
4107 case LyXParagraph::FIG:
4108 if (pextra_type == PEXTRA_FLOATFLT
4109 && (!pextra_width.empty()
4110 || !pextra_widthp.empty()))
4111 file += "\\end{floatingfigure}";
4113 file += "\\end{figure}";
4115 case LyXParagraph::TAB:
4116 file += "\\end{table}";
4118 case LyXParagraph::WIDE_FIG:
4119 file += "\\end{figure*}";
4121 case LyXParagraph::WIDE_TAB:
4122 file += "\\end{table*}";
4124 case LyXParagraph::ALGORITHM:
4125 file += "\\end{algorithm}";
4129 if (footnotekind != LyXParagraph::FOOTNOTE
4130 && footnotekind != LyXParagraph::MARGIN) {
4131 // we need to ensure that real floats like tables and figures
4132 // have their \end{} on a line of their own otherwise we can
4133 // get incorrect results when using the endfloat.sty package.
4138 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4143 void LyXParagraph::SetPExtraType(int type, char const * width,
4144 char const * widthp)
4147 pextra_width = width;
4148 pextra_widthp = widthp;
4150 if (textclasslist.Style(current_view->buffer()->params.textclass,
4151 layout).isEnvironment()) {
4156 while (par && (par->layout == layout)
4157 && (par->depth == depth)) {
4159 par = par->Previous();
4161 par = par->FirstPhysicalPar();
4162 while (par && par->depth > depth) {
4163 par = par->Previous();
4165 par = par->FirstPhysicalPar();
4169 while (par && (par->layout == layout)
4170 && (par->depth == depth)) {
4171 par->pextra_type = type;
4172 par->pextra_width = width;
4173 par->pextra_widthp = widthp;
4174 par = par->NextAfterFootnote();
4175 if (par && (par->depth > depth))
4176 par->SetPExtraType(type, width, widthp);
4177 while (par && ((par->depth > depth) || par->IsDummy()))
4178 par = par->NextAfterFootnote();
4184 void LyXParagraph::UnsetPExtraType()
4186 if (pextra_type == PEXTRA_NONE)
4189 pextra_type = PEXTRA_NONE;
4190 pextra_width.clear();
4191 pextra_widthp.clear();
4193 if (textclasslist.Style(current_view->buffer()->params.textclass,
4194 layout).isEnvironment()) {
4199 while (par && (par->layout == layout)
4200 && (par->depth == depth)) {
4202 par = par->Previous();
4204 par = par->FirstPhysicalPar();
4205 while (par && par->depth > depth) {
4206 par = par->Previous();
4208 par = par->FirstPhysicalPar();
4212 while (par && (par->layout == layout)
4213 && (par->depth == depth)) {
4214 par->pextra_type = PEXTRA_NONE;
4215 par->pextra_width.clear();
4216 par->pextra_widthp.clear();
4217 par = par->NextAfterFootnote();
4218 if (par && (par->depth > depth))
4219 par->UnsetPExtraType();
4220 while (par && ((par->depth > depth) || par->IsDummy()))
4221 par = par->NextAfterFootnote();
4227 bool LyXParagraph::IsHfill(size_type pos) const
4229 return IsHfillChar(GetChar(pos));
4233 bool LyXParagraph::IsInset(size_type pos) const
4235 return IsInsetChar(GetChar(pos));
4239 bool LyXParagraph::IsFloat(size_type pos) const
4241 return IsFloatChar(GetChar(pos));
4245 bool LyXParagraph::IsNewline(size_type pos) const
4249 tmp = IsNewlineChar(GetChar(pos));
4254 bool LyXParagraph::IsSeparator(size_type pos) const
4256 return IsSeparatorChar(GetChar(pos));
4260 bool LyXParagraph::IsLineSeparator(size_type pos) const
4262 return IsLineSeparatorChar(GetChar(pos));
4266 bool LyXParagraph::IsKomma(size_type pos) const
4268 return IsKommaChar(GetChar(pos));
4272 /// Used by the spellchecker
4273 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4275 unsigned char c = GetChar(pos);
4276 if (IsLetterChar(c))
4278 // '\0' is not a letter, allthough every string contains "" (below)
4281 // We want to pass the ' and escape chars to ispell
4282 string extra = lyxrc->isp_esc_chars + '\'';
4286 return contains(extra, ch);
4290 bool LyXParagraph::IsWord(size_type pos ) const
4292 return IsWordChar(GetChar(pos)) ;