1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
14 #pragma implementation "lyxparagraph.h"
17 #include "lyxparagraph.h"
18 #include "support/textutils.h"
21 #include "tex-strings.h"
22 #include "bufferparams.h"
23 #include "support/FileInfo.h"
25 #include "LaTeXFeatures.h"
26 #include "insets/insetinclude.h"
27 #include "support/filetools.h"
28 #include "lyx_gui_misc.h"
32 extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
33 extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
34 int tex_code_break_column = 72; // needs non-zero initialization. set later.
35 // this is a bad idea, but how can LyXParagraph find its buffer to get
36 // parameters? (JMarc)
37 extern BufferView * current_view;
42 extern string bibitemWidthest();
44 /* this is a minibuffer */
45 static char minibuffer_char;
46 static LyXFont minibuffer_font;
47 static Inset * minibuffer_inset;
50 // Initialization of the counter for the paragraph id's,
51 // declared in lyxparagraph.h
52 unsigned int LyXParagraph::paragraph_id = 0;
55 LyXParagraph::LyXParagraph()
57 text.reserve(500); // is this number too big?
59 for (int i = 0; i < 10; ++i) setCounter(i , 0);
69 footnoteflag = LyXParagraph::NO_FOOTNOTE;
71 align = LYX_ALIGN_BLOCK;
73 /* table stuff -- begin*/
75 /* table stuff -- end*/
77 bibkey = 0; // ale970302
82 /* this konstruktor inserts the new paragraph in a list */
83 LyXParagraph::LyXParagraph(LyXParagraph * par)
85 #warning we also need a reserve here
86 #warning this would be a nice place to shrink par
87 for (int i = 0; i < 10; ++i) setCounter(i, 0);
93 next->previous = this;
95 previous->next = this;
100 footnoteflag = LyXParagraph::NO_FOOTNOTE;
101 footnotekind = LyXParagraph::FOOTNOTE;
103 /* table stuff -- begin*/
105 /* table stuff -- end*/
108 bibkey = 0; // ale970302
114 void LyXParagraph::writeFile(FILE * file, BufferParams & params,
115 char footflag, char dth)
117 LyXFont font1, font2;
123 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
125 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
127 /* The beginning or the end of a footnote environment? */
128 if (footflag != footnoteflag) {
129 footflag = footnoteflag;
131 fprintf(file, "\n\\begin_float %s ",
132 string_footnotekinds[footnotekind]);
135 fprintf(file, "\n\\end_float ");
139 /* The beginning or end of a deeper (i.e. nested) area? */
142 while (depth > dth) {
143 fprintf(file, "\n\\begin_deeper ");
148 while (depth < dth) {
149 fprintf(file, "\n\\end_deeper ");
155 /* First write the layout */
156 fprintf(file, "\n\\layout %s\n",
157 textclasslist.NameOfLayout(params.textclass, layout)
160 /* maybe some vertical spaces */
161 if (added_space_top.kind() != VSpace::NONE)
162 fprintf(file, "\\added_space_top %s ",
163 added_space_top.asLyXCommand().c_str());
164 if (added_space_bottom.kind() != VSpace::NONE)
165 fprintf(file, "\\added_space_bottom %s ",
166 added_space_bottom.asLyXCommand().c_str());
168 /* The labelwidth string used in lists */
169 if (!labelwidthstring.empty())
170 fprintf(file, "\\labelwidthstring %s\n",
171 labelwidthstring.c_str());
173 /* Lines above or below? */
175 fprintf(file, "\\line_top ");
177 fprintf(file, "\\line_bottom ");
179 /* Pagebreaks above or below? */
181 fprintf(file, "\\pagebreak_top ");
182 if (pagebreak_bottom)
183 fprintf(file, "\\pagebreak_bottom ");
185 /* Start of appendix? */
186 if (start_of_appendix)
187 fprintf(file, "\\start_of_appendix ");
191 fprintf(file, "\\noindent ");
194 if (align != LYX_ALIGN_LAYOUT) {
196 case LYX_ALIGN_LEFT: h = 1; break;
197 case LYX_ALIGN_RIGHT: h = 2; break;
198 case LYX_ALIGN_CENTER: h = 3; break;
199 default: h = 0; break;
201 fprintf(file, "\\align %s ", string_align[h]);
203 if (pextra_type != PEXTRA_NONE) {
204 fprintf(file, "\\pextra_type %d", pextra_type);
205 if (pextra_type == PEXTRA_MINIPAGE) {
206 fprintf(file, " \\pextra_alignment %d",
209 fprintf(file, " \\pextra_hfill %d",
211 if (pextra_start_minipage)
213 " \\pextra_start_minipage %d",
214 pextra_start_minipage);
216 if (!pextra_width.empty()) {
217 fprintf(file, " \\pextra_width %s",
219 .asLyXCommand().c_str());
220 } else if (!pextra_widthp.empty()) {
221 fprintf(file, " \\pextra_widthp %s",
222 pextra_widthp.c_str());
228 /* Dummy layout. This means that a footnote ended */
229 fprintf(file, "\n\\end_float ");
230 footflag = LyXParagraph::NO_FOOTNOTE;
233 /* It might be a table */
235 fprintf(file, "\\LyXTable\n");
243 font1 = LyXFont(LyXFont::ALL_INHERIT);
246 for (size_type i = 0; i < size(); i++) {
252 // Write font changes
253 font2 = GetFontSettings(i);
254 if (font2 != font1) {
255 font2.lyxWriteChanges(font1, file);
265 if (inset->DirectWrite()) {
266 // international char, let it write
267 // code directly so it's shorter in
271 fprintf(file, "\n\\begin_inset ");
273 fprintf(file, "\n\\end_inset \n");
279 fprintf(file, "\n\\newline \n");
283 fprintf(file, "\n\\hfill \n");
286 case META_PROTECTED_SEPARATOR:
287 fprintf(file, "\n\\protected_separator \n");
291 fprintf(file, "\n\\backslash \n");
295 if (i + 1 < size() && GetChar(i + 1) == ' ') {
296 fprintf(file, ".\n");
302 if ((column > 70 && c == ' ')
307 // this check is to amend a bug. LyX sometimes
308 // inserts '\0' this could cause problems.
310 fprintf(file, "%c", c);
312 lyxerr << "ERROR (LyXParagraph::writeFile):"
313 " NULL char in structure." << endl;
319 // now write the next paragraph
321 next->writeFile(file, params, footflag, dth);
325 void LyXParagraph::validate(LaTeXFeatures & features)
327 // this will be useful later
328 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
332 if (line_top || line_bottom)
333 features.lyxline = true;
336 features.layout[GetLayout()] = true;
339 for (FontList::const_iterator cit = fontlist.begin();
340 cit != fontlist.end(); ++cit) {
341 if ((*cit).font.noun() == LyXFont::ON) {
342 lyxerr[Debug::LATEX] << "font.noun: "
343 << (*cit).font.noun()
345 features.noun = true;
346 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
347 << (*cit).font.stateText()
350 switch ((*cit).font.color()) {
352 case LyXFont::INHERIT_COLOR:
353 case LyXFont::IGNORE_COLOR: break;
355 features.color = true;
356 lyxerr[Debug::LATEX] << "Color enabled. Font: "
357 << (*cit).font.stateText()
363 FontTable * tmpfonttable = fonttable;
364 while (tmpfonttable) {
365 if (tmpfonttable->font.noun() == LyXFont::ON) {
366 lyxerr[Debug::LATEX] << "font.noun: "
367 << tmpfonttable->font.noun()
369 features.noun = true;
370 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
371 << tmpfonttable->font.stateText()
374 switch (tmpfonttable->font.color()) {
376 case LyXFont::INHERIT_COLOR:
377 case LyXFont::IGNORE_COLOR:
380 features.color = true;
381 lyxerr[Debug::LATEX] << "Color enabled. Font: "
382 << tmpfonttable->font.stateText()
385 tmpfonttable = tmpfonttable->next;
389 for (InsetList::const_iterator cit = insetlist.begin();
390 cit != insetlist.end(); ++cit) {
391 (*cit).inset->Validate(features);
395 InsetTable * tmpinsettable = insettable;
396 while (tmpinsettable) {
397 if (tmpinsettable->inset) {
398 tmpinsettable->inset->Validate(features);
400 tmpinsettable = tmpinsettable->next;
403 if (table && table->IsLongTable())
404 features.longtable = true;
405 if (pextra_type == PEXTRA_INDENT)
406 features.LyXParagraphIndent = true;
407 if (pextra_type == PEXTRA_FLOATFLT)
408 features.floatflt = true;
409 if (layout.needprotect
410 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
411 features.NeedLyXFootnoteCode = true;
412 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
413 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
414 features.NeedLyXMinipageIndent = true;
415 if (table && table->NeedRotating())
416 features.rotating = true;
417 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
418 features.algorithm = true;
422 /* first few functions needed for cut and paste and paragraph breaking */
423 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos)
425 minibuffer_char = GetChar(pos);
426 minibuffer_font = GetFontSettings(pos);
427 minibuffer_inset = 0;
428 if (minibuffer_char == LyXParagraph::META_INSET) {
430 minibuffer_inset = GetInset(pos)->Clone();
432 minibuffer_inset = 0;
433 minibuffer_char = ' ';
434 // This reflects what GetInset() does (ARRae)
439 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
441 minibuffer_char = GetChar(pos);
442 minibuffer_font = GetFontSettings(pos);
443 minibuffer_inset = 0;
444 if (minibuffer_char == LyXParagraph::META_INSET) {
446 minibuffer_inset = GetInset(pos);
447 // This is a little hack since I want exactly
448 // the inset, not just a clone. Otherwise
449 // the inset would be deleted when calling Erase(pos)
451 for (InsetList::iterator it = insetlist.begin();
452 it != insetlist.end(); ++it) {
453 if ((*it).pos == pos) {
460 InsetTable * tmpi = insettable;
461 while (tmpi && tmpi->pos != pos) {
464 if (tmpi) { /* This should always be true */
469 minibuffer_inset = 0;
470 minibuffer_char = ' ';
471 // This reflects what GetInset() does (ARRae)
476 /* Erase(pos); now the caller is responsible for that*/
480 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
482 InsertChar(pos, minibuffer_char);
483 SetFont(pos, minibuffer_font);
484 if (minibuffer_char == LyXParagraph::META_INSET)
485 InsertInset(pos, minibuffer_inset);
488 /* end of minibuffer */
492 void LyXParagraph::Clear()
497 pagebreak_top = false;
498 pagebreak_bottom = false;
500 added_space_top = VSpace(VSpace::NONE);
501 added_space_bottom = VSpace(VSpace::NONE);
503 align = LYX_ALIGN_LAYOUT;
507 pextra_type = PEXTRA_NONE;
508 pextra_width.clear();
509 pextra_widthp.clear();
510 pextra_alignment = MINIPAGE_ALIGN_TOP;
511 pextra_hfill = false;
512 pextra_start_minipage = false;
515 labelwidthstring.clear();
519 start_of_appendix = false;
523 /* the destructor removes the new paragraph from the list */
524 LyXParagraph::~LyXParagraph()
527 previous->next = next;
529 next->previous = previous;
532 InsetTable * tmpinset;
534 tmpinset = insettable;
535 insettable = insettable->next;
537 delete tmpinset->inset;
539 if (insettable && insettable->next == insettable) {
540 // somehow this recursion appears occasionally
541 // but I can't find where. This bandaid
542 // helps but isn't the best fix. (ARRae)
543 if (insettable->inset) {
544 delete insettable->inset;
554 fonttable = fonttable->next;
559 /* table stuff -- begin*/
562 /* table stuff -- end*/
570 void LyXParagraph::Erase(LyXParagraph::size_type pos)
572 /* > because last is the next unused position, and you can
573 * use it if you want */
575 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
576 NextAfterFootnote()->Erase(pos - text.size() - 1);
578 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
579 "position does not exist." << endl;
582 if (pos < size()) { // last is free for insertation, but should be empty
584 /* if it is an inset, delete the inset entry */
585 if (text[pos] == LyXParagraph::META_INSET) {
587 for(InsetList::iterator it = insetlist.begin();
588 it != insetlist.end(); ++it) {
589 if ((*it).pos == pos) {
597 /* if it is an inset, delete the inset entry */
598 if (text[pos] == LyXParagraph::META_INSET) {
600 InsetTable *tmpi = insettable;
601 InsetTable *tmpi2 = tmpi;
602 while (tmpi && tmpi->pos != pos) {
606 if (tmpi) { // this should always be true
607 if (tmpi->inset) // delete the inset if it exists
609 if (tmpi == insettable)
610 insettable = tmpi->next;
612 tmpi2->next = tmpi->next;
617 text.erase(text.begin() + pos);
619 /* erase entries in the tables */
620 for(FontList::iterator it = fontlist.begin();
621 it != fontlist.end(); ++it) {
622 if (pos >= (*it).pos && pos <= (*it).pos_end) {
623 if ((*it).pos == (*it).pos_end) {
630 /* update all other entries */
631 for(FontList::iterator it = fontlist.begin();
632 it != fontlist.end(); ++it) {
635 if ((*it).pos_end >= pos)
639 /* update the inset table */
640 for(InsetList::iterator it = insetlist.begin();
641 it != insetlist.end(); ++it) {
646 /* erase entries in the tables */
648 FontTable * tmp = fonttable;
649 FontTable * prev = 0;
650 while (tmp && !found) {
651 if (pos >= tmp->pos && pos <= tmp->pos_end)
659 if (found && tmp->pos == tmp->pos_end) {
660 /* if it is a multi-character font entry, we just make
661 * it smaller (see update below), otherwise we should
664 prev->next = tmp->next;
666 fonttable = tmp->next;
671 /* update all other entries */
677 if (tmp->pos_end >= pos)
682 /* update the inset table */
683 InsetTable * tmpi = insettable;
691 lyxerr << "ERROR (LyXParagraph::Erase): "
692 "can't erase non-existant char." << endl;
697 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
699 /* > because last is the next unused position, and you can
700 * use it if you want */
703 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
704 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
707 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
708 "position does not exist." << endl;
711 text.insert(text.begin() + pos, c);
713 // update the font table
714 for(FontList::iterator it = fontlist.begin();
715 it != fontlist.end(); ++it) {
716 if ((*it).pos >= pos)
718 if ((*it).pos_end >= pos)
721 // update the inset table
722 for(InsetList::iterator it = insetlist.begin();
723 it != insetlist.end(); ++it) {
724 if ((*it).pos >= pos)
728 /* update the font table */
729 FontTable * tmp = fonttable;
733 if (tmp->pos_end >= pos)
738 /* update the inset table */
739 InsetTable * tmpi = insettable;
741 if (tmpi->pos >= pos)
749 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
752 /* > because last is the next unused position, and you can
753 * use it if you want */
756 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
758 ->InsertInset(pos - text.size() - 1, inset);
760 lyxerr << "ERROR (LyXParagraph::InsertInset): "
761 "position does not exist: " << pos << endl;
764 if (text[pos] != LyXParagraph::META_INSET) {
765 lyxerr << "ERROR (LyXParagraph::InsertInset): "
766 "there is no LyXParagraph::META_INSET" << endl;
775 insetlist.push_back(tmp);
780 /* add a new entry in the inset table */
781 InsetTable * tmpi = new InsetTable;
784 tmpi->next = insettable;
791 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
795 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
796 return NextAfterFootnote()
797 ->GetInset(pos - text.size() - 1);
799 lyxerr << "ERROR (LyXParagraph::GetInset): "
800 "position does not exist: "
807 for(InsetList::iterator it = insetlist.begin();
808 it != insetlist.end(); ++it) {
809 if ((*it).pos == pos) {
813 lyxerr << "ERROR (LyXParagraph::GetInset): "
814 "Inset does not exist: " << pos << endl;
815 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
816 // Did this commenting out introduce a bug? So far I have not
817 // seen any, please enlighten me. (Lgb)
818 // My guess is that since the inset does not exist, we might
819 // as well replace it with a space to prevent crashes. (Asger)
823 InsetTable * tmpi = insettable;
825 while (tmpi && tmpi->pos != pos)
831 lyxerr << "ERROR (LyXParagraph::GetInset): "
832 "Inset does not exist: " << pos << endl;
833 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
834 // Did this commenting out introduce a bug? So far I have not
835 // seen any, please enlighten me. (Lgb)
836 // My guess is that since the inset does not exist, we might
837 // as well replace it with a space to prevent crashes. (Asger)
844 // Gets uninstantiated font setting at position.
845 // Optimized after profiling. (Asger)
846 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos)
850 for(FontList::iterator it = fontlist.begin();
851 it != fontlist.end(); ++it) {
852 if (pos >= (*it).pos && pos <= (*it).pos_end)
856 FontTable * tmp = fonttable;
858 if (pos >= tmp->pos && pos <= tmp->pos_end)
864 /* > because last is the next unused position, and you can
865 * use it if you want */
866 else if (pos > size()) {
868 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
869 return NextAfterFootnote()
870 ->GetFontSettings(pos - text.size() - 1);
872 // Why is it an error to ask for the font of a
873 // position that does not exist? Would it be
874 // enough for this to be anable on debug?
875 // We want strict error checking, but it's ok to only
876 // have it when debugging. (Asger)
877 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
878 "position does not exist. "
879 << pos << " (" << static_cast<int>(pos)
883 return GetFontSettings(pos - 1);
885 return LyXFont(LyXFont::ALL_INHERIT);
889 // Gets the fully instantiated font at a given position in a paragraph
890 // This is basically the same function as LyXText::GetFont() in text2.C.
891 // The difference is that this one is used for generating the LaTeX file,
892 // and thus cosmetic "improvements" are disallowed: This has to deliver
893 // the true picture of the buffer. (Asger)
894 // If position is -1, we get the layout font of the paragraph.
895 // If position is -2, we get the font of the manual label of the paragraph.
896 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos)
899 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
901 LyXParagraph::size_type main_body = 0;
902 if (layout.labeltype == LABEL_MANUAL)
903 main_body = BeginningOfMainBody();
908 layoutfont = layout.labelfont;
910 layoutfont = layout.font;
911 tmpfont = GetFontSettings(pos);
912 tmpfont.realize(layoutfont);
914 // process layoutfont for pos == -1 and labelfont for pos < -1
916 tmpfont = layout.font;
918 tmpfont = layout.labelfont;
921 // check for environment font information
922 char par_depth = GetDepth();
923 LyXParagraph * par = this;
924 while (par && par_depth && !tmpfont.resolved()) {
925 par = par->DepthHook(par_depth - 1);
927 tmpfont.realize(textclasslist.
928 Style(GetCurrentTextClass(),
929 par->GetLayout()).font);
930 par_depth = par->GetDepth();
934 tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
939 /// Returns the height of the highest font in range
940 LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
942 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
944 for(FontList::const_iterator cit = fontlist.begin();
945 cit != fontlist.end(); ++cit) {
946 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
947 LyXFont::FONT_SIZE size = (*cit).font.size();
948 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
953 FontTable * tmp = fonttable;
955 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
956 LyXFont::FONT_SIZE size = tmp->font.size();
957 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
967 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
970 /* a workaround to 'fix' some bugs in text-class */
972 // This function is important. It should not work around bugs.
973 // Let's find the bugs instead and fix them. (Asger)
974 lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
975 " bad position " << pos << endl;
983 /* > because last is the next unused position, and you can
984 * use it if you want */
985 else if (pos > size()) {
986 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
987 return NextAfterFootnote()
988 ->GetChar(pos - text.size() - 1);
990 lyxerr << "ERROR (LyXParagraph::GetChar): "
991 "position does not exist."
992 << pos << " (" << static_cast<int>(pos)
997 /* we should have a footnote environment */
998 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
999 // Notice that LyX does request the
1000 // last char from time to time. (Asger)
1001 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1002 // "expected footnote." << endl;
1005 switch (next->footnotekind) {
1006 case LyXParagraph::FOOTNOTE:
1007 return LyXParagraph::META_FOOTNOTE;
1008 case LyXParagraph::MARGIN:
1009 return LyXParagraph::META_MARGIN;
1010 case LyXParagraph::FIG:
1011 case LyXParagraph::WIDE_FIG:
1012 return LyXParagraph::META_FIG;
1013 case LyXParagraph::TAB:
1014 case LyXParagraph::WIDE_TAB:
1015 return LyXParagraph::META_TAB;
1016 case LyXParagraph::ALGORITHM:
1017 return LyXParagraph::META_ALGORITHM;
1019 return '\0'; // to shut up gcc
1024 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
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 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos)
1082 //Added 98/9/21 by REH
1083 // return an string of the current word, and the end of the word
1086 // the current word is defined as starting at the first character from
1087 // the immediate left of lastpospos which meets the definition of IsLetter(),
1088 // continuing to the last character to the right of this meeting
1092 // i just left this in from GetChar()
1094 #ifdef DEVEL_VERSION
1095 /* a workaround to 'fix' some bugs in text-class */
1097 // This function is important. It should not work around bugs.
1098 // Let's find the bugs instead and fix them. (Asger)
1099 lyxerr << "FATAL ERROR (LyXParagraph::GetWord):"
1100 " bad position " << lastpos << endl;
1110 //i think the devcode aborts before this, but why not be
1112 if (lastpos < 0) lastpos= 0;
1115 // move back until we have a letter
1117 //there's no real reason to have firstpos & lastpos as
1118 //separate variables as this is written, but maybe someon
1119 // will want to return firstpos in the future.
1121 //since someone might have typed a punctuation first
1122 int firstpos = lastpos;
1124 while ((firstpos >= 0) && !IsLetter(firstpos))
1127 // now find the beginning by looking for a nonletter
1129 while ((firstpos>= 0) && IsLetter(firstpos))
1132 // the above is now pointing to the preceeding non-letter
1136 // so copy characters into theword until we get a nonletter
1137 // note that this can easily exceed lastpos, wich means
1138 // that if used in the middle of a word, the whole word
1141 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1148 LyXParagraph::size_type LyXParagraph::Last()
1150 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1151 return text.size() + NextAfterFootnote()->Last() + 1;
1152 /* the 1 is the symbol
1159 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1161 /* > because last is the next unused position, and you can
1162 * use it if you want */
1165 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1166 return NextAfterFootnote()
1167 ->ParFromPos(pos - text.size() - 1);
1169 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1170 "position does not exist." << endl;
1178 int LyXParagraph::PositionInParFromPos(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 ->PositionInParFromPos(pos - text.size() - 1);
1189 "ERROR (LyXParagraph::PositionInParFromPos): "
1190 "position does not exist." << endl;
1198 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1199 LyXFont const & font)
1201 /* > because last is the next unused position, and you can
1202 * use it if you want */
1204 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1205 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1208 lyxerr << "ERROR (LyXParagraph::SetFont): "
1209 "position does not exist." << endl;
1213 LyXFont patternfont(LyXFont::ALL_INHERIT);
1215 // First, reduce font against layout/label font
1216 // Update: The SetCharFont() routine in text2.C already reduces font, so
1217 // we don't need to do that here. (Asger)
1218 // No need to simplify this because it will disappear in a new kernel. (Asger)
1220 // Next search font table
1221 for(FontList::iterator it = fontlist.begin();
1222 it != fontlist.end(); ++it) {
1223 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1225 // we found a font entry. maybe we have to
1226 // split it and create a new one
1228 if ((*it).pos != (*it).pos_end) {
1229 // more than one character
1230 if (pos == (*it).pos) {
1231 // maybe we could enlarge
1232 // the left fonttable
1233 for(FontList::iterator fit = fontlist.begin();
1234 fit != fontlist.end(); ++fit) {
1235 if (pos - 1 >= (*fit).pos
1236 && pos - 1 <= (*fit).pos_end
1237 && (*fit).font == font) {
1245 // Add a new entry in the
1246 // fonttable for the position
1249 tmp.pos_end = (*it).pos_end;
1250 tmp.font = (*it).font;
1251 (*it).pos_end = pos;
1252 fontlist.push_back(tmp);
1253 } else if (pos == (*it).pos_end) {
1254 // Add a new entry in the
1255 // fonttable for the position
1257 tmp.pos = (*it).pos;
1258 tmp.pos_end = (*it).pos_end - 1;
1259 tmp.font = (*it).font;
1260 (*it).pos = (*it).pos_end;
1261 fontlist.push_back(tmp);
1263 // Add a new entry in the
1264 // fonttable for the position
1266 tmp.pos = (*it).pos;
1267 tmp.pos_end = pos - 1;
1268 tmp.font = (*it).font;
1269 fontlist.push_back(tmp);
1272 tmp.pos_end = (*it).pos_end;
1273 tmp.font = (*it).font;
1274 fontlist.push_back(tmp);
1277 (*it).pos_end = pos;
1285 // if we did not find a font entry, but if the font at hand
1286 // is the same as default, we just forget it
1287 if (font == patternfont) return;
1289 // ok, we did not find a font entry. But maybe there is exactly
1290 // the needed font entry one position left
1291 for(FontList::iterator it = fontlist.begin();
1292 it != fontlist.end(); ++it) {
1293 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1294 && (*it).font == font) {
1299 // Add a new entry in the
1300 // fonttable for the position
1304 tmp.font = patternfont;
1305 fontlist.push_back(tmp);
1307 // Next search font table
1311 FontTable * tmp = fonttable;
1312 while (tmp && !found) {
1313 if (pos >= tmp->pos && pos <= tmp->pos_end)
1320 /* if we did not find a font entry, but if the font at hand
1321 * is the same as default, we just forget it */
1322 if (font == patternfont)
1325 /* ok, we did not find a font entry. But maybe there is exactly
1326 * the needed font entry one position left */
1329 while (tmp2 && !found) {
1330 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1336 /* ok there is one. maybe it is exactly the needed font */
1337 if (tmp2->font == font) {
1338 /* put the position under the font */
1343 /* Add a new entry in the
1344 * fonttable for the position */
1345 tmp = new FontTable;
1348 tmp->font = patternfont;
1349 tmp->next = fonttable;
1352 /* we found a font entry. maybe we have to split it and create
1355 if (tmp->pos != tmp->pos_end) { /* more than one character */
1357 if (pos == tmp->pos) {
1358 /* maybe we could enlarge the left fonttable */
1362 while (tmp2 && !found) {
1363 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1369 /* Is there is one, and is it exactly the needed font? */
1370 if (found && tmp2->font == font) {
1371 /* put the position under the font */
1377 /* Add a new entry in the
1378 * fonttable for the position */
1379 tmp2 = new FontTable;
1380 tmp2->pos = pos + 1;
1381 tmp2->pos_end = tmp->pos_end;
1382 tmp2->font = tmp->font;
1384 tmp2->next = fonttable;
1387 else if (pos == tmp->pos_end) {
1388 /* Add a new entry in the
1389 * fonttable for the position */
1390 tmp2 = new FontTable;
1391 tmp2->pos = tmp->pos;
1392 tmp2->pos_end = tmp->pos_end - 1;
1393 tmp2->font = tmp->font;
1394 tmp->pos = tmp->pos_end;
1395 tmp2->next = fonttable;
1399 /* Add a new entry in the
1400 * fonttable for the position */
1401 tmp2 = new FontTable;
1402 tmp2->pos = tmp->pos;
1403 tmp2->pos_end = pos - 1;
1404 tmp2->font = tmp->font;
1405 tmp2->next = fonttable;
1408 tmp2 = new FontTable;
1409 tmp2->pos = pos + 1;
1410 tmp2->pos_end = tmp->pos_end;
1411 tmp2->font = tmp->font;
1412 tmp2->next = fonttable;
1425 /* this function is able to hide closed footnotes */
1426 LyXParagraph * LyXParagraph::Next()
1428 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1429 LyXParagraph * tmp = next;
1431 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1433 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1434 return tmp->Next(); /* there can be more than one
1435 footnote in a logical
1438 return next; /* this should never happen! */
1445 LyXParagraph * LyXParagraph::NextAfterFootnote()
1447 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1448 LyXParagraph * tmp = next;
1449 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1451 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1452 return tmp; /* there can be more than one footnote
1453 in a logical paragraph */
1455 return next; /* this should never happen! */
1462 LyXParagraph * LyXParagraph::NextAfterFootnote() const
1464 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1465 LyXParagraph * tmp = next;
1466 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1468 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1469 return tmp; /* there can be more than one footnote
1470 in a logical paragraph */
1472 return next; /* this should never happen! */
1479 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1482 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1484 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1485 tmp = tmp->previous;
1486 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1487 return tmp; /* there can be more than one footnote
1488 in a logical paragraph */
1490 return previous; /* this should never happen! */
1497 LyXParagraph * LyXParagraph::LastPhysicalPar()
1499 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1502 LyXParagraph * tmp = this;
1504 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1505 tmp = tmp->NextAfterFootnote();
1512 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1516 LyXParagraph * tmppar = this;
1518 while (tmppar && (tmppar->IsDummy()
1519 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1520 tmppar = tmppar->previous;
1523 return this; /* this should never happen! */
1529 /* this function is able to hide closed footnotes */
1530 LyXParagraph * LyXParagraph::Previous()
1532 LyXParagraph * tmp = previous;
1537 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1538 tmp = tmp->previous;
1540 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1541 tmp = tmp->previous;
1542 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1543 return tmp->next->Previous();
1553 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1556 size_type i, pos_end, pos_first;
1557 /* create a new paragraph */
1558 LyXParagraph * par = ParFromPos(pos);
1559 LyXParagraph * firstpar = FirstPhysicalPar();
1561 LyXParagraph * tmp = new LyXParagraph(par);
1563 tmp->footnoteflag = footnoteflag;
1564 tmp->footnotekind = footnotekind;
1566 /* this is an idea for a more userfriendly layout handling, I will
1567 * see what the users say */
1569 /* layout stays the same with latex-environments */
1571 tmp->SetOnlyLayout(firstpar->layout);
1572 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1575 if (Last() > pos || !Last() || flag == 2) {
1576 tmp->SetOnlyLayout(firstpar->layout);
1577 tmp->align = firstpar->align;
1578 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1580 tmp->line_bottom = firstpar->line_bottom;
1581 firstpar->line_bottom = false;
1582 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1583 firstpar->pagebreak_bottom = false;
1584 tmp->added_space_bottom = firstpar->added_space_bottom;
1585 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1587 tmp->depth = firstpar->depth;
1588 tmp->noindent = firstpar->noindent;
1590 /* copy everything behind the break-position
1591 to the new paragraph
1594 while (ParFromPos(pos_first) != par)
1597 pos_end = pos_first + par->text.size() - 1;
1598 tmp->text.reserve(pos_end - pos);
1600 for (i = pos; i <= pos_end; i++) {
1601 par->CutIntoMinibuffer(i - pos_first);
1602 tmp->InsertFromMinibuffer(i - pos);
1605 for (i = pos_end; i >= pos; i--)
1606 par->Erase(i - pos_first);
1608 par->text.resize(par->text.size());
1611 /* just an idea of me */
1613 tmp->line_top = firstpar->line_top;
1614 tmp->pagebreak_top = firstpar->pagebreak_top;
1615 tmp->added_space_top = firstpar->added_space_top;
1616 tmp->bibkey = firstpar->bibkey;
1618 /* layout stays the same with latex-environments */
1620 firstpar->SetOnlyLayout(tmp->layout);
1621 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1622 firstpar->depth = tmp->depth;
1628 void LyXParagraph::MakeSameLayout(LyXParagraph * par)
1630 par = par->FirstPhysicalPar();
1631 footnoteflag = par->footnoteflag;
1632 footnotekind = par->footnotekind;
1634 layout = par->layout;
1635 align = par-> align;
1636 SetLabelWidthString(par->labelwidthstring);
1638 line_bottom = par->line_bottom;
1639 pagebreak_bottom = par->pagebreak_bottom;
1640 added_space_bottom = par->added_space_bottom;
1642 line_top = par->line_top;
1643 pagebreak_top = par->pagebreak_top;
1644 added_space_top = par->added_space_top;
1646 pextra_type = par->pextra_type;
1647 pextra_width = par->pextra_width;
1648 pextra_widthp = par->pextra_widthp;
1649 pextra_alignment = par->pextra_alignment;
1650 pextra_hfill = par->pextra_hfill;
1651 pextra_start_minipage = par->pextra_start_minipage;
1653 noindent = par->noindent;
1658 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1660 LyXParagraph * tmppar = this;
1663 && tmppar->previous->footnoteflag ==
1664 LyXParagraph::CLOSED_FOOTNOTE)
1665 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1666 tmppar = tmppar->previous;
1669 return this; /* this should never happen! */
1675 LyXParagraph * LyXParagraph::Clone()
1677 /* create a new paragraph */
1678 LyXParagraph * result = new LyXParagraph;
1680 result->MakeSameLayout(this);
1682 /* this is because of the dummy layout of the paragraphs that
1684 result->layout = layout;
1686 /* table stuff -- begin*/
1688 result->table = table->Clone();
1691 /* table stuff -- end*/
1694 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1697 /* copy everything behind the break-position to the new paragraph */
1699 result->text.reserve(size());
1700 for (size_type i = 0; i < size(); i++) {
1701 CopyIntoMinibuffer(i);
1702 result->InsertFromMinibuffer(i);
1708 bool LyXParagraph::HasSameLayout(LyXParagraph * par)
1710 par = par->FirstPhysicalPar();
1713 par->footnoteflag == footnoteflag &&
1714 par->footnotekind == footnotekind &&
1716 par->layout == layout &&
1718 par->align == align &&
1720 par->line_bottom == line_bottom &&
1721 par->pagebreak_bottom == pagebreak_bottom &&
1722 par->added_space_bottom == added_space_bottom &&
1724 par->line_top == line_top &&
1725 par->pagebreak_top == pagebreak_top &&
1726 par->added_space_top == added_space_top &&
1728 par->pextra_type == pextra_type &&
1729 par->pextra_width == pextra_width &&
1730 par->pextra_widthp == pextra_widthp &&
1731 par->pextra_alignment == pextra_alignment &&
1732 par->pextra_hfill == pextra_hfill &&
1733 par->pextra_start_minipage == pextra_start_minipage &&
1735 par->table == table && // what means: NO TABLE AT ALL
1737 par->noindent == noindent &&
1738 par->depth == depth);
1742 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1744 size_type i, pos_end, pos_first;
1746 /* create a new paragraph */
1747 LyXParagraph * par = ParFromPos(pos);
1749 LyXParagraph * tmp = new LyXParagraph(par);
1751 tmp->MakeSameLayout(par);
1754 /* copy everything behind the break-position to the new
1757 while (ParFromPos(pos_first) != par)
1759 pos_end = pos_first + par->text.size() - 1;
1760 /* make shure there is enough memory for the now larger
1761 paragraph. This is not neccessary, because
1762 InsertFromMinibuffer will enlarge the memory (it uses
1763 InsertChar of course). But doing it by hand
1764 is MUCH faster! (only one time, not thousend times!!) */
1765 tmp->text.reserve(pos_end - pos);
1767 for (i = pos; i <= pos_end; i++) {
1769 par->CutIntoMinibuffer(i - pos_first);
1770 tmp->InsertFromMinibuffer(i - pos);
1772 for (i = pos_end; i >= pos; i--)
1773 par->Erase(i - pos_first);
1775 par->text.resize(par->text.size());
1780 /* be carefull, this does not make any check at all */
1781 void LyXParagraph::PasteParagraph()
1783 /* copy the next paragraph to this one */
1784 LyXParagraph * the_next = Next();
1786 LyXParagraph * firstpar = FirstPhysicalPar();
1788 /* first the DTP-stuff */
1789 firstpar->line_bottom = the_next->line_bottom;
1790 firstpar->added_space_bottom = the_next->added_space_bottom;
1791 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1793 size_type pos_end = the_next->text.size() - 1;
1794 size_type pos_insert = Last();
1797 /* ok, now copy the paragraph */
1798 for (i = 0; i <= pos_end; i++) {
1799 the_next->CutIntoMinibuffer(i);
1800 InsertFromMinibuffer(pos_insert + i);
1803 /* delete the next paragraph */
1808 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1810 LyXParagraph * par = ParFromPos(pos);
1812 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1813 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1819 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1821 LyXParagraph * par = ParFromPos(pos);
1823 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1824 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1830 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout()
1832 return FirstPhysicalPar()->layout;
1836 char LyXParagraph::GetDepth()
1838 return FirstPhysicalPar()->depth;
1842 char LyXParagraph::GetAlign()
1844 return FirstPhysicalPar()->align;
1848 string LyXParagraph::GetLabestring()
1850 return FirstPhysicalPar()->labelstring;
1854 int LyXParagraph::GetFirstCounter(int i)
1856 return FirstPhysicalPar()->counter[i];
1860 /* the next two functions are for the manual labels */
1861 string LyXParagraph::GetLabelWidthString()
1863 if (!FirstPhysicalPar()->labelwidthstring.empty())
1864 return FirstPhysicalPar()->labelwidthstring;
1866 return _("Senseless with this layout!");
1870 void LyXParagraph::SetLabelWidthString(string const & s)
1872 LyXParagraph * par = FirstPhysicalPar();
1874 par->labelwidthstring = s;
1878 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1880 LyXParagraph * par = FirstPhysicalPar();
1881 LyXParagraph * ppar = 0;
1882 LyXParagraph * npar = 0;
1884 par->layout = new_layout;
1885 /* table stuff -- begin*/
1888 /* table stuff -- end*/
1889 if (par->pextra_type == PEXTRA_NONE) {
1890 if (par->Previous()) {
1891 ppar = par->Previous()->FirstPhysicalPar();
1894 && (ppar->depth > par->depth))
1895 ppar = ppar->Previous()->FirstPhysicalPar();
1898 npar = par->Next()->NextAfterFootnote();
1901 && (npar->depth > par->depth))
1902 npar = npar->Next()->NextAfterFootnote();
1904 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1906 p1 = ppar->pextra_width,
1907 p2 = ppar->pextra_widthp;
1908 ppar->SetPExtraType(ppar->pextra_type,
1909 p1.c_str(), p2.c_str());
1911 if ((par->pextra_type == PEXTRA_NONE) &&
1912 npar && (npar->pextra_type != PEXTRA_NONE)) {
1914 p1 = npar->pextra_width,
1915 p2 = npar->pextra_widthp;
1916 npar->SetPExtraType(npar->pextra_type,
1917 p1.c_str(), p2.c_str());
1923 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
1926 * par = FirstPhysicalPar(),
1930 par->layout = new_layout;
1931 par->labelwidthstring.clear();
1932 par->align = LYX_ALIGN_LAYOUT;
1933 par->added_space_top = VSpace(VSpace::NONE);
1934 par->added_space_bottom = VSpace(VSpace::NONE);
1935 /* table stuff -- begin*/
1938 /* table stuff -- end*/
1939 if (par->pextra_type == PEXTRA_NONE) {
1940 if (par->Previous()) {
1941 ppar = par->Previous()->FirstPhysicalPar();
1944 && (ppar->depth > par->depth))
1945 ppar = ppar->Previous()->FirstPhysicalPar();
1948 npar = par->Next()->NextAfterFootnote();
1951 && (npar->depth > par->depth))
1952 npar = npar->Next()->NextAfterFootnote();
1954 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1956 p1 = ppar->pextra_width,
1957 p2 = ppar->pextra_widthp;
1958 ppar->SetPExtraType(ppar->pextra_type,
1959 p1.c_str(), p2.c_str());
1961 if ((par->pextra_type == PEXTRA_NONE) &&
1962 npar && (npar->pextra_type != PEXTRA_NONE)) {
1964 p1 = npar->pextra_width,
1965 p2 = npar->pextra_widthp;
1966 npar->SetPExtraType(npar->pextra_type,
1967 p1.c_str(), p2.c_str());
1973 /* if the layout of a paragraph contains a manual label, the beginning of the
1974 * main body is the beginning of the second word. This is what the par-
1975 * function returns. If the layout does not contain a label, the main
1976 * body always starts with position 0. This differentiation is necessary,
1977 * because there cannot be a newline or a blank <= the beginning of the
1978 * main body in TeX. */
1980 int LyXParagraph::BeginningOfMainBody()
1982 if (FirstPhysicalPar() != this)
1985 // Unroll the first two cycles of the loop
1986 // and remember the previous character to
1987 // remove unnecessary GetChar() calls
1990 && GetChar(i) != LyXParagraph::META_NEWLINE) {
1992 char previous_char, temp;
1994 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
1995 // Yes, this ^ is supposed to be "= " not "== "
1998 && previous_char != ' '
1999 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2001 previous_char = temp;
2006 if (i == 0 && i == size() &&
2007 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2008 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2009 i++; /* the cursor should not jump
2010 * to the main body if there
2016 LyXParagraph * LyXParagraph::DepthHook(int deth)
2018 LyXParagraph * newpar = this;
2023 newpar = newpar->FirstPhysicalPar()->Previous();
2024 } while (newpar && newpar->GetDepth() > deth
2025 && newpar->footnoteflag == footnoteflag);
2028 if (Previous() || GetDepth())
2029 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2033 return newpar->FirstPhysicalPar();
2037 int LyXParagraph::AutoDeleteInsets()
2041 for (InsetList::iterator it = insetlist.begin();
2042 it != insetlist.end(); ++it) {
2043 if ((*it).inset->AutoDelete()) {
2050 InsetTable * tmpi = insettable;
2051 InsetTable * tmpi2 = tmpi;
2057 if (tmpi2->inset->AutoDelete()) {
2062 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2063 "cannot auto-delete insets" << endl;
2070 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2073 InsetTable * tmp = 0;
2074 for (InsetList::iterator it = insetlist.begin();
2075 it != insetlist.end(); ++it) {
2076 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2087 InsetTable * tmpi = insettable;
2088 InsetTable * tmpi2 = 0;
2090 if (tmpi->pos >= pos) {
2091 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2098 return tmpi2->inset;
2106 /* returns -1 if inset not found */
2107 int LyXParagraph::GetPositionOfInset(Inset * inset)
2110 for (InsetList::iterator it = insetlist.begin();
2111 it != insetlist.end(); ++it) {
2112 if ((*it).inset == inset) {
2116 // Think about footnotes
2117 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2118 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2119 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2121 return size() + 1 + further;
2125 /* find the entry */
2126 InsetTable * tmpi = insettable;
2127 while (tmpi && tmpi->inset != inset) {
2130 if (tmpi && tmpi->inset)
2133 /* think about footnotes */
2134 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2135 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2137 NextAfterFootnote()->GetPositionOfInset(inset);
2139 return text.size() + 1 + further;
2147 void LyXParagraph::readSimpleWholeFile(FILE * myfile)
2151 if (!feof(myfile)) {
2155 InsertChar(text.size(), c);
2156 } while (!feof(myfile));
2162 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2163 string & foot, TexRow & foot_texrow,
2166 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2167 LyXParagraph * par = next;
2168 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2171 bool further_blank_line = false;
2173 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2175 if (start_of_appendix) {
2176 file += "\\appendix\n";
2180 if (tex_code_break_column && style.isCommand()){
2185 if (pagebreak_top) {
2186 file += "\\newpage";
2187 further_blank_line = true;
2189 if (added_space_top.kind() != VSpace::NONE) {
2190 file += added_space_top.asLatexCommand();
2191 further_blank_line = true;
2195 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2196 file += "\\vspace{-1\\parskip}";
2197 further_blank_line = true;
2200 if (further_blank_line){
2205 switch (style.latextype) {
2208 file += style.latexname();
2209 file += style.latexparam();
2211 case LATEX_ITEM_ENVIRONMENT:
2213 bibkey->Latex(file, false);
2217 case LATEX_LIST_ENVIRONMENT:
2224 bool need_par = SimpleTeXOnePar(file, texrow);
2226 // Spit out footnotes
2227 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2228 && par->footnoteflag != footnoteflag) {
2229 par = par->TeXFootnote(file, texrow,
2230 foot, foot_texrow, foot_count);
2231 par->SimpleTeXOnePar(file, texrow);
2235 // Make sure that \\par is done with the font of the last
2236 // character if this has another size as the default.
2237 // This is necessary because LaTeX (and LyX on the screen)
2238 // calculates the space between the baselines according
2239 // to this font. (Matthias)
2240 LyXFont font = getFont(Last()-1);
2242 if (style.resfont.size() != font.size()) {
2244 file += font.latexSize();
2248 } else if (textclasslist.Style(GetCurrentTextClass(),
2249 GetLayout()).isCommand()){
2250 if (style.resfont.size() != font.size()) {
2252 file += font.latexSize();
2256 } else if (style.resfont.size() != font.size()){
2257 file += "{\\" + font.latexSize() + " \\par}";
2260 switch (style.latextype) {
2261 case LATEX_ITEM_ENVIRONMENT:
2262 case LATEX_LIST_ENVIRONMENT:
2263 if (par && (depth < par->depth)) {
2268 case LATEX_ENVIRONMENT:
2269 // if its the last paragraph of the current environment
2270 // skip it otherwise fall through
2272 && (par->layout != layout
2273 || par->depth != depth
2274 || par->pextra_type != pextra_type))
2277 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2278 && footnotekind != LyXParagraph::FOOTNOTE
2279 && footnotekind != LyXParagraph::MARGIN
2283 // don't insert this if we would be adding it
2284 // before or after a table in a float. This
2285 // little trick is needed in order to allow
2286 // use of tables in \subfigures or \subtables.
2292 further_blank_line = false;
2294 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2295 further_blank_line = true;
2298 if (added_space_bottom.kind() != VSpace::NONE) {
2299 file += added_space_bottom.asLatexCommand();
2300 further_blank_line = true;
2303 if (pagebreak_bottom) {
2304 file += "\\newpage";
2305 further_blank_line = true;
2308 if (further_blank_line){
2313 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2314 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2319 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2324 // This one spits out the text of the paragraph
2325 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2327 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2330 return SimpleTeXOneTablePar(file, texrow);
2333 size_type main_body;
2335 bool return_value = false;
2337 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2340 /* maybe we have to create a optional argument */
2341 if (style.labeltype != LABEL_MANUAL)
2344 main_body = BeginningOfMainBody();
2346 if (main_body > 0) {
2348 basefont = getFont(-2); // Get label font
2350 basefont = getFont(-1); // Get layout font
2358 if (style.isCommand()) {
2361 } else if (align != LYX_ALIGN_LAYOUT) {
2364 return_value = true;
2368 // Which font is currently active?
2369 LyXFont running_font = basefont;
2370 // Do we have an open font change?
2371 bool open_font = false;
2373 texrow.start(this, 0);
2375 for (size_type i = 0; i < size(); ++i) {
2377 // First char in paragraph or after label?
2378 if (i == main_body && !IsDummy()) {
2379 if (main_body > 0) {
2381 column += running_font.latexWriteEndChanges(file, basefont);
2384 basefont = getFont(-1); // Now use the layout font
2385 running_font = basefont;
2389 if (style.isCommand()) {
2392 } else if (align != LYX_ALIGN_LAYOUT) {
2395 return_value = true;
2399 file += "\\noindent ";
2403 case LYX_ALIGN_NONE:
2404 case LYX_ALIGN_BLOCK:
2405 case LYX_ALIGN_LAYOUT:
2406 case LYX_ALIGN_SPECIAL: break;
2407 case LYX_ALIGN_LEFT:
2408 file += "\\raggedright ";
2411 case LYX_ALIGN_RIGHT:
2412 file += "\\raggedleft ";
2415 case LYX_ALIGN_CENTER:
2416 file += "\\centering ";
2424 // Fully instantiated font
2425 LyXFont font = getFont(i);
2427 // Spaces at end of font change are simulated to be
2428 // outside font change, i.e. we write "\textXX{text} "
2429 // rather than "\textXX{text }". (Asger)
2430 if (open_font && c == ' ' && i <= size() - 2
2431 && !getFont(i+1).equalExceptLatex(running_font)
2432 && !getFont(i+1).equalExceptLatex(font)) {
2433 font = getFont(i+1);
2435 // We end font definition before blanks
2436 if (!font.equalExceptLatex(running_font) && open_font) {
2437 column += running_font.latexWriteEndChanges(file,
2439 running_font = basefont;
2443 // Blanks are printed before start of fontswitch
2445 // Do not print the separation of the optional argument
2446 if (i != main_body - 1) {
2447 SimpleTeXBlanks(file, texrow, i,
2448 column, font, style);
2452 // Do we need to change font?
2453 if (!font.equalExceptLatex(running_font)
2454 && i != main_body-1) {
2455 column += font.latexWriteStartChanges(file, basefont);
2456 running_font = font;
2460 if (c == LyXParagraph::META_NEWLINE) {
2461 // newlines are handled differently here than
2462 // the default in SimpleTeXSpecialChars().
2463 if (!style.newline_allowed
2464 || font.latex() == LyXFont::ON) {
2468 column += running_font.latexWriteEndChanges(file, basefont);
2471 basefont = getFont(-1);
2472 running_font = basefont;
2473 if (font.family() ==
2474 LyXFont::TYPEWRITER_FAMILY) {
2480 texrow.start(this, i+1);
2483 SimpleTeXSpecialChars(file, texrow,
2484 font, running_font, basefont,
2485 open_font, style, i, column, c);
2489 // If we have an open font definition, we have to close it
2491 running_font.latexWriteEndChanges(file, basefont);
2494 /* needed if there is an optional argument but no contents */
2495 if (main_body > 0 && main_body == size()) {
2497 return_value = false;
2500 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2501 return return_value;
2505 // This one spits out the text of a table paragraph
2506 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2508 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2512 bool return_value = false;
2513 int current_cell_number = -1;
2515 LyXLayout const & style =
2516 textclasslist.Style(GetCurrentTextClass(), GetLayout());
2517 LyXFont basefont = getFont(-1); // Get layout font
2518 // Which font is currently active?
2519 LyXFont running_font = basefont;
2520 // Do we have an open font change?
2521 bool open_font = false;
2524 if (!IsDummy()) { // it is dummy if it is in a float!!!
2525 if (style.isCommand()) {
2528 } else if (align != LYX_ALIGN_LAYOUT) {
2531 return_value = true;
2534 file += "\\noindent ";
2538 case LYX_ALIGN_NONE:
2539 case LYX_ALIGN_BLOCK:
2540 case LYX_ALIGN_LAYOUT:
2541 case LYX_ALIGN_SPECIAL: break;
2542 case LYX_ALIGN_LEFT:
2543 file += "\\raggedright ";
2546 case LYX_ALIGN_RIGHT:
2547 file += "\\raggedleft ";
2550 case LYX_ALIGN_CENTER:
2551 file += "\\centering ";
2556 current_cell_number = -1;
2557 tmp = table->TexEndOfCell(file, current_cell_number);
2558 for (; tmp >0 ; --tmp)
2561 texrow.start(this, 0);
2563 for (size_type i = 0; i < size(); ++i) {
2565 if (table->IsContRow(current_cell_number+1)) {
2566 if (c == LyXParagraph::META_NEWLINE)
2567 current_cell_number++;
2572 // Fully instantiated font
2573 LyXFont font = getFont(i);
2575 // Spaces at end of font change are simulated to be outside font change.
2576 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2577 if (open_font && c == ' ' && i <= size() - 2
2578 && getFont(i+1) != running_font && getFont(i+1) != font) {
2579 font = getFont(i+1);
2582 // We end font definition before blanks
2583 if (font != running_font && open_font) {
2584 column += running_font.latexWriteEndChanges(file,
2586 running_font = basefont;
2589 // Blanks are printed before start of fontswitch
2591 SimpleTeXBlanks(file, texrow, i, column, font, style);
2593 // Do we need to change font?
2594 if (font != running_font) {
2595 column += font.latexWriteStartChanges(file, basefont);
2596 running_font = font;
2599 // Do we need to turn on LaTeX mode?
2600 if (font.latex() != running_font.latex()) {
2601 if (font.latex() == LyXFont::ON
2602 && style.needprotect) {
2603 file += "\\protect ";
2607 if (c == LyXParagraph::META_NEWLINE) {
2608 // special case for inside a table
2609 // different from default case in SimpleTeXSpecialChars()
2611 column += running_font.latexWriteEndChanges(file, basefont);
2614 basefont = getFont(-1);
2615 running_font = basefont;
2616 current_cell_number++;
2617 if (table->CellHasContRow(current_cell_number) >= 0) {
2618 TeXContTableRows(file, i+1,
2619 current_cell_number,
2622 // if this cell follow only ContRows till end don't
2623 // put the EndOfCell because it is put after the
2625 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2626 current_cell_number--;
2629 int tmp = table->TexEndOfCell(file,
2630 current_cell_number);
2633 } else if (tmp < 0) {
2639 texrow.start(this, i+1);
2641 SimpleTeXSpecialChars(file, texrow,
2642 font, running_font, basefont,
2643 open_font, style, i, column, c);
2647 // If we have an open font definition, we have to close it
2649 running_font.latexWriteEndChanges(file, basefont);
2651 current_cell_number++;
2652 tmp = table->TexEndOfCell(file, current_cell_number);
2653 for (; tmp > 0; --tmp)
2655 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2656 return return_value;
2660 // This one spits out the text off ContRows in tables
2661 bool LyXParagraph::TeXContTableRows(string & file,
2662 LyXParagraph::size_type i,
2663 int current_cell_number,
2664 int & column, TexRow & texrow)
2666 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2672 bool return_value = false;
2673 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2677 basefont = getFont(-1); // Get layout font
2678 // Which font is currently active?
2679 LyXFont running_font = basefont;
2680 // Do we have an open font change?
2681 bool open_font = false;
2683 size_type lastpos = i;
2684 int cell = table->CellHasContRow(current_cell_number);
2685 current_cell_number++;
2687 // first find the right position
2689 for (; (i < size()) && (current_cell_number<cell); ++i) {
2691 if (c == LyXParagraph::META_NEWLINE)
2692 current_cell_number++;
2696 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2700 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2704 for (; i < size() && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2708 // Fully instantiated font
2709 LyXFont font = getFont(i);
2711 // Spaces at end of font change are simulated to be outside font change.
2712 // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
2713 if (open_font && c == ' ' && i <= size() - 2
2714 && getFont(i + 1) != running_font
2715 && getFont(i + 1) != font) {
2716 font = getFont(i + 1);
2719 // We end font definition before blanks
2720 if (font != running_font && open_font) {
2721 column += running_font.latexWriteEndChanges(file, basefont);
2722 running_font = basefont;
2725 // Blanks are printed before start of fontswitch
2727 SimpleTeXBlanks(file, texrow, i,
2728 column, font, style);
2730 // Do we need to change font?
2731 if (font != running_font) {
2733 font.latexWriteStartChanges(file,
2735 running_font = font;
2738 // Do we need to turn on LaTeX mode?
2739 if (font.latex() != running_font.latex()) {
2740 if (font.latex() == LyXFont::ON
2741 && style.needprotect)
2743 file += "\\protect ";
2747 SimpleTeXSpecialChars(file, texrow, font,
2748 running_font, basefont,
2749 open_font, style, i, column, c);
2751 // If we have an open font definition, we have to close it
2753 running_font.latexWriteEndChanges(file, basefont);
2756 basefont = getFont(-1);
2757 running_font = basefont;
2758 cell = table->CellHasContRow(current_cell_number);
2760 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2761 return return_value;
2765 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2767 bool retval = false;
2769 case LyXParagraph::META_HFILL:
2770 sgml_string.clear();
2772 case LyXParagraph::META_PROTECTED_SEPARATOR:
2775 case LyXParagraph::META_NEWLINE:
2779 sgml_string = "&";
2782 sgml_string = "<";
2785 sgml_string = ">";
2788 sgml_string = "$";
2791 sgml_string = "#";
2794 sgml_string = "%";
2797 sgml_string = "[";
2800 sgml_string = "]";
2803 sgml_string = "{";
2806 sgml_string = "}";
2809 sgml_string = "˜";
2812 sgml_string = """;
2815 sgml_string = "\";
2821 case '\0': /* Ignore :-) */
2822 sgml_string.clear();
2831 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2832 int & desc_on, int depth)
2836 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2838 int current_cell_number = -1;
2839 LyXFont font1, font2;
2842 size_type main_body;
2843 string emph = "emphasis";
2844 bool emph_flag= false;
2845 int char_line_count= 0;
2847 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2849 if (style.labeltype != LABEL_MANUAL)
2852 main_body = BeginningOfMainBody();
2854 /* gets paragraph main font */
2856 font1 = style.labelfont;
2860 char_line_count = depth;
2861 addNewlineAndDepth(file, depth);
2862 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2863 file += "<INFORMALTABLE>";
2864 addNewlineAndDepth(file, ++depth);
2866 current_cell_number = -1;
2867 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2869 /* parsing main loop */
2870 for (size_type i = 0; i < size(); ++i) {
2872 if (table->IsContRow(current_cell_number+1)) {
2873 if (c == LyXParagraph::META_NEWLINE)
2874 current_cell_number++;
2879 // Fully instantiated font
2882 /* handle <emphasis> tag */
2883 if (font1.emph() != font2.emph() && i) {
2884 if (font2.emph() == LyXFont::ON) {
2885 file += "<emphasis>";
2887 } else if (emph_flag) {
2888 file += "</emphasis>";
2892 if (c == LyXParagraph::META_NEWLINE) {
2893 // we have only to control for emphasis open here!
2895 file += "</emphasis>";
2898 font1 = font2 = getFont(-1);
2899 current_cell_number++;
2900 if (table->CellHasContRow(current_cell_number) >= 0) {
2901 DocBookContTableRows(file, extra, desc_on, i+1,
2902 current_cell_number,
2905 // if this cell follow only ContRows till end don't
2906 // put the EndOfCell because it is put after the
2908 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2909 current_cell_number--;
2912 tmp= table->DocBookEndOfCell(file, current_cell_number,
2917 } else if (c == LyXParagraph::META_INSET) {
2918 inset = GetInset(i);
2920 inset->DocBook(tmp_out);
2922 // This code needs some explanation:
2923 // Two insets are treated specially
2924 // label if it is the first element in a command paragraph
2926 // graphics inside tables or figure floats can't go on
2927 // title (the equivalente in latex for this case is caption
2928 // and title should come first
2931 if(desc_on != 3 || i != 0) {
2932 if(tmp_out[0] == '@') {
2934 extra += frontStrip(tmp_out, '@');
2936 file += frontStrip(tmp_out, '@');
2940 } else if (font2.latex() == LyXFont::ON) {
2941 // "TeX"-Mode on == > SGML-Mode on.
2947 if (linuxDocConvertChar(c, sgml_string)
2948 && !style.free_spacing) {
2949 // in freespacing mode, spaces are
2950 // non-breaking characters
2955 file += "</term><listitem><para>";
2961 file += sgml_string;
2967 /* needed if there is an optional argument but no contents */
2968 if (main_body > 0 && main_body == size()) {
2973 file += "</emphasis>";
2976 current_cell_number++;
2977 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2978 /* resets description flag correctly */
2981 /* <term> not closed... */
2985 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
2986 file += "</INFORMALTABLE>";
2988 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
2993 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
2994 int & desc_on, LyXParagraph::size_type i,
2995 int current_cell_number, int &column)
3001 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3004 LyXFont font1, font2;
3007 size_type main_body;
3009 string emph= "emphasis";
3010 bool emph_flag= false;
3011 int char_line_count= 0;
3013 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3016 if (style.labeltype != LABEL_MANUAL)
3019 main_body = BeginningOfMainBody();
3021 /* gets paragraph main font */
3023 font1 = style.labelfont;
3028 cell = table->CellHasContRow(current_cell_number);
3029 current_cell_number++;
3031 // first find the right position
3033 for (; i < size() && current_cell_number < cell; ++i) {
3035 if (c == LyXParagraph::META_NEWLINE)
3036 current_cell_number++;
3040 // I don't know how to handle this so I comment it
3041 // for the moment (Jug)
3042 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3043 // file += " \\\\\n";
3046 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3051 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3055 // Fully instantiated font
3058 /* handle <emphasis> tag */
3059 if (font1.emph() != font2.emph() && i) {
3060 if (font2.emph() == LyXFont::ON) {
3061 file += "<emphasis>";
3063 } else if (emph_flag) {
3064 file += "</emphasis>";
3068 if (c == LyXParagraph::META_INSET) {
3069 inset = GetInset(i);
3071 inset->DocBook(tmp_out);
3073 // This code needs some explanation:
3074 // Two insets are treated specially
3075 // label if it is the first element in a command paragraph
3077 // graphics inside tables or figure floats can't go on
3078 // title (the equivalente in latex for this case is caption
3079 // and title should come first
3082 if(desc_on != 3 || i != 0) {
3083 if(tmp_out[0] == '@') {
3085 extra += frontStrip(tmp_out, '@');
3087 file += frontStrip(tmp_out, '@');
3091 } else if (font2.latex() == LyXFont::ON) {
3092 // "TeX"-Mode on == > SGML-Mode on.
3098 if (linuxDocConvertChar(c, sgml_string)
3099 && !style.free_spacing) {
3100 // in freespacing mode, spaces are
3101 // non-breaking characters
3106 file += "</term><listitem><para>";
3112 file += sgml_string;
3116 // we have only to control for emphasis open here!
3118 file += "</emphasis>";
3121 font1 = font2 = getFont(-1);
3122 cell = table->CellHasContRow(current_cell_number);
3124 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3127 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3128 LyXParagraph::size_type const i,
3129 int & column, LyXFont const & font,
3130 LyXLayout const & style)
3132 if (column > tex_code_break_column
3134 && GetChar(i - 1) != ' '
3136 // In LaTeX mode, we don't want to
3137 // break lines since some commands
3139 && ! (font.latex() == LyXFont::ON)
3140 // same in FreeSpacing mode
3141 && !style.free_spacing
3142 // In typewriter mode, we want to avoid
3143 // ! . ? : at the end of a line
3144 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3145 && (GetChar(i-1) == '.'
3146 || GetChar(i-1) == '?'
3147 || GetChar(i-1) == ':'
3148 || GetChar(i-1) == '!'))) {
3149 if (tex_code_break_column == 0) {
3150 // in batchmode we need LaTeX to still
3151 // see it as a space not as an extra '\n'
3157 texrow.start(this, i+1);
3159 } else if (font.latex() == LyXFont::OFF) {
3160 if (style.free_spacing) {
3169 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3171 LyXFont & running_font,
3174 LyXLayout const & style,
3175 LyXParagraph::size_type & i,
3176 int & column, char const c)
3178 // Two major modes: LaTeX or plain
3179 // Handle here those cases common to both modes
3180 // and then split to handle the two modes separately.
3182 case LyXParagraph::META_INSET: {
3183 Inset * inset = GetInset(i);
3185 int len = file.length();
3186 int tmp = inset->Latex(file, style.isCommand());
3191 column += file.length() - len;
3200 case LyXParagraph::META_NEWLINE:
3202 column += running_font.latexWriteEndChanges(file,
3206 basefont = getFont(-1);
3207 running_font = basefont;
3210 case LyXParagraph::META_HFILL:
3211 file += "\\hfill{}";
3216 // And now for the special cases within each mode
3217 // Are we in LaTeX mode?
3218 if (font.latex() == LyXFont::ON) {
3219 // at present we only have one option
3220 // but I'll leave it as a switch statement
3221 // so its simpler to extend. (ARRae)
3223 case LyXParagraph::META_PROTECTED_SEPARATOR:
3228 // make sure that we will not print
3229 // error generating chars to the tex
3230 // file. This test would not be needed
3231 // if it were done in the buffer
3239 // Plain mode (i.e. not LaTeX)
3241 case LyXParagraph::META_PROTECTED_SEPARATOR:
3246 file += "\\textbackslash{}";
3250 case '°': case '±': case '²': case '³':
3251 case '×': case '÷': case '¹': case 'ª':
3252 case 'º': case '¬': case 'µ':
3253 if (current_view->buffer()->params.inputenc == "latin1") {
3254 file += "\\ensuremath{";
3263 case '|': case '<': case '>':
3264 // In T1 encoding, these characters exist
3265 if (lyxrc->fontenc == "T1") {
3267 //... but we should avoid ligatures
3268 if ((c == '>' || c == '<')
3270 && GetChar(i+1) == c){
3271 file += "\\textcompwordmark{}";
3276 // Typewriter font also has them
3277 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3281 // Otherwise, we use what LaTeX
3285 file += "\\textless{}";
3289 file += "\\textgreater{}";
3293 file += "\\textbar{}";
3299 case '-': // "--" in Typewriter mode -> "-{}-"
3301 && GetChar(i + 1) == '-'
3302 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3311 file += "\\char`\\\"{}";
3316 if (current_view->buffer()->params.inputenc == "default") {
3317 file += "\\pounds{}";
3325 case '%': case '#': case '{':
3339 case '*': case '[': case ']':
3340 // avoid being mistaken for optional arguments
3348 /* blanks are printed before font switching */
3349 // Sure? I am not! (try nice-latex)
3350 // I am sure it's correct. LyX might be smarter
3351 // in the future, but for now, nothing wrong is
3356 /* idea for labels --- begin*/
3360 && font.family() != LyXFont::TYPEWRITER_FAMILY
3361 && GetChar(i + 1) == 'y'
3362 && GetChar(i + 2) == 'X') {
3370 && font.family() != LyXFont::TYPEWRITER_FAMILY
3371 && GetChar(i + 1) == 'e'
3372 && GetChar(i + 2) == 'X') {
3377 /* check for LaTeX2e */
3380 && font.family() != LyXFont::TYPEWRITER_FAMILY
3381 && GetChar(i + 1) == 'a'
3382 && GetChar(i + 2) == 'T'
3383 && GetChar(i + 3) == 'e'
3384 && GetChar(i + 4) == 'X'
3385 && GetChar(i + 5) == '2'
3386 && GetChar(i + 6) == 'e') {
3387 file += "\\LaTeXe{}";
3391 /* check for LaTeX */
3394 && font.family() != LyXFont::TYPEWRITER_FAMILY
3395 && GetChar(i + 1) == 'a'
3396 && GetChar(i + 2) == 'T'
3397 && GetChar(i + 3) == 'e'
3398 && GetChar(i + 4) == 'X') {
3399 file += "\\LaTeX{}";
3402 /* idea for labels --- end*/
3403 } else if (c != '\0') {
3413 bool LyXParagraph::RoffContTableRows(FILE * fp,
3414 LyXParagraph::size_type i,
3420 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3426 string fname2 = TmpFileName(string(), "RAT2");
3428 int cell = table->CellHasContRow(actcell);
3431 // first find the right position
3433 for (; i < size() && actcell < cell; ++i) {
3435 if (c == LyXParagraph::META_NEWLINE)
3440 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3443 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3445 font2 = GetFontSettings(i);
3446 if (font1.latex() != font2.latex()) {
3447 if (font2.latex() != LyXFont::OFF)
3452 case LyXParagraph::META_INSET:
3453 if ((inset = GetInset(i))) {
3454 if (!(fp2= fopen(fname2.c_str(), "w+"))) {
3455 WriteAlert(_("LYX_ERROR:"),
3456 _("Cannot open temporary file:"),
3460 inset->Latex(fp2,-1);
3465 fprintf(fp, "\\\\");
3473 case LyXParagraph::META_NEWLINE:
3475 case LyXParagraph::META_HFILL:
3477 case LyXParagraph::META_PROTECTED_SEPARATOR:
3480 fprintf(fp, "\\\\");
3484 fprintf(fp, "%c", c);
3486 lyxerr.debug() << "RoffAsciiTable: NULL char in structure." << endl;
3490 cell = table->CellHasContRow(actcell);
3496 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3497 string & foot, TexRow & foot_texrow,
3500 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3501 LyXParagraph * par = this;
3503 while (par && par->depth == depth) {
3505 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3506 if (textclasslist.Style(GetCurrentTextClass(),
3507 par->layout).isEnvironment()
3508 || par->pextra_type != PEXTRA_NONE)
3510 par = par->TeXEnvironment(file, texrow,
3514 par = par->TeXOnePar(file, texrow,
3519 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3525 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3526 string & foot, TexRow & foot_texrow,
3529 bool eindent_open = false;
3530 bool foot_this_level = false;
3531 // flags when footnotetext should be appended to file.
3532 static bool minipage_open = false;
3533 static int minipage_open_depth = 0;
3534 char par_sep = current_view->buffer()->params.paragraph_separation;
3536 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3538 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3540 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3543 if (pextra_type == PEXTRA_INDENT) {
3544 if (!pextra_width.empty()) {
3545 file += "\\begin{LyXParagraphIndent}{"
3546 + pextra_width + "}\n";
3548 //float ib = atof(pextra_widthp.c_str())/100;
3549 // string can't handle floats at present (971109)
3550 // so I'll do a conversion by hand knowing that
3551 // the limits are 0.0 to 1.0. ARRae.
3552 file += "\\begin{LyXParagraphIndent}{";
3553 switch (pextra_widthp.length()) {
3559 file += pextra_widthp;
3563 file += pextra_widthp;
3565 file += "\\columnwidth}\n";
3568 eindent_open = true;
3570 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3571 if (pextra_hfill && Previous() &&
3572 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3573 file += "\\hfill{}\n";
3576 if (par_sep == BufferParams::PARSEP_INDENT) {
3577 file += "{\\setlength\\parindent{0pt}\n";
3580 file += "\\begin{minipage}";
3581 switch(pextra_alignment) {
3582 case MINIPAGE_ALIGN_TOP:
3585 case MINIPAGE_ALIGN_MIDDLE:
3588 case MINIPAGE_ALIGN_BOTTOM:
3592 if (!pextra_width.empty()) {
3594 file += pextra_width + "}\n";
3596 //float ib = atof(par->pextra_width.c_str())/100;
3597 // string can't handle floats at present
3598 // so I'll do a conversion by hand knowing that
3599 // the limits are 0.0 to 1.0. ARRae.
3601 switch (pextra_widthp.length()) {
3607 file += pextra_widthp;
3611 file += pextra_widthp;
3613 file += "\\columnwidth}\n";
3616 if (par_sep == BufferParams::PARSEP_INDENT) {
3617 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3620 minipage_open = true;
3621 minipage_open_depth = depth;
3624 #ifdef WITH_WARNINGS
3625 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3626 //I disabled it because it breaks when lists span on several
3629 if (style.isEnvironment()){
3630 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3631 #ifdef FANCY_FOOTNOTE_CODE
3632 if (foot_count < 0) {
3633 // flag that footnote[mark][text] should be
3634 // used for any footnotes from now on
3636 foot_this_level = true;
3639 file += "\\begin{" + style.latexname() + "}{"
3640 + labelwidthstring + "}\n";
3641 } else if (style.labeltype == LABEL_BIBLIO) {
3643 file += "\\begin{" + style.latexname() + "}{"
3644 + bibitemWidthest() + "}\n";
3645 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3646 #ifdef FANCY_FOOTNOTE_CODE
3647 if (foot_count < 0) {
3648 // flag that footnote[mark][text] should be
3649 // used for any footnotes from now on
3651 foot_this_level = true;
3654 file += "\\begin{" + style.latexname() + '}'
3655 + style.latexparam() + '\n';
3657 file += "\\begin{" + style.latexname() + '}'
3658 + style.latexparam() + '\n';
3661 LyXParagraph * par = this;
3663 par = par->TeXOnePar(file, texrow,
3664 foot, foot_texrow, foot_count);
3666 if (minipage_open && par && !style.isEnvironment() &&
3667 (par->pextra_type == PEXTRA_MINIPAGE) &&
3668 par->pextra_start_minipage) {
3669 file += "\\end{minipage}\n";
3671 if (par_sep == BufferParams::PARSEP_INDENT) {
3675 minipage_open = false;
3677 if (par && par->depth > depth) {
3678 if (textclasslist.Style(GetCurrentTextClass(),
3679 par->layout).isParagraph()
3681 && !suffixIs(file, "\n\n")) {
3682 // There should be at least one '\n' already
3683 // but we need there to be two for Standard
3684 // paragraphs that are depth-increment'ed to be
3685 // output correctly. However, tables can also be
3686 // paragraphs so don't adjust them. ARRae
3690 par = par->TeXDeeper(file, texrow,
3691 foot, foot_texrow, foot_count);
3693 if (par && par->layout == layout && par->depth == depth &&
3694 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3695 if (par->pextra_hfill && par->Previous() &&
3696 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3697 file += "\\hfill{}\n";
3700 if (par_sep == BufferParams::PARSEP_INDENT) {
3701 file += "{\\setlength\\parindent{0pt}\n";
3704 file += "\\begin{minipage}";
3705 switch(par->pextra_alignment) {
3706 case MINIPAGE_ALIGN_TOP:
3709 case MINIPAGE_ALIGN_MIDDLE:
3712 case MINIPAGE_ALIGN_BOTTOM:
3716 if (!par->pextra_width.empty()) {
3718 file += par->pextra_width;
3721 //float ib = atof(par->pextra_widthp.c_str())/100;
3722 // string can't handle floats at present
3723 // so I'll do a conversion by hand knowing that
3724 // the limits are 0.0 to 1.0. ARRae.
3726 switch (par->pextra_widthp.length()) {
3732 file += par->pextra_widthp;
3736 file += par->pextra_widthp;
3738 file += "\\columnwidth}\n";
3741 if (par_sep == BufferParams::PARSEP_INDENT) {
3742 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3745 minipage_open = true;
3746 minipage_open_depth = par->depth;
3749 && par->layout == layout
3750 && par->depth == depth
3751 && par->pextra_type == pextra_type);
3753 if (style.isEnvironment()) {
3754 file += "\\end{" + style.latexname() + '}';
3755 // maybe this should go after the minipage closes?
3756 if (foot_this_level) {
3757 if (foot_count >= 1) {
3758 if (foot_count > 1) {
3759 file += "\\addtocounter{footnote}{-";
3760 file += tostr(foot_count - 1);
3764 texrow += foot_texrow;
3766 foot_texrow.reset();
3771 if (minipage_open && (minipage_open_depth == depth) &&
3772 (!par || par->pextra_start_minipage ||
3773 par->pextra_type != PEXTRA_MINIPAGE)) {
3774 file += "\\end{minipage}\n";
3776 if (par_sep == BufferParams::PARSEP_INDENT) {
3780 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3781 file += "\\medskip\n\n";
3785 minipage_open = false;
3788 file += "\\end{LyXParagraphIndent}\n";
3791 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3792 && par->pextra_hfill)) {
3796 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3797 return par; // ale970302
3801 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3802 string & foot, TexRow & foot_texrow,
3805 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3806 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3807 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3808 "No footnote!" << endl;
3810 LyXParagraph * par = this;
3811 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3812 previous->GetLayout());
3814 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3815 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3816 "Float other than footnote in command"
3817 " with moving argument is illegal" << endl;
3820 if (footnotekind != LyXParagraph::FOOTNOTE
3821 && footnotekind != LyXParagraph::MARGIN
3823 && !suffixIs(file, '\n')) {
3824 // we need to ensure that real floats like tables and figures
3825 // have their \begin{} on a new line otherwise we can get
3826 // incorrect results when using the endfloat.sty package
3827 // especially if two floats follow one another. ARRae 981022
3828 // NOTE: if the file is length 0 it must have just been
3829 // written out so we assume it ended with a '\n'
3834 BufferParams * params = ¤t_view->buffer()->params;
3835 bool footer_in_body = true;
3836 switch (footnotekind) {
3837 case LyXParagraph::FOOTNOTE:
3838 if (style.intitle) {
3839 file += "\\thanks{\n";
3840 footer_in_body = false;
3842 if (foot_count == -1) {
3843 // we're at depth 0 so we can use:
3844 file += "\\footnote{%\n";
3845 footer_in_body = false;
3847 file += "\\footnotemark{}%\n";
3849 // we only need this when there are
3850 // multiple footnotes
3851 foot += "\\stepcounter{footnote}";
3853 foot += "\\footnotetext{%\n";
3854 foot_texrow.start(this, 0);
3855 foot_texrow.newline();
3860 case LyXParagraph::MARGIN:
3861 file += "\\marginpar{\n";
3863 case LyXParagraph::FIG:
3864 if (pextra_type == PEXTRA_FLOATFLT
3865 && (!pextra_width.empty()
3866 || !pextra_widthp.empty())) {
3868 if (!pextra_width.empty())
3869 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3870 pextra_width.c_str());
3872 sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
3873 atoi(pextra_widthp.c_str())/100.0);
3876 file += "\\begin{figure}";
3877 if (!params->float_placement.empty()) {
3879 file += params->float_placement;
3886 case LyXParagraph::TAB:
3887 file += "\\begin{table}";
3888 if (!params->float_placement.empty()) {
3890 file += params->float_placement;
3896 case LyXParagraph::WIDE_FIG:
3897 file += "\\begin{figure*}";
3898 if (!params->float_placement.empty()) {
3900 file += params->float_placement;
3906 case LyXParagraph::WIDE_TAB:
3907 file += "\\begin{table*}";
3908 if (!params->float_placement.empty()) {
3910 file += params->float_placement;
3916 case LyXParagraph::ALGORITHM:
3917 file += "\\begin{algorithm}\n";
3922 if (footnotekind != LyXParagraph::FOOTNOTE
3923 || !footer_in_body) {
3924 // Process text for all floats except footnotes in body
3926 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3929 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
3931 if (style.isEnvironment()
3932 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
3933 // Allows the use of minipages within float environments.
3934 // Shouldn't be circular because we don't support
3935 // footnotes inside floats (yet). ARRae
3936 par = par->TeXEnvironment(file, texrow,
3940 par = par->TeXOnePar(file, texrow,
3945 if (par && !par->IsDummy() && par->depth > depth) {
3946 par = par->TeXDeeper(file, texrow,
3950 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
3952 // process footnotes > depth 0 or in environments separately
3953 // NOTE: Currently don't support footnotes within footnotes
3954 // even though that is possible using the \footnotemark
3956 TexRow dummy_texrow;
3957 int dummy_count = 0;
3959 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3962 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
3964 if (style.isEnvironment()
3965 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
3966 // Allows the use of minipages within float environments.
3967 // Shouldn't be circular because we don't support
3968 // footnotes inside floats (yet). ARRae
3969 par = par->TeXEnvironment(foot, foot_texrow,
3970 dummy, dummy_texrow,
3973 par = par->TeXOnePar(foot, foot_texrow,
3974 dummy, dummy_texrow,
3978 if (par && !par->IsDummy() && par->depth > depth) {
3979 par = par->TeXDeeper(foot, foot_texrow,
3980 dummy, dummy_texrow,
3983 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
3985 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3986 "Footnote in a Footnote -- not supported"
3991 switch (footnotekind) {
3992 case LyXParagraph::FOOTNOTE:
3993 if (footer_in_body) {
3994 // This helps tell which of the multiple
3995 // footnotetexts an error was in.
3997 foot_texrow.newline();
4002 case LyXParagraph::MARGIN:
4005 case LyXParagraph::FIG:
4006 if (pextra_type == PEXTRA_FLOATFLT
4007 && (!pextra_width.empty()
4008 || !pextra_widthp.empty()))
4009 file += "\\end{floatingfigure}";
4011 file += "\\end{figure}";
4013 case LyXParagraph::TAB:
4014 file += "\\end{table}";
4016 case LyXParagraph::WIDE_FIG:
4017 file += "\\end{figure*}";
4019 case LyXParagraph::WIDE_TAB:
4020 file += "\\end{table*}";
4022 case LyXParagraph::ALGORITHM:
4023 file += "\\end{algorithm}";
4027 if (footnotekind != LyXParagraph::FOOTNOTE
4028 && footnotekind != LyXParagraph::MARGIN) {
4029 // we need to ensure that real floats like tables and figures
4030 // have their \end{} on a line of their own otherwise we can
4031 // get incorrect results when using the endfloat.sty package.
4036 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4041 void LyXParagraph::SetPExtraType(int type, char const * width,
4042 char const * widthp)
4045 pextra_width = width;
4046 pextra_widthp = widthp;
4048 if (textclasslist.Style(GetCurrentTextClass(),
4049 layout).isEnvironment()) {
4054 while (par && (par->layout == layout) && (par->depth == depth)) {
4056 par = par->Previous();
4058 par = par->FirstPhysicalPar();
4059 while (par && par->depth > depth) {
4060 par = par->Previous();
4062 par = par->FirstPhysicalPar();
4066 while (par && (par->layout == layout) && (par->depth == depth)) {
4067 par->pextra_type = type;
4068 par->pextra_width = width;
4069 par->pextra_widthp = widthp;
4070 par = par->NextAfterFootnote();
4071 if (par && (par->depth > depth))
4072 par->SetPExtraType(type, width, widthp);
4073 while (par && ((par->depth > depth) || par->IsDummy()))
4074 par = par->NextAfterFootnote();
4080 void LyXParagraph::UnsetPExtraType()
4082 if (pextra_type == PEXTRA_NONE)
4085 pextra_type = PEXTRA_NONE;
4086 pextra_width.clear();
4087 pextra_widthp.clear();
4089 if (textclasslist.Style(GetCurrentTextClass(),
4090 layout).isEnvironment()) {
4095 while (par && (par->layout == layout) && (par->depth == depth)) {
4097 par = par->Previous();
4099 par = par->FirstPhysicalPar();
4100 while (par && par->depth > depth) {
4101 par = par->Previous();
4103 par = par->FirstPhysicalPar();
4107 while (par && (par->layout == layout) && (par->depth == depth)) {
4108 par->pextra_type = PEXTRA_NONE;
4109 par->pextra_width.clear();
4110 par->pextra_widthp.clear();
4111 par = par->NextAfterFootnote();
4112 if (par && (par->depth > depth))
4113 par->UnsetPExtraType();
4114 while (par && ((par->depth > depth) || par->IsDummy()))
4115 par = par->NextAfterFootnote();
4121 bool LyXParagraph::IsHfill(size_type pos) const
4123 return IsHfillChar(GetChar(pos));
4127 bool LyXParagraph::IsInset(size_type pos) const
4129 return IsInsetChar(GetChar(pos));
4133 bool LyXParagraph::IsFloat(size_type pos) const
4135 return IsFloatChar(GetChar(pos));
4139 bool LyXParagraph::IsNewline(size_type pos) const
4143 tmp = IsNewlineChar(GetChar(pos));
4148 bool LyXParagraph::IsSeparator(size_type pos) const
4150 return IsSeparatorChar(GetChar(pos));
4154 bool LyXParagraph::IsLineSeparator(size_type pos) const
4156 return IsLineSeparatorChar(GetChar(pos));
4160 bool LyXParagraph::IsKomma(size_type pos) const
4162 return IsKommaChar(GetChar(pos));
4166 /// Used by the spellchecker
4167 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4169 unsigned char c = GetChar(pos);
4170 if (IsLetterChar(c))
4172 // '\0' is not a letter, allthough every string contains "" (below)
4175 // We want to pass the ' and escape chars to ispell
4176 string extra = lyxrc->isp_esc_chars + '\'';
4180 return contains(extra, ch);
4184 bool LyXParagraph::IsWord(size_type pos ) const
4186 return IsWordChar( GetChar(pos) ) ;