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 extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
39 int tex_code_break_column = 72; // needs non-zero initialization. set later.
40 // this is a bad idea, but how can LyXParagraph find its buffer to get
41 // parameters? (JMarc)
42 extern BufferView * current_view;
47 extern string bibitemWidthest();
49 /* this is a minibuffer */
50 static char minibuffer_char;
51 static LyXFont minibuffer_font;
52 static Inset * minibuffer_inset;
55 // Initialization of the counter for the paragraph id's,
56 // declared in lyxparagraph.h
57 unsigned int LyXParagraph::paragraph_id = 0;
60 LyXParagraph::LyXParagraph()
62 text.reserve(500); // is this number too big?
64 for (int i = 0; i < 10; ++i) setCounter(i , 0);
74 footnoteflag = LyXParagraph::NO_FOOTNOTE;
76 align = LYX_ALIGN_BLOCK;
78 /* table stuff -- begin*/
80 /* table stuff -- end*/
82 bibkey = 0; // ale970302
87 /* this konstruktor inserts the new paragraph in a list */
88 LyXParagraph::LyXParagraph(LyXParagraph * par)
91 par->text.resize(par->text.size());
93 for (int i = 0; i < 10; ++i) setCounter(i, 0);
99 next->previous = this;
101 previous->next = this;
106 footnoteflag = LyXParagraph::NO_FOOTNOTE;
107 footnotekind = LyXParagraph::FOOTNOTE;
109 /* table stuff -- begin*/
111 /* table stuff -- end*/
112 id_ = paragraph_id++;
114 bibkey = 0; // ale970302
120 void LyXParagraph::writeFile(ostream & os, BufferParams & params,
121 char footflag, char dth)
123 LyXFont font1, font2;
129 if (footnoteflag != LyXParagraph::NO_FOOTNOTE
131 || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
133 /* The beginning or the end of a footnote environment? */
134 if (footflag != footnoteflag) {
135 footflag = footnoteflag;
137 os << "\n\\begin_float "
138 << string_footnotekinds[footnotekind]
142 os << "\n\\end_float ";
146 /* The beginning or end of a deeper (i.e. nested) area? */
149 while (depth > dth) {
150 os << "\n\\begin_deeper ";
155 while (depth < dth) {
156 os << "\n\\end_deeper ";
162 /* First write the layout */
164 << textclasslist.NameOfLayout(params.textclass, layout)
167 /* maybe some vertical spaces */
168 if (added_space_top.kind() != VSpace::NONE)
169 os << "\\added_space_top "
170 << added_space_top.asLyXCommand() << " ";
171 if (added_space_bottom.kind() != VSpace::NONE)
172 os << "\\added_space_bottom "
173 << added_space_bottom.asLyXCommand() << " ";
175 /* The labelwidth string used in lists */
176 if (!labelwidthstring.empty())
177 os << "\\labelwidthstring "
178 << labelwidthstring << '\n';
180 /* Lines above or below? */
184 os << "\\line_bottom ";
186 /* Pagebreaks above or below? */
188 os << "\\pagebreak_top ";
189 if (pagebreak_bottom)
190 os << "\\pagebreak_bottom ";
192 /* Start of appendix? */
193 if (start_of_appendix)
194 os << "\\start_of_appendix ";
201 if (align != LYX_ALIGN_LAYOUT) {
203 case LYX_ALIGN_LEFT: h = 1; break;
204 case LYX_ALIGN_RIGHT: h = 2; break;
205 case LYX_ALIGN_CENTER: h = 3; break;
206 default: h = 0; break;
208 os << "\\align " << string_align[h] << " ";
210 if (pextra_type != PEXTRA_NONE) {
211 os << "\\pextra_type " << pextra_type;
212 if (pextra_type == PEXTRA_MINIPAGE) {
213 os << " \\pextra_alignment "
216 os << " \\pextra_hfill "
218 if (pextra_start_minipage)
219 os << " \\pextra_start_minipage "
220 << pextra_start_minipage;
222 if (!pextra_width.empty()) {
223 os << " \\pextra_width "
224 << VSpace(pextra_width).asLyXCommand();
225 } else if (!pextra_widthp.empty()) {
226 os << " \\pextra_widthp "
233 /* Dummy layout. This means that a footnote ended */
234 os << "\n\\end_float ";
235 footflag = LyXParagraph::NO_FOOTNOTE;
238 /* It might be a table */
240 os << "\\LyXTable\n";
248 font1 = LyXFont(LyXFont::ALL_INHERIT);
251 for (size_type i = 0; i < size(); i++) {
257 // Write font changes
258 font2 = GetFontSettings(i);
259 if (font2 != font1) {
260 font2.lyxWriteChanges(font1, os);
270 if (inset->DirectWrite()) {
271 // international char, let it write
272 // code directly so it's shorter in
276 os << "\n\\begin_inset ";
278 os << "\n\\end_inset \n\n";
283 os << "\n\\newline \n";
287 os << "\n\\hfill \n";
290 case META_PROTECTED_SEPARATOR:
291 os << "\n\\protected_separator \n";
295 os << "\n\\backslash \n";
299 if (i + 1 < size() && GetChar(i + 1) == ' ') {
306 if ((column > 70 && c == ' ')
311 // this check is to amend a bug. LyX sometimes
312 // inserts '\0' this could cause problems.
316 lyxerr << "ERROR (LyXParagraph::writeFile):"
317 " NULL char in structure." << endl;
323 // now write the next paragraph
325 next->writeFile(os, params, footflag, dth);
329 void LyXParagraph::validate(LaTeXFeatures & features)
331 // this will be useful later
332 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
336 if (line_top || line_bottom)
337 features.lyxline = true;
340 features.layout[GetLayout()] = true;
343 for (FontList::const_iterator cit = fontlist.begin();
344 cit != fontlist.end(); ++cit) {
345 if ((*cit).font.noun() == LyXFont::ON) {
346 lyxerr[Debug::LATEX] << "font.noun: "
347 << (*cit).font.noun()
349 features.noun = true;
350 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
351 << (*cit).font.stateText()
354 switch ((*cit).font.color()) {
356 case LyXFont::INHERIT_COLOR:
357 case LyXFont::IGNORE_COLOR: break;
359 features.color = true;
360 lyxerr[Debug::LATEX] << "Color enabled. Font: "
361 << (*cit).font.stateText()
367 FontTable * tmpfonttable = fonttable;
368 while (tmpfonttable) {
369 if (tmpfonttable->font.noun() == LyXFont::ON) {
370 lyxerr[Debug::LATEX] << "font.noun: "
371 << tmpfonttable->font.noun()
373 features.noun = true;
374 lyxerr[Debug::LATEX] << "Noun enabled. Font: "
375 << tmpfonttable->font.stateText()
378 switch (tmpfonttable->font.color()) {
380 case LyXFont::INHERIT_COLOR:
381 case LyXFont::IGNORE_COLOR:
384 features.color = true;
385 lyxerr[Debug::LATEX] << "Color enabled. Font: "
386 << tmpfonttable->font.stateText()
389 tmpfonttable = tmpfonttable->next;
393 for (InsetList::const_iterator cit = insetlist.begin();
394 cit != insetlist.end(); ++cit) {
395 (*cit).inset->Validate(features);
399 InsetTable * tmpinsettable = insettable;
400 while (tmpinsettable) {
401 if (tmpinsettable->inset) {
402 tmpinsettable->inset->Validate(features);
404 tmpinsettable = tmpinsettable->next;
407 if (table && table->IsLongTable())
408 features.longtable = true;
409 if (pextra_type == PEXTRA_INDENT)
410 features.LyXParagraphIndent = true;
411 if (pextra_type == PEXTRA_FLOATFLT)
412 features.floatflt = true;
413 if (layout.needprotect
414 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
415 features.NeedLyXFootnoteCode = true;
416 if ((current_view->buffer()->params.paragraph_separation == BufferParams::PARSEP_INDENT) &&
417 (pextra_type == LyXParagraph::PEXTRA_MINIPAGE))
418 features.NeedLyXMinipageIndent = true;
419 if (table && table->NeedRotating())
420 features.rotating = true;
421 if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
422 features.algorithm = true;
426 /* first few functions needed for cut and paste and paragraph breaking */
427 void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos) const
429 minibuffer_char = GetChar(pos);
430 minibuffer_font = GetFontSettings(pos);
431 minibuffer_inset = 0;
432 if (minibuffer_char == LyXParagraph::META_INSET) {
434 minibuffer_inset = GetInset(pos)->Clone();
436 minibuffer_inset = 0;
437 minibuffer_char = ' ';
438 // This reflects what GetInset() does (ARRae)
443 void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
445 minibuffer_char = GetChar(pos);
446 minibuffer_font = GetFontSettings(pos);
447 minibuffer_inset = 0;
448 if (minibuffer_char == LyXParagraph::META_INSET) {
450 minibuffer_inset = GetInset(pos);
451 // This is a little hack since I want exactly
452 // the inset, not just a clone. Otherwise
453 // the inset would be deleted when calling Erase(pos)
455 for (InsetList::iterator it = insetlist.begin();
456 it != insetlist.end(); ++it) {
457 if ((*it).pos == pos) {
464 InsetTable * tmpi = insettable;
465 while (tmpi && tmpi->pos != pos) {
468 if (tmpi) { /* This should always be true */
473 minibuffer_inset = 0;
474 minibuffer_char = ' ';
475 // This reflects what GetInset() does (ARRae)
480 /* Erase(pos); now the caller is responsible for that*/
484 void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
486 InsertChar(pos, minibuffer_char);
487 SetFont(pos, minibuffer_font);
488 if (minibuffer_char == LyXParagraph::META_INSET)
489 InsertInset(pos, minibuffer_inset);
492 /* end of minibuffer */
496 void LyXParagraph::Clear()
501 pagebreak_top = false;
502 pagebreak_bottom = false;
504 added_space_top = VSpace(VSpace::NONE);
505 added_space_bottom = VSpace(VSpace::NONE);
507 align = LYX_ALIGN_LAYOUT;
511 pextra_type = PEXTRA_NONE;
512 pextra_width.clear();
513 pextra_widthp.clear();
514 pextra_alignment = MINIPAGE_ALIGN_TOP;
515 pextra_hfill = false;
516 pextra_start_minipage = false;
519 labelwidthstring.clear();
523 start_of_appendix = false;
527 /* the destructor removes the new paragraph from the list */
528 LyXParagraph::~LyXParagraph()
531 previous->next = next;
533 next->previous = previous;
536 InsetTable * tmpinset;
538 tmpinset = insettable;
539 insettable = insettable->next;
541 delete tmpinset->inset;
543 if (insettable && insettable->next == insettable) {
544 // somehow this recursion appears occasionally
545 // but I can't find where. This bandaid
546 // helps but isn't the best fix. (ARRae)
547 if (insettable->inset) {
548 delete insettable->inset;
558 fonttable = fonttable->next;
563 /* table stuff -- begin*/
566 /* table stuff -- end*/
574 void LyXParagraph::Erase(LyXParagraph::size_type pos)
576 /* > because last is the next unused position, and you can
577 * use it if you want */
579 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
580 NextAfterFootnote()->Erase(pos - text.size() - 1);
582 lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
583 "position does not exist." << endl;
586 if (pos < size()) { // last is free for insertation, but should be empty
588 /* if it is an inset, delete the inset entry */
589 if (text[pos] == LyXParagraph::META_INSET) {
591 for(InsetList::iterator it = insetlist.begin();
592 it != insetlist.end(); ++it) {
593 if ((*it).pos == pos) {
601 /* if it is an inset, delete the inset entry */
602 if (text[pos] == LyXParagraph::META_INSET) {
604 InsetTable *tmpi = insettable;
605 InsetTable *tmpi2 = tmpi;
606 while (tmpi && tmpi->pos != pos) {
610 if (tmpi) { // this should always be true
611 if (tmpi->inset) // delete the inset if it exists
613 if (tmpi == insettable)
614 insettable = tmpi->next;
616 tmpi2->next = tmpi->next;
621 text.erase(text.begin() + pos);
623 /* erase entries in the tables */
624 for(FontList::iterator it = fontlist.begin();
625 it != fontlist.end(); ++it) {
626 if (pos >= (*it).pos && pos <= (*it).pos_end) {
627 if ((*it).pos == (*it).pos_end) {
634 /* update all other entries */
635 for(FontList::iterator it = fontlist.begin();
636 it != fontlist.end(); ++it) {
639 if ((*it).pos_end >= pos)
643 /* update the inset table */
644 for(InsetList::iterator it = insetlist.begin();
645 it != insetlist.end(); ++it) {
650 /* erase entries in the tables */
652 FontTable * tmp = fonttable;
653 FontTable * prev = 0;
654 while (tmp && !found) {
655 if (pos >= tmp->pos && pos <= tmp->pos_end)
663 if (found && tmp->pos == tmp->pos_end) {
664 /* if it is a multi-character font entry, we just make
665 * it smaller (see update below), otherwise we should
668 prev->next = tmp->next;
670 fonttable = tmp->next;
675 /* update all other entries */
681 if (tmp->pos_end >= pos)
686 /* update the inset table */
687 InsetTable * tmpi = insettable;
695 lyxerr << "ERROR (LyXParagraph::Erase): "
696 "can't erase non-existant char." << endl;
701 void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
703 /* > because last is the next unused position, and you can
704 * use it if you want */
707 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
708 NextAfterFootnote()->InsertChar(pos - text.size() - 1,
711 lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
712 "position does not exist." << endl;
715 text.insert(text.begin() + pos, c);
717 // update the font table
718 for(FontList::iterator it = fontlist.begin();
719 it != fontlist.end(); ++it) {
720 if ((*it).pos >= pos)
722 if ((*it).pos_end >= pos)
725 // update the inset table
726 for(InsetList::iterator it = insetlist.begin();
727 it != insetlist.end(); ++it) {
728 if ((*it).pos >= pos)
732 /* update the font table */
733 FontTable * tmp = fonttable;
737 if (tmp->pos_end >= pos)
742 /* update the inset table */
743 InsetTable * tmpi = insettable;
745 if (tmpi->pos >= pos)
753 void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
756 /* > because last is the next unused position, and you can
757 * use it if you want */
760 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
762 ->InsertInset(pos - text.size() - 1, inset);
764 lyxerr << "ERROR (LyXParagraph::InsertInset): "
765 "position does not exist: " << pos << endl;
768 if (text[pos] != LyXParagraph::META_INSET) {
769 lyxerr << "ERROR (LyXParagraph::InsertInset): "
770 "there is no LyXParagraph::META_INSET" << endl;
779 insetlist.push_back(tmp);
784 /* add a new entry in the inset table */
785 InsetTable * tmpi = new InsetTable;
788 tmpi->next = insettable;
795 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
799 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
800 return NextAfterFootnote()
801 ->GetInset(pos - text.size() - 1);
803 lyxerr << "ERROR (LyXParagraph::GetInset): "
804 "position does not exist: "
811 for(InsetList::iterator it = insetlist.begin();
812 it != insetlist.end(); ++it) {
813 if ((*it).pos == pos) {
817 lyxerr << "ERROR (LyXParagraph::GetInset): "
818 "Inset does not exist: " << pos << endl;
819 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
820 // Did this commenting out introduce a bug? So far I have not
821 // seen any, please enlighten me. (Lgb)
822 // My guess is that since the inset does not exist, we might
823 // as well replace it with a space to prevent crashes. (Asger)
827 InsetTable * tmpi = insettable;
829 while (tmpi && tmpi->pos != pos)
835 lyxerr << "ERROR (LyXParagraph::GetInset): "
836 "Inset does not exist: " << pos << endl;
837 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
838 // Did this commenting out introduce a bug? So far I have not
839 // seen any, please enlighten me. (Lgb)
840 // My guess is that since the inset does not exist, we might
841 // as well replace it with a space to prevent crashes. (Asger)
848 Inset const * LyXParagraph::GetInset(LyXParagraph::size_type pos) const
852 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
853 return NextAfterFootnote()
854 ->GetInset(pos - text.size() - 1);
856 lyxerr << "ERROR (LyXParagraph::GetInset): "
857 "position does not exist: "
864 for(InsetList::const_iterator cit = insetlist.begin();
865 cit != insetlist.end(); ++cit) {
866 if ((*cit).pos == pos) {
870 lyxerr << "ERROR (LyXParagraph::GetInset): "
871 "Inset does not exist: " << pos << endl;
872 text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
873 // Did this commenting out introduce a bug? So far I have not
874 // seen any, please enlighten me. (Lgb)
875 // My guess is that since the inset does not exist, we might
876 // as well replace it with a space to prevent crashes. (Asger)
880 InsetTable * tmpi = insettable;
882 while (tmpi && tmpi->pos != pos)
888 lyxerr << "ERROR (LyXParagraph::GetInset): "
889 "Inset does not exist: " << pos << endl;
890 // in the const version we need to comment it out anyway...
891 //text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
892 // Did this commenting out introduce a bug? So far I have not
893 // seen any, please enlighten me. (Lgb)
894 // My guess is that since the inset does not exist, we might
895 // as well replace it with a space to prevent crashes. (Asger)
902 // Gets uninstantiated font setting at position.
903 // Optimized after profiling. (Asger)
904 LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos) const
908 for(FontList::iterator it = fontlist.begin();
909 it != fontlist.end(); ++it) {
910 if (pos >= (*it).pos && pos <= (*it).pos_end)
914 FontTable * tmp = fonttable;
916 if (pos >= tmp->pos && pos <= tmp->pos_end)
922 /* > because last is the next unused position, and you can
923 * use it if you want */
924 else if (pos > size()) {
926 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
927 return NextAfterFootnote()
928 ->GetFontSettings(pos - text.size() - 1);
930 // Why is it an error to ask for the font of a
931 // position that does not exist? Would it be
932 // enough for this to be anable on debug?
933 // We want strict error checking, but it's ok to only
934 // have it when debugging. (Asger)
935 lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
936 "position does not exist. "
937 << pos << " (" << static_cast<int>(pos)
941 return GetFontSettings(pos - 1);
943 return LyXFont(LyXFont::ALL_INHERIT);
947 // Gets the fully instantiated font at a given position in a paragraph
948 // This is basically the same function as LyXText::GetFont() in text2.C.
949 // The difference is that this one is used for generating the LaTeX file,
950 // and thus cosmetic "improvements" are disallowed: This has to deliver
951 // the true picture of the buffer. (Asger)
952 // If position is -1, we get the layout font of the paragraph.
953 // If position is -2, we get the font of the manual label of the paragraph.
954 LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos) const
957 LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(),
959 LyXParagraph::size_type main_body = 0;
960 if (layout.labeltype == LABEL_MANUAL)
961 main_body = BeginningOfMainBody();
966 layoutfont = layout.labelfont;
968 layoutfont = layout.font;
969 tmpfont = GetFontSettings(pos);
970 tmpfont.realize(layoutfont);
972 // process layoutfont for pos == -1 and labelfont for pos < -1
974 tmpfont = layout.font;
976 tmpfont = layout.labelfont;
979 // check for environment font information
980 char par_depth = GetDepth();
981 LyXParagraph const * par = this;
982 while (par && par_depth && !tmpfont.resolved()) {
983 par = par->DepthHook(par_depth - 1);
985 tmpfont.realize(textclasslist.
986 Style(GetCurrentTextClass(),
987 par->GetLayout()).font);
988 par_depth = par->GetDepth();
992 tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
997 /// Returns the height of the highest font in range
998 LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
1000 LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
1002 for(FontList::const_iterator cit = fontlist.begin();
1003 cit != fontlist.end(); ++cit) {
1004 if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
1005 LyXFont::FONT_SIZE size = (*cit).font.size();
1006 if (size > maxsize && size <= LyXFont::SIZE_HUGER)
1011 FontTable * tmp = fonttable;
1013 if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
1014 LyXFont::FONT_SIZE size = tmp->font.size();
1015 if (size > maxsize && size<= LyXFont::SIZE_HUGER)
1025 char LyXParagraph::GetChar(LyXParagraph::size_type pos)
1032 /* > because last is the next unused position, and you can
1033 * use it if you want */
1034 else if (pos > size()) {
1035 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1036 return NextAfterFootnote()
1037 ->GetChar(pos - text.size() - 1);
1039 lyxerr << "ERROR (LyXParagraph::GetChar): "
1040 "position does not exist."
1041 << pos << " (" << static_cast<int>(pos)
1046 /* we should have a footnote environment */
1047 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1048 // Notice that LyX does request the
1049 // last char from time to time. (Asger)
1050 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1051 // "expected footnote." << endl;
1054 switch (next->footnotekind) {
1055 case LyXParagraph::FOOTNOTE:
1056 return LyXParagraph::META_FOOTNOTE;
1057 case LyXParagraph::MARGIN:
1058 return LyXParagraph::META_MARGIN;
1059 case LyXParagraph::FIG:
1060 case LyXParagraph::WIDE_FIG:
1061 return LyXParagraph::META_FIG;
1062 case LyXParagraph::TAB:
1063 case LyXParagraph::WIDE_TAB:
1064 return LyXParagraph::META_TAB;
1065 case LyXParagraph::ALGORITHM:
1066 return LyXParagraph::META_ALGORITHM;
1068 return '\0'; // to shut up gcc
1073 char LyXParagraph::GetChar(LyXParagraph::size_type pos) const
1080 /* > because last is the next unused position, and you can
1081 * use it if you want */
1082 else if (pos > size()) {
1083 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1084 return NextAfterFootnote()
1085 ->GetChar(pos - text.size() - 1);
1087 lyxerr << "ERROR (LyXParagraph::GetChar): "
1088 "position does not exist."
1089 << pos << " (" << static_cast<int>(pos)
1094 /* we should have a footnote environment */
1095 if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
1096 // Notice that LyX does request the
1097 // last char from time to time. (Asger)
1098 //lyxerr << "ERROR (LyXParagraph::GetChar): "
1099 // "expected footnote." << endl;
1102 switch (next->footnotekind) {
1103 case LyXParagraph::FOOTNOTE:
1104 return LyXParagraph::META_FOOTNOTE;
1105 case LyXParagraph::MARGIN:
1106 return LyXParagraph::META_MARGIN;
1107 case LyXParagraph::FIG:
1108 case LyXParagraph::WIDE_FIG:
1109 return LyXParagraph::META_FIG;
1110 case LyXParagraph::TAB:
1111 case LyXParagraph::WIDE_TAB:
1112 return LyXParagraph::META_TAB;
1113 case LyXParagraph::ALGORITHM:
1114 return LyXParagraph::META_ALGORITHM;
1116 return '\0'; // to shut up gcc
1121 // return an string of the current word, and the end of the word in lastpos.
1122 string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos) const
1126 // the current word is defined as starting at the first character from
1127 // the immediate left of lastpospos which meets the definition of IsLetter(),
1128 // continuing to the last character to the right of this meeting
1135 // move back until we have a letter
1137 //there's no real reason to have firstpos & lastpos as
1138 //separate variables as this is written, but maybe someon
1139 // will want to return firstpos in the future.
1141 //since someone might have typed a punctuation first
1142 int firstpos = lastpos;
1144 while ((firstpos >= 0) && !IsLetter(firstpos))
1147 // now find the beginning by looking for a nonletter
1149 while ((firstpos>= 0) && IsLetter(firstpos))
1152 // the above is now pointing to the preceeding non-letter
1156 // so copy characters into theword until we get a nonletter
1157 // note that this can easily exceed lastpos, wich means
1158 // that if used in the middle of a word, the whole word
1161 while (IsLetter(lastpos)) theword += GetChar(lastpos++);
1168 LyXParagraph::size_type LyXParagraph::Last() const
1170 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1171 return text.size() + NextAfterFootnote()->Last() + 1;
1172 /* the 1 is the symbol
1179 LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
1181 /* > because last is the next unused position, and you can
1182 * use it if you want */
1185 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1186 return NextAfterFootnote()
1187 ->ParFromPos(pos - text.size() - 1);
1189 lyxerr << "ERROR (LyXParagraph::ParFromPos): "
1190 "position does not exist." << endl;
1198 int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos) const
1200 /* > because last is the next unused position, and you can
1201 * use it if you want */
1204 && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1205 return NextAfterFootnote()
1206 ->PositionInParFromPos(pos - text.size() - 1);
1209 "ERROR (LyXParagraph::PositionInParFromPos): "
1210 "position does not exist." << endl;
1218 void LyXParagraph::SetFont(LyXParagraph::size_type pos,
1219 LyXFont const & font)
1221 /* > because last is the next unused position, and you can
1222 * use it if you want */
1224 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1225 NextAfterFootnote()->SetFont(pos - text.size() - 1,
1228 lyxerr << "ERROR (LyXParagraph::SetFont): "
1229 "position does not exist." << endl;
1233 LyXFont patternfont(LyXFont::ALL_INHERIT);
1235 // First, reduce font against layout/label font
1236 // Update: The SetCharFont() routine in text2.C already reduces font, so
1237 // we don't need to do that here. (Asger)
1238 // No need to simplify this because it will disappear in a new kernel. (Asger)
1240 // Next search font table
1241 for(FontList::iterator it = fontlist.begin();
1242 it != fontlist.end(); ++it) {
1243 if (pos >= (*it).pos && pos <= (*it).pos_end) {
1245 // we found a font entry. maybe we have to
1246 // split it and create a new one
1248 if ((*it).pos != (*it).pos_end) {
1249 // more than one character
1250 if (pos == (*it).pos) {
1251 // maybe we could enlarge
1252 // the left fonttable
1253 for(FontList::iterator fit = fontlist.begin();
1254 fit != fontlist.end(); ++fit) {
1255 if (pos - 1 >= (*fit).pos
1256 && pos - 1 <= (*fit).pos_end
1257 && (*fit).font == font) {
1265 // Add a new entry in the
1266 // fonttable for the position
1269 tmp.pos_end = (*it).pos_end;
1270 tmp.font = (*it).font;
1271 (*it).pos_end = pos;
1272 fontlist.push_back(tmp);
1273 } else if (pos == (*it).pos_end) {
1274 // Add a new entry in the
1275 // fonttable for the position
1277 tmp.pos = (*it).pos;
1278 tmp.pos_end = (*it).pos_end - 1;
1279 tmp.font = (*it).font;
1280 (*it).pos = (*it).pos_end;
1281 fontlist.push_back(tmp);
1283 // Add a new entry in the
1284 // fonttable for the position
1286 tmp.pos = (*it).pos;
1287 tmp.pos_end = pos - 1;
1288 tmp.font = (*it).font;
1289 fontlist.push_back(tmp);
1292 tmp.pos_end = (*it).pos_end;
1293 tmp.font = (*it).font;
1294 fontlist.push_back(tmp);
1297 (*it).pos_end = pos;
1305 // if we did not find a font entry, but if the font at hand
1306 // is the same as default, we just forget it
1307 if (font == patternfont) return;
1309 // ok, we did not find a font entry. But maybe there is exactly
1310 // the needed font entry one position left
1311 for(FontList::iterator it = fontlist.begin();
1312 it != fontlist.end(); ++it) {
1313 if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
1314 && (*it).font == font) {
1319 // Add a new entry in the
1320 // fonttable for the position
1324 tmp.font = patternfont;
1325 fontlist.push_back(tmp);
1327 // Next search font table
1331 FontTable * tmp = fonttable;
1332 while (tmp && !found) {
1333 if (pos >= tmp->pos && pos <= tmp->pos_end)
1340 /* if we did not find a font entry, but if the font at hand
1341 * is the same as default, we just forget it */
1342 if (font == patternfont)
1345 /* ok, we did not find a font entry. But maybe there is exactly
1346 * the needed font entry one position left */
1349 while (tmp2 && !found) {
1350 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1356 /* ok there is one. maybe it is exactly the needed font */
1357 if (tmp2->font == font) {
1358 /* put the position under the font */
1363 /* Add a new entry in the
1364 * fonttable for the position */
1365 tmp = new FontTable;
1368 tmp->font = patternfont;
1369 tmp->next = fonttable;
1372 /* we found a font entry. maybe we have to split it and create
1375 if (tmp->pos != tmp->pos_end) { /* more than one character */
1377 if (pos == tmp->pos) {
1378 /* maybe we could enlarge the left fonttable */
1382 while (tmp2 && !found) {
1383 if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
1389 /* Is there is one, and is it exactly the needed font? */
1390 if (found && tmp2->font == font) {
1391 /* put the position under the font */
1397 /* Add a new entry in the
1398 * fonttable for the position */
1399 tmp2 = new FontTable;
1400 tmp2->pos = pos + 1;
1401 tmp2->pos_end = tmp->pos_end;
1402 tmp2->font = tmp->font;
1404 tmp2->next = fonttable;
1407 else if (pos == tmp->pos_end) {
1408 /* Add a new entry in the
1409 * fonttable for the position */
1410 tmp2 = new FontTable;
1411 tmp2->pos = tmp->pos;
1412 tmp2->pos_end = tmp->pos_end - 1;
1413 tmp2->font = tmp->font;
1414 tmp->pos = tmp->pos_end;
1415 tmp2->next = fonttable;
1419 /* Add a new entry in the
1420 * fonttable for the position */
1421 tmp2 = new FontTable;
1422 tmp2->pos = tmp->pos;
1423 tmp2->pos_end = pos - 1;
1424 tmp2->font = tmp->font;
1425 tmp2->next = fonttable;
1428 tmp2 = new FontTable;
1429 tmp2->pos = pos + 1;
1430 tmp2->pos_end = tmp->pos_end;
1431 tmp2->font = tmp->font;
1432 tmp2->next = fonttable;
1445 /* this function is able to hide closed footnotes */
1446 LyXParagraph * LyXParagraph::Next()
1448 if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1449 LyXParagraph * tmp = next;
1451 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1453 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1454 return tmp->Next(); /* there can be more than one
1455 footnote in a logical
1458 return next; /* this should never happen! */
1465 LyXParagraph * LyXParagraph::NextAfterFootnote()
1467 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1468 LyXParagraph * tmp = next;
1469 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1471 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1472 return tmp; /* there can be more than one footnote
1473 in a logical paragraph */
1475 return next; /* this should never happen! */
1482 LyXParagraph const * LyXParagraph::NextAfterFootnote() const
1484 if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1485 LyXParagraph * tmp = next;
1486 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1488 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1489 return tmp; /* there can be more than one footnote
1490 in a logical paragraph */
1492 return next; /* this should never happen! */
1499 LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
1502 if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
1504 while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1505 tmp = tmp->previous;
1506 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1507 return tmp; /* there can be more than one footnote
1508 in a logical paragraph */
1510 return previous; /* this should never happen! */
1517 LyXParagraph * LyXParagraph::LastPhysicalPar()
1519 if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
1522 LyXParagraph * tmp = this;
1524 && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
1525 tmp = tmp->NextAfterFootnote();
1532 LyXParagraph * LyXParagraph::FirstPhysicalPar()
1536 LyXParagraph * tmppar = this;
1538 while (tmppar && (tmppar->IsDummy()
1539 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1540 tmppar = tmppar->previous;
1543 return this; /* this should never happen! */
1549 LyXParagraph const * LyXParagraph::FirstPhysicalPar() const
1553 LyXParagraph const * tmppar = this;
1555 while (tmppar && (tmppar->IsDummy()
1556 || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
1557 tmppar = tmppar->previous;
1560 return this; /* this should never happen! */
1566 /* this function is able to hide closed footnotes */
1567 LyXParagraph * LyXParagraph::Previous()
1569 LyXParagraph * tmp = previous;
1574 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1575 tmp = tmp->previous;
1577 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1578 tmp = tmp->previous;
1579 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1580 return tmp->next->Previous();
1590 /* this function is able to hide closed footnotes */
1591 LyXParagraph const * LyXParagraph::Previous() const
1593 LyXParagraph * tmp = previous;
1598 && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1599 tmp = tmp->previous;
1601 && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
1602 tmp = tmp->previous;
1603 if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE)
1604 return tmp->next->Previous();
1614 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
1617 size_type i, pos_end, pos_first;
1618 /* create a new paragraph */
1619 LyXParagraph * par = ParFromPos(pos);
1620 LyXParagraph * firstpar = FirstPhysicalPar();
1622 LyXParagraph * tmp = new LyXParagraph(par);
1624 tmp->footnoteflag = footnoteflag;
1625 tmp->footnotekind = footnotekind;
1627 /* this is an idea for a more userfriendly layout handling, I will
1628 * see what the users say */
1630 /* layout stays the same with latex-environments */
1632 tmp->SetOnlyLayout(firstpar->layout);
1633 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1636 if (Last() > pos || !Last() || flag == 2) {
1637 tmp->SetOnlyLayout(firstpar->layout);
1638 tmp->align = firstpar->align;
1639 tmp->SetLabelWidthString(firstpar->labelwidthstring);
1641 tmp->line_bottom = firstpar->line_bottom;
1642 firstpar->line_bottom = false;
1643 tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
1644 firstpar->pagebreak_bottom = false;
1645 tmp->added_space_bottom = firstpar->added_space_bottom;
1646 firstpar->added_space_bottom = VSpace(VSpace::NONE);
1648 tmp->depth = firstpar->depth;
1649 tmp->noindent = firstpar->noindent;
1651 /* copy everything behind the break-position
1652 to the new paragraph
1655 while (ParFromPos(pos_first) != par)
1658 pos_end = pos_first + par->text.size() - 1;
1659 tmp->text.reserve(pos_end - pos);
1661 for (i = pos; i <= pos_end; i++) {
1662 par->CutIntoMinibuffer(i - pos_first);
1663 tmp->InsertFromMinibuffer(i - pos);
1666 for (i = pos_end; i >= pos; i--)
1667 par->Erase(i - pos_first);
1669 par->text.resize(par->text.size());
1672 /* just an idea of me */
1674 tmp->line_top = firstpar->line_top;
1675 tmp->pagebreak_top = firstpar->pagebreak_top;
1676 tmp->added_space_top = firstpar->added_space_top;
1677 tmp->bibkey = firstpar->bibkey;
1679 /* layout stays the same with latex-environments */
1681 firstpar->SetOnlyLayout(tmp->layout);
1682 firstpar->SetLabelWidthString(tmp->labelwidthstring);
1683 firstpar->depth = tmp->depth;
1689 void LyXParagraph::MakeSameLayout(LyXParagraph const * par)
1691 par = par->FirstPhysicalPar();
1692 footnoteflag = par->footnoteflag;
1693 footnotekind = par->footnotekind;
1695 layout = par->layout;
1696 align = par-> align;
1697 SetLabelWidthString(par->labelwidthstring);
1699 line_bottom = par->line_bottom;
1700 pagebreak_bottom = par->pagebreak_bottom;
1701 added_space_bottom = par->added_space_bottom;
1703 line_top = par->line_top;
1704 pagebreak_top = par->pagebreak_top;
1705 added_space_top = par->added_space_top;
1707 pextra_type = par->pextra_type;
1708 pextra_width = par->pextra_width;
1709 pextra_widthp = par->pextra_widthp;
1710 pextra_alignment = par->pextra_alignment;
1711 pextra_hfill = par->pextra_hfill;
1712 pextra_start_minipage = par->pextra_start_minipage;
1714 noindent = par->noindent;
1719 LyXParagraph * LyXParagraph::FirstSelfrowPar()
1721 LyXParagraph * tmppar = this;
1724 && tmppar->previous->footnoteflag ==
1725 LyXParagraph::CLOSED_FOOTNOTE)
1726 || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
1727 tmppar = tmppar->previous;
1730 return this; /* this should never happen! */
1736 LyXParagraph * LyXParagraph::Clone() const
1738 /* create a new paragraph */
1739 LyXParagraph * result = new LyXParagraph;
1741 result->MakeSameLayout(this);
1743 /* this is because of the dummy layout of the paragraphs that
1745 result->layout = layout;
1747 /* table stuff -- begin*/
1749 result->table = table->Clone();
1752 /* table stuff -- end*/
1755 result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
1758 /* copy everything behind the break-position to the new paragraph */
1760 for (size_type i = 0; i < size(); i++) {
1761 CopyIntoMinibuffer(i);
1762 result->InsertFromMinibuffer(i);
1764 result->text.resize(result->text.size());
1769 bool LyXParagraph::HasSameLayout(LyXParagraph const * par)
1771 par = par->FirstPhysicalPar();
1774 par->footnoteflag == footnoteflag &&
1775 par->footnotekind == footnotekind &&
1777 par->layout == layout &&
1779 par->align == align &&
1781 par->line_bottom == line_bottom &&
1782 par->pagebreak_bottom == pagebreak_bottom &&
1783 par->added_space_bottom == added_space_bottom &&
1785 par->line_top == line_top &&
1786 par->pagebreak_top == pagebreak_top &&
1787 par->added_space_top == added_space_top &&
1789 par->pextra_type == pextra_type &&
1790 par->pextra_width == pextra_width &&
1791 par->pextra_widthp == pextra_widthp &&
1792 par->pextra_alignment == pextra_alignment &&
1793 par->pextra_hfill == pextra_hfill &&
1794 par->pextra_start_minipage == pextra_start_minipage &&
1796 par->table == table && // what means: NO TABLE AT ALL
1798 par->noindent == noindent &&
1799 par->depth == depth);
1803 void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
1805 size_type i, pos_end, pos_first;
1807 /* create a new paragraph */
1808 LyXParagraph * par = ParFromPos(pos);
1810 LyXParagraph * tmp = new LyXParagraph(par);
1812 tmp->MakeSameLayout(par);
1815 /* copy everything behind the break-position to the new
1818 while (ParFromPos(pos_first) != par)
1820 pos_end = pos_first + par->text.size() - 1;
1821 /* make shure there is enough memory for the now larger
1822 paragraph. This is not neccessary, because
1823 InsertFromMinibuffer will enlarge the memory (it uses
1824 InsertChar of course). But doing it by hand
1825 is MUCH faster! (only one time, not thousend times!!) */
1826 tmp->text.reserve(pos_end - pos);
1828 for (i = pos; i <= pos_end; i++) {
1830 par->CutIntoMinibuffer(i - pos_first);
1831 tmp->InsertFromMinibuffer(i - pos);
1833 for (i = pos_end; i >= pos; i--)
1834 par->Erase(i - pos_first);
1836 par->text.resize(par->text.size());
1841 /* be carefull, this does not make any check at all */
1842 void LyXParagraph::PasteParagraph()
1844 /* copy the next paragraph to this one */
1845 LyXParagraph * the_next = Next();
1847 LyXParagraph * firstpar = FirstPhysicalPar();
1849 /* first the DTP-stuff */
1850 firstpar->line_bottom = the_next->line_bottom;
1851 firstpar->added_space_bottom = the_next->added_space_bottom;
1852 firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
1854 size_type pos_end = the_next->text.size() - 1;
1855 size_type pos_insert = Last();
1858 /* ok, now copy the paragraph */
1859 for (i = 0; i <= pos_end; i++) {
1860 the_next->CutIntoMinibuffer(i);
1861 InsertFromMinibuffer(pos_insert + i);
1864 /* delete the next paragraph */
1869 void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
1871 LyXParagraph * par = ParFromPos(pos);
1873 while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
1874 par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
1880 void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
1882 LyXParagraph * par = ParFromPos(pos);
1884 while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
1885 par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
1891 LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout() const
1893 return FirstPhysicalPar()->layout;
1897 char LyXParagraph::GetDepth() const
1899 return FirstPhysicalPar()->depth;
1903 char LyXParagraph::GetAlign() const
1905 return FirstPhysicalPar()->align;
1909 string LyXParagraph::GetLabestring() const
1911 return FirstPhysicalPar()->labelstring;
1915 int LyXParagraph::GetFirstCounter(int i) const
1917 return FirstPhysicalPar()->counter_[i];
1921 /* the next two functions are for the manual labels */
1922 string LyXParagraph::GetLabelWidthString() const
1924 if (!FirstPhysicalPar()->labelwidthstring.empty())
1925 return FirstPhysicalPar()->labelwidthstring;
1927 return _("Senseless with this layout!");
1931 void LyXParagraph::SetLabelWidthString(string const & s)
1933 LyXParagraph * par = FirstPhysicalPar();
1935 par->labelwidthstring = s;
1939 void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
1941 LyXParagraph * par = FirstPhysicalPar();
1942 LyXParagraph * ppar = 0;
1943 LyXParagraph * npar = 0;
1945 par->layout = new_layout;
1946 /* table stuff -- begin*/
1949 /* table stuff -- end*/
1950 if (par->pextra_type == PEXTRA_NONE) {
1951 if (par->Previous()) {
1952 ppar = par->Previous()->FirstPhysicalPar();
1955 && (ppar->depth > par->depth))
1956 ppar = ppar->Previous()->FirstPhysicalPar();
1959 npar = par->Next()->NextAfterFootnote();
1962 && (npar->depth > par->depth))
1963 npar = npar->Next()->NextAfterFootnote();
1965 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
1967 p1 = ppar->pextra_width,
1968 p2 = ppar->pextra_widthp;
1969 ppar->SetPExtraType(ppar->pextra_type,
1970 p1.c_str(), p2.c_str());
1972 if ((par->pextra_type == PEXTRA_NONE) &&
1973 npar && (npar->pextra_type != PEXTRA_NONE)) {
1975 p1 = npar->pextra_width,
1976 p2 = npar->pextra_widthp;
1977 npar->SetPExtraType(npar->pextra_type,
1978 p1.c_str(), p2.c_str());
1984 void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
1987 * par = FirstPhysicalPar(),
1991 par->layout = new_layout;
1992 par->labelwidthstring.clear();
1993 par->align = LYX_ALIGN_LAYOUT;
1994 par->added_space_top = VSpace(VSpace::NONE);
1995 par->added_space_bottom = VSpace(VSpace::NONE);
1996 /* table stuff -- begin*/
1999 /* table stuff -- end*/
2000 if (par->pextra_type == PEXTRA_NONE) {
2001 if (par->Previous()) {
2002 ppar = par->Previous()->FirstPhysicalPar();
2005 && (ppar->depth > par->depth))
2006 ppar = ppar->Previous()->FirstPhysicalPar();
2009 npar = par->Next()->NextAfterFootnote();
2012 && (npar->depth > par->depth))
2013 npar = npar->Next()->NextAfterFootnote();
2015 if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
2017 p1 = ppar->pextra_width,
2018 p2 = ppar->pextra_widthp;
2019 ppar->SetPExtraType(ppar->pextra_type,
2020 p1.c_str(), p2.c_str());
2022 if ((par->pextra_type == PEXTRA_NONE) &&
2023 npar && (npar->pextra_type != PEXTRA_NONE)) {
2025 p1 = npar->pextra_width,
2026 p2 = npar->pextra_widthp;
2027 npar->SetPExtraType(npar->pextra_type,
2028 p1.c_str(), p2.c_str());
2034 /* if the layout of a paragraph contains a manual label, the beginning of the
2035 * main body is the beginning of the second word. This is what the par-
2036 * function returns. If the layout does not contain a label, the main
2037 * body always starts with position 0. This differentiation is necessary,
2038 * because there cannot be a newline or a blank <= the beginning of the
2039 * main body in TeX. */
2041 int LyXParagraph::BeginningOfMainBody() const
2043 if (FirstPhysicalPar() != this)
2046 // Unroll the first two cycles of the loop
2047 // and remember the previous character to
2048 // remove unnecessary GetChar() calls
2051 && GetChar(i) != LyXParagraph::META_NEWLINE) {
2053 char previous_char, temp;
2055 && (previous_char = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2056 // Yes, this ^ is supposed to be "= " not "=="
2059 && previous_char != ' '
2060 && (temp = GetChar(i)) != LyXParagraph::META_NEWLINE) {
2062 previous_char = temp;
2067 if (i == 0 && i == size() &&
2068 !(footnoteflag == LyXParagraph::NO_FOOTNOTE
2069 && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
2070 i++; /* the cursor should not jump
2071 * to the main body if there
2077 LyXParagraph * LyXParagraph::DepthHook(int deth)
2079 LyXParagraph * newpar = this;
2084 newpar = newpar->FirstPhysicalPar()->Previous();
2085 } while (newpar && newpar->GetDepth() > deth
2086 && newpar->footnoteflag == footnoteflag);
2089 if (Previous() || GetDepth())
2090 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2094 return newpar->FirstPhysicalPar();
2098 LyXParagraph const * LyXParagraph::DepthHook(int deth) const
2100 LyXParagraph const * newpar = this;
2105 newpar = newpar->FirstPhysicalPar()->Previous();
2106 } while (newpar && newpar->GetDepth() > deth
2107 && newpar->footnoteflag == footnoteflag);
2110 if (Previous() || GetDepth())
2111 lyxerr << "ERROR (LyXParagraph::DepthHook): "
2115 return newpar->FirstPhysicalPar();
2119 int LyXParagraph::AutoDeleteInsets()
2123 for (InsetList::iterator it = insetlist.begin();
2124 it != insetlist.end(); ++it) {
2125 if ((*it).inset->AutoDelete()) {
2132 InsetTable * tmpi = insettable;
2133 InsetTable * tmpi2 = tmpi;
2139 if (tmpi2->inset->AutoDelete()) {
2144 lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
2145 "cannot auto-delete insets" << endl;
2152 Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
2155 InsetTable * tmp = 0;
2156 for (InsetList::iterator it = insetlist.begin();
2157 it != insetlist.end(); ++it) {
2158 if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
2169 InsetTable * tmpi = insettable;
2170 InsetTable * tmpi2 = 0;
2172 if (tmpi->pos >= pos) {
2173 if (!tmpi2 || tmpi->pos < tmpi2->pos)
2180 return tmpi2->inset;
2188 /* returns -1 if inset not found */
2189 int LyXParagraph::GetPositionOfInset(Inset * inset) const
2192 for (InsetList::iterator it = insetlist.begin();
2193 it != insetlist.end(); ++it) {
2194 if ((*it).inset == inset) {
2198 // Think about footnotes
2199 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2200 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2201 int further = NextAfterFootnote()->GetPositionOfInset(inset);
2203 return size() + 1 + further;
2207 /* find the entry */
2208 InsetTable * tmpi = insettable;
2209 while (tmpi && tmpi->inset != inset) {
2212 if (tmpi && tmpi->inset)
2215 /* think about footnotes */
2216 if (footnoteflag == LyXParagraph::NO_FOOTNOTE
2217 && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
2219 NextAfterFootnote()->GetPositionOfInset(inset);
2221 return text.size() + 1 + further;
2229 void LyXParagraph::readSimpleWholeFile(FILE * myfile)
2233 if (!feof(myfile)) {
2237 InsertChar(text.size(), c);
2238 } while (!feof(myfile));
2244 LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
2245 string & foot, TexRow & foot_texrow,
2248 lyxerr[Debug::LATEX] << "TeXOnePar... " << this << endl;
2249 LyXParagraph * par = next;
2250 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2253 bool further_blank_line = false;
2255 lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
2257 if (start_of_appendix) {
2258 file += "\\appendix\n";
2262 if (tex_code_break_column && style.isCommand()){
2267 if (pagebreak_top) {
2268 file += "\\newpage";
2269 further_blank_line = true;
2271 if (added_space_top.kind() != VSpace::NONE) {
2272 file += added_space_top.asLatexCommand();
2273 further_blank_line = true;
2277 file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
2278 file += "\\vspace{-1\\parskip}";
2279 further_blank_line = true;
2282 if (further_blank_line){
2287 switch (style.latextype) {
2290 file += style.latexname();
2291 file += style.latexparam();
2293 case LATEX_ITEM_ENVIRONMENT:
2295 bibkey->Latex(file, false);
2299 case LATEX_LIST_ENVIRONMENT:
2306 bool need_par = SimpleTeXOnePar(file, texrow);
2308 // Spit out footnotes
2309 while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
2310 && par->footnoteflag != footnoteflag) {
2311 par = par->TeXFootnote(file, texrow,
2312 foot, foot_texrow, foot_count);
2313 par->SimpleTeXOnePar(file, texrow);
2317 // Make sure that \\par is done with the font of the last
2318 // character if this has another size as the default.
2319 // This is necessary because LaTeX (and LyX on the screen)
2320 // calculates the space between the baselines according
2321 // to this font. (Matthias)
2322 LyXFont font = getFont(Last()-1);
2324 if (style.resfont.size() != font.size()) {
2326 file += font.latexSize();
2330 } else if (textclasslist.Style(GetCurrentTextClass(),
2331 GetLayout()).isCommand()){
2332 if (style.resfont.size() != font.size()) {
2334 file += font.latexSize();
2338 } else if (style.resfont.size() != font.size()){
2339 file += "{\\" + font.latexSize() + " \\par}";
2342 switch (style.latextype) {
2343 case LATEX_ITEM_ENVIRONMENT:
2344 case LATEX_LIST_ENVIRONMENT:
2345 if (par && (depth < par->depth)) {
2350 case LATEX_ENVIRONMENT:
2351 // if its the last paragraph of the current environment
2352 // skip it otherwise fall through
2354 && (par->layout != layout
2355 || par->depth != depth
2356 || par->pextra_type != pextra_type))
2359 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
2360 && footnotekind != LyXParagraph::FOOTNOTE
2361 && footnotekind != LyXParagraph::MARGIN
2365 // don't insert this if we would be adding it
2366 // before or after a table in a float. This
2367 // little trick is needed in order to allow
2368 // use of tables in \subfigures or \subtables.
2374 further_blank_line = false;
2376 file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
2377 further_blank_line = true;
2380 if (added_space_bottom.kind() != VSpace::NONE) {
2381 file += added_space_bottom.asLatexCommand();
2382 further_blank_line = true;
2385 if (pagebreak_bottom) {
2386 file += "\\newpage";
2387 further_blank_line = true;
2390 if (further_blank_line){
2395 if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
2396 par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
2401 lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
2406 // This one spits out the text of the paragraph
2407 bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
2409 lyxerr[Debug::LATEX] << "SimpleTeXOnePar... " << this << endl;
2412 return SimpleTeXOneTablePar(file, texrow);
2415 size_type main_body;
2417 bool return_value = false;
2419 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
2422 /* maybe we have to create a optional argument */
2423 if (style.labeltype != LABEL_MANUAL)
2426 main_body = BeginningOfMainBody();
2428 if (main_body > 0) {
2430 basefont = getFont(-2); // Get label font
2432 basefont = getFont(-1); // Get layout font
2440 if (style.isCommand()) {
2443 } else if (align != LYX_ALIGN_LAYOUT) {
2446 return_value = true;
2450 // Which font is currently active?
2451 LyXFont running_font = basefont;
2452 // Do we have an open font change?
2453 bool open_font = false;
2455 texrow.start(this, 0);
2457 for (size_type i = 0; i < size(); ++i) {
2459 // First char in paragraph or after label?
2460 if (i == main_body && !IsDummy()) {
2461 if (main_body > 0) {
2463 column += running_font.latexWriteEndChanges(file, basefont);
2466 basefont = getFont(-1); // Now use the layout font
2467 running_font = basefont;
2471 if (style.isCommand()) {
2474 } else if (align != LYX_ALIGN_LAYOUT) {
2477 return_value = true;
2481 file += "\\noindent ";
2485 case LYX_ALIGN_NONE:
2486 case LYX_ALIGN_BLOCK:
2487 case LYX_ALIGN_LAYOUT:
2488 case LYX_ALIGN_SPECIAL: break;
2489 case LYX_ALIGN_LEFT:
2490 file += "\\raggedright ";
2493 case LYX_ALIGN_RIGHT:
2494 file += "\\raggedleft ";
2497 case LYX_ALIGN_CENTER:
2498 file += "\\centering ";
2506 // Fully instantiated font
2507 LyXFont font = getFont(i);
2509 // Spaces at end of font change are simulated to be
2510 // outside font change, i.e. we write "\textXX{text} "
2511 // rather than "\textXX{text }". (Asger)
2512 if (open_font && c == ' ' && i <= size() - 2
2513 && !getFont(i+1).equalExceptLatex(running_font)
2514 && !getFont(i+1).equalExceptLatex(font)) {
2515 font = getFont(i+1);
2517 // We end font definition before blanks
2518 if (!font.equalExceptLatex(running_font) && open_font) {
2519 column += running_font.latexWriteEndChanges(file,
2521 running_font = basefont;
2525 // Blanks are printed before start of fontswitch
2527 // Do not print the separation of the optional argument
2528 if (i != main_body - 1) {
2529 SimpleTeXBlanks(file, texrow, i,
2530 column, font, style);
2534 // Do we need to change font?
2535 if (!font.equalExceptLatex(running_font)
2536 && i != main_body-1) {
2537 column += font.latexWriteStartChanges(file, basefont);
2538 running_font = font;
2542 if (c == LyXParagraph::META_NEWLINE) {
2543 // newlines are handled differently here than
2544 // the default in SimpleTeXSpecialChars().
2545 if (!style.newline_allowed
2546 || font.latex() == LyXFont::ON) {
2550 column += running_font.latexWriteEndChanges(file, basefont);
2553 basefont = getFont(-1);
2554 running_font = basefont;
2555 if (font.family() ==
2556 LyXFont::TYPEWRITER_FAMILY) {
2562 texrow.start(this, i+1);
2565 SimpleTeXSpecialChars(file, texrow,
2566 font, running_font, basefont,
2567 open_font, style, i, column, c);
2571 // If we have an open font definition, we have to close it
2573 running_font.latexWriteEndChanges(file, basefont);
2576 /* needed if there is an optional argument but no contents */
2577 if (main_body > 0 && main_body == size()) {
2579 return_value = false;
2582 lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
2583 return return_value;
2587 // This one spits out the text of a table paragraph
2588 bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
2590 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar... " << this << endl;
2594 bool return_value = false;
2595 int current_cell_number = -1;
2597 LyXLayout const & style =
2598 textclasslist.Style(GetCurrentTextClass(), GetLayout());
2599 LyXFont basefont = getFont(-1); // Get layout font
2600 // Which font is currently active?
2601 LyXFont running_font = basefont;
2602 // Do we have an open font change?
2603 bool open_font = false;
2606 if (!IsDummy()) { // it is dummy if it is in a float!!!
2607 if (style.isCommand()) {
2610 } else if (align != LYX_ALIGN_LAYOUT) {
2613 return_value = true;
2616 file += "\\noindent ";
2620 case LYX_ALIGN_NONE:
2621 case LYX_ALIGN_BLOCK:
2622 case LYX_ALIGN_LAYOUT:
2623 case LYX_ALIGN_SPECIAL: break;
2624 case LYX_ALIGN_LEFT:
2625 file += "\\raggedright ";
2628 case LYX_ALIGN_RIGHT:
2629 file += "\\raggedleft ";
2632 case LYX_ALIGN_CENTER:
2633 file += "\\centering ";
2638 current_cell_number = -1;
2639 tmp = table->TexEndOfCell(file, current_cell_number);
2640 for (; tmp > 0 ; --tmp)
2643 texrow.start(this, 0);
2645 for (size_type i = 0; i < size(); ++i) {
2647 if (table->IsContRow(current_cell_number+1)) {
2648 if (c == LyXParagraph::META_NEWLINE)
2649 current_cell_number++;
2654 // Fully instantiated font
2655 LyXFont font = getFont(i);
2657 // Spaces at end of font change are simulated to be
2658 // outside font change.
2659 // i.e. we write "\textXX{text} " rather than
2660 // "\textXX{text }". (Asger)
2661 if (open_font && c == ' ' && i <= size() - 2
2662 && getFont(i+1) != running_font && getFont(i+1) != font) {
2663 font = getFont(i+1);
2666 // We end font definition before blanks
2667 if (font != running_font && open_font) {
2668 column += running_font.latexWriteEndChanges(file,
2670 running_font = basefont;
2673 // Blanks are printed before start of fontswitch
2675 SimpleTeXBlanks(file, texrow, i, column, font, style);
2677 // Do we need to change font?
2678 if (font != running_font) {
2679 column += font.latexWriteStartChanges(file, basefont);
2680 running_font = font;
2683 // Do we need to turn on LaTeX mode?
2684 if (font.latex() != running_font.latex()) {
2685 if (font.latex() == LyXFont::ON
2686 && style.needprotect) {
2687 file += "\\protect ";
2691 if (c == LyXParagraph::META_NEWLINE) {
2692 // special case for inside a table
2693 // different from default case in
2694 // SimpleTeXSpecialChars()
2696 column += running_font
2697 .latexWriteEndChanges(file, basefont);
2700 basefont = getFont(-1);
2701 running_font = basefont;
2702 current_cell_number++;
2703 if (table->CellHasContRow(current_cell_number) >= 0) {
2704 TeXContTableRows(file, i+1,
2705 current_cell_number,
2708 // if this cell follow only ContRows till end don't
2709 // put the EndOfCell because it is put after the
2711 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2712 current_cell_number--;
2715 int tmp = table->TexEndOfCell(file,
2716 current_cell_number);
2719 } else if (tmp < 0) {
2725 texrow.start(this, i+1);
2727 SimpleTeXSpecialChars(file, texrow,
2728 font, running_font, basefont,
2729 open_font, style, i, column, c);
2733 // If we have an open font definition, we have to close it
2735 running_font.latexWriteEndChanges(file, basefont);
2737 current_cell_number++;
2738 tmp = table->TexEndOfCell(file, current_cell_number);
2739 for (; tmp > 0; --tmp)
2741 lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
2742 return return_value;
2746 // This one spits out the text off ContRows in tables
2747 bool LyXParagraph::TeXContTableRows(string & file,
2748 LyXParagraph::size_type i,
2749 int current_cell_number,
2750 int & column, TexRow & texrow)
2752 lyxerr[Debug::LATEX] << "TeXContTableRows... " << this << endl;
2758 bool return_value = false;
2759 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2763 basefont = getFont(-1); // Get layout font
2764 // Which font is currently active?
2765 LyXFont running_font = basefont;
2766 // Do we have an open font change?
2767 bool open_font = false;
2769 size_type lastpos = i;
2770 int cell = table->CellHasContRow(current_cell_number);
2771 ++current_cell_number;
2773 // first find the right position
2775 for (; (i < size()) && (current_cell_number<cell); ++i) {
2777 if (c == LyXParagraph::META_NEWLINE)
2778 current_cell_number++;
2782 if (table->Linebreaks(table->FirstVirtualCell(cell))) {
2786 } else if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
2791 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
2795 // Fully instantiated font
2796 LyXFont font = getFont(i);
2798 // Spaces at end of font change are simulated to
2799 // be outside font change. i.e. we write
2800 // "\textXX{text} " rather than "\textXX{text }".
2802 if (open_font && c == ' ' && i <= size() - 2
2803 && getFont(i + 1) != running_font
2804 && getFont(i + 1) != font) {
2805 font = getFont(i + 1);
2808 // We end font definition before blanks
2809 if (font != running_font && open_font) {
2810 column += running_font.latexWriteEndChanges(file, basefont);
2811 running_font = basefont;
2814 // Blanks are printed before start of fontswitch
2816 SimpleTeXBlanks(file, texrow, i,
2817 column, font, style);
2819 // Do we need to change font?
2820 if (font != running_font) {
2822 font.latexWriteStartChanges(file,
2824 running_font = font;
2827 // Do we need to turn on LaTeX mode?
2828 if (font.latex() != running_font.latex()) {
2829 if (font.latex() == LyXFont::ON
2830 && style.needprotect)
2832 file += "\\protect ";
2836 SimpleTeXSpecialChars(file, texrow, font,
2837 running_font, basefont,
2838 open_font, style, i, column, c);
2840 // If we have an open font definition, we have to close it
2842 running_font.latexWriteEndChanges(file, basefont);
2845 basefont = getFont(-1);
2846 running_font = basefont;
2847 cell = table->CellHasContRow(current_cell_number);
2849 lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
2850 return return_value;
2854 bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
2856 bool retval = false;
2858 case LyXParagraph::META_HFILL:
2859 sgml_string.clear();
2861 case LyXParagraph::META_PROTECTED_SEPARATOR:
2864 case LyXParagraph::META_NEWLINE:
2868 sgml_string = "&";
2871 sgml_string = "<";
2874 sgml_string = ">";
2877 sgml_string = "$";
2880 sgml_string = "#";
2883 sgml_string = "%";
2886 sgml_string = "[";
2889 sgml_string = "]";
2892 sgml_string = "{";
2895 sgml_string = "}";
2898 sgml_string = "˜";
2901 sgml_string = """;
2904 sgml_string = "\";
2910 case '\0': /* Ignore :-) */
2911 sgml_string.clear();
2921 void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
2922 int & desc_on, int depth)
2925 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
2927 LyXFont font1, font2;
2930 size_type main_body;
2931 string emph = "emphasis";
2932 bool emph_flag = false;
2934 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
2937 if (style.labeltype != LABEL_MANUAL)
2940 main_body = BeginningOfMainBody();
2942 /* gets paragraph main font */
2944 font1 = style.labelfont;
2948 int char_line_count = depth;
2949 addNewlineAndDepth(file, depth);
2950 if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
2951 file += "<INFORMALTABLE>";
2952 addNewlineAndDepth(file, ++depth);
2954 int current_cell_number = -1;
2955 int tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
2957 /* parsing main loop */
2958 for (size_type i = 0; i < size(); ++i) {
2960 if (table->IsContRow(current_cell_number+1)) {
2961 if (c == LyXParagraph::META_NEWLINE)
2962 ++current_cell_number;
2967 // Fully instantiated font
2970 /* handle <emphasis> tag */
2971 if (font1.emph() != font2.emph() && i) {
2972 if (font2.emph() == LyXFont::ON) {
2973 file += "<emphasis>";
2975 } else if (emph_flag) {
2976 file += "</emphasis>";
2980 if (c == LyXParagraph::META_NEWLINE) {
2981 // we have only to control for emphasis open here!
2983 file += "</emphasis>";
2986 font1 = font2 = getFont(-1);
2987 current_cell_number++;
2988 if (table->CellHasContRow(current_cell_number) >= 0) {
2989 DocBookContTableRows(file, extra, desc_on, i+1,
2990 current_cell_number,
2993 // if this cell follow only ContRows till end don't
2994 // put the EndOfCell because it is put after the
2996 if (table->ShouldBeVeryLastCell(current_cell_number)) {
2997 current_cell_number--;
3000 tmp= table->DocBookEndOfCell(file, current_cell_number,
3005 } else if (c == LyXParagraph::META_INSET) {
3006 inset = GetInset(i);
3008 inset->DocBook(tmp_out);
3010 // This code needs some explanation:
3011 // Two insets are treated specially
3012 // label if it is the first element in a
3013 // command paragraph
3015 // graphics inside tables or figure floats
3017 // title (the equivalente in latex for this
3019 // and title should come first
3022 if(desc_on != 3 || i != 0) {
3023 if(tmp_out[0] == '@') {
3025 extra += frontStrip(tmp_out,
3028 file += frontStrip(tmp_out,
3033 } else if (font2.latex() == LyXFont::ON) {
3034 // "TeX"-Mode on == > SGML-Mode on.
3040 if (linuxDocConvertChar(c, sgml_string)
3041 && !style.free_spacing) {
3042 // in freespacing mode, spaces are
3043 // non-breaking characters
3048 file += "</term><listitem><para>";
3054 file += sgml_string;
3060 /* needed if there is an optional argument but no contents */
3061 if (main_body > 0 && main_body == size()) {
3066 file += "</emphasis>";
3069 current_cell_number++;
3070 tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
3071 /* resets description flag correctly */
3074 /* <term> not closed... */
3078 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3079 file += "</INFORMALTABLE>";
3081 lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
3086 void LyXParagraph::DocBookContTableRows(string & file, string & extra,
3088 LyXParagraph::size_type i,
3089 int current_cell_number, int &column)
3094 lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
3097 LyXFont font1, font2;
3100 size_type main_body;
3102 string emph= "emphasis";
3103 bool emph_flag= false;
3104 int char_line_count= 0;
3106 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3109 if (style.labeltype != LABEL_MANUAL)
3112 main_body = BeginningOfMainBody();
3114 /* gets paragraph main font */
3116 font1 = style.labelfont;
3121 cell = table->CellHasContRow(current_cell_number);
3122 ++current_cell_number;
3124 // first find the right position
3126 for (; i < size() && current_cell_number < cell; ++i) {
3128 if (c == LyXParagraph::META_NEWLINE)
3129 current_cell_number++;
3133 // I don't know how to handle this so I comment it
3134 // for the moment (Jug)
3135 // if (table->Linebreaks(table->FirstVirtualCell(cell))) {
3136 // file += " \\\\\n";
3139 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE)) {
3144 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3148 // Fully instantiated font
3151 /* handle <emphasis> tag */
3152 if (font1.emph() != font2.emph() && i) {
3153 if (font2.emph() == LyXFont::ON) {
3154 file += "<emphasis>";
3156 } else if (emph_flag) {
3157 file += "</emphasis>";
3161 if (c == LyXParagraph::META_INSET) {
3162 inset = GetInset(i);
3164 inset->DocBook(tmp_out);
3166 // This code needs some explanation:
3167 // Two insets are treated specially
3168 // label if it is the first element in a command paragraph
3170 // graphics inside tables or figure floats can't go on
3171 // title (the equivalente in latex for this case is caption
3172 // and title should come first
3175 if(desc_on != 3 || i != 0) {
3176 if(tmp_out[0] == '@') {
3178 extra += frontStrip(tmp_out, '@');
3180 file += frontStrip(tmp_out, '@');
3184 } else if (font2.latex() == LyXFont::ON) {
3185 // "TeX"-Mode on == > SGML-Mode on.
3191 if (linuxDocConvertChar(c, sgml_string)
3192 && !style.free_spacing) {
3193 // in freespacing mode, spaces are
3194 // non-breaking characters
3199 file += "</term><listitem><para>";
3205 file += sgml_string;
3209 // we have only to control for emphasis open here!
3211 file += "</emphasis>";
3214 font1 = font2 = getFont(-1);
3215 cell = table->CellHasContRow(current_cell_number);
3217 lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
3221 void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
3222 LyXParagraph::size_type const i,
3223 int & column, LyXFont const & font,
3224 LyXLayout const & style)
3226 if (column > tex_code_break_column
3228 && GetChar(i - 1) != ' '
3230 // In LaTeX mode, we don't want to
3231 // break lines since some commands
3233 && ! (font.latex() == LyXFont::ON)
3234 // same in FreeSpacing mode
3235 && !style.free_spacing
3236 // In typewriter mode, we want to avoid
3237 // ! . ? : at the end of a line
3238 && !(font.family() == LyXFont::TYPEWRITER_FAMILY
3239 && (GetChar(i-1) == '.'
3240 || GetChar(i-1) == '?'
3241 || GetChar(i-1) == ':'
3242 || GetChar(i-1) == '!'))) {
3243 if (tex_code_break_column == 0) {
3244 // in batchmode we need LaTeX to still
3245 // see it as a space not as an extra '\n'
3251 texrow.start(this, i+1);
3253 } else if (font.latex() == LyXFont::OFF) {
3254 if (style.free_spacing) {
3263 void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
3265 LyXFont & running_font,
3268 LyXLayout const & style,
3269 LyXParagraph::size_type & i,
3270 int & column, char const c)
3272 // Two major modes: LaTeX or plain
3273 // Handle here those cases common to both modes
3274 // and then split to handle the two modes separately.
3276 case LyXParagraph::META_INSET: {
3277 Inset * inset = GetInset(i);
3279 int len = file.length();
3280 int tmp = inset->Latex(file, style.isCommand());
3285 column += file.length() - len;
3294 case LyXParagraph::META_NEWLINE:
3296 column += running_font.latexWriteEndChanges(file,
3300 basefont = getFont(-1);
3301 running_font = basefont;
3304 case LyXParagraph::META_HFILL:
3305 file += "\\hfill{}";
3310 // And now for the special cases within each mode
3311 // Are we in LaTeX mode?
3312 if (font.latex() == LyXFont::ON) {
3313 // at present we only have one option
3314 // but I'll leave it as a switch statement
3315 // so its simpler to extend. (ARRae)
3317 case LyXParagraph::META_PROTECTED_SEPARATOR:
3322 // make sure that we will not print
3323 // error generating chars to the tex
3324 // file. This test would not be needed
3325 // if it were done in the buffer
3333 // Plain mode (i.e. not LaTeX)
3335 case LyXParagraph::META_PROTECTED_SEPARATOR:
3340 file += "\\textbackslash{}";
3344 case '°': case '±': case '²': case '³':
3345 case '×': case '÷': case '¹': case 'ª':
3346 case 'º': case '¬': case 'µ':
3347 if (current_view->buffer()->params.inputenc == "latin1") {
3348 file += "\\ensuremath{";
3357 case '|': case '<': case '>':
3358 // In T1 encoding, these characters exist
3359 if (lyxrc->fontenc == "T1") {
3361 //... but we should avoid ligatures
3362 if ((c == '>' || c == '<')
3364 && GetChar(i+1) == c){
3365 file += "\\textcompwordmark{}";
3370 // Typewriter font also has them
3371 if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
3375 // Otherwise, we use what LaTeX
3379 file += "\\textless{}";
3383 file += "\\textgreater{}";
3387 file += "\\textbar{}";
3393 case '-': // "--" in Typewriter mode -> "-{}-"
3395 && GetChar(i + 1) == '-'
3396 && font.family() == LyXFont::TYPEWRITER_FAMILY) {
3405 file += "\\char`\\\"{}";
3410 if (current_view->buffer()->params.inputenc == "default") {
3411 file += "\\pounds{}";
3419 case '%': case '#': case '{':
3427 file += "\\textasciitilde{}";
3432 file += "\\textasciicircum{}";
3436 case '*': case '[': case ']':
3437 // avoid being mistaken for optional arguments
3445 /* blanks are printed before font switching */
3446 // Sure? I am not! (try nice-latex)
3447 // I am sure it's correct. LyX might be smarter
3448 // in the future, but for now, nothing wrong is
3453 /* idea for labels --- begin*/
3457 && font.family() != LyXFont::TYPEWRITER_FAMILY
3458 && GetChar(i + 1) == 'y'
3459 && GetChar(i + 2) == 'X') {
3467 && font.family() != LyXFont::TYPEWRITER_FAMILY
3468 && GetChar(i + 1) == 'e'
3469 && GetChar(i + 2) == 'X') {
3474 /* check for LaTeX2e */
3477 && font.family() != LyXFont::TYPEWRITER_FAMILY
3478 && GetChar(i + 1) == 'a'
3479 && GetChar(i + 2) == 'T'
3480 && GetChar(i + 3) == 'e'
3481 && GetChar(i + 4) == 'X'
3482 && GetChar(i + 5) == '2'
3483 && GetChar(i + 6) == 'e') {
3484 file += "\\LaTeXe{}";
3488 /* check for LaTeX */
3491 && font.family() != LyXFont::TYPEWRITER_FAMILY
3492 && GetChar(i + 1) == 'a'
3493 && GetChar(i + 2) == 'T'
3494 && GetChar(i + 3) == 'e'
3495 && GetChar(i + 4) == 'X') {
3496 file += "\\LaTeX{}";
3499 /* idea for labels --- end*/
3500 } else if (c != '\0') {
3510 bool LyXParagraph::RoffContTableRows(ostream & os,
3511 LyXParagraph::size_type i,
3517 LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
3522 string fname2 = TmpFileName(string(), "RAT2");
3524 int cell = table->CellHasContRow(actcell);
3527 // first find the right position
3529 for (; i < size() && actcell < cell; ++i) {
3531 if (c == LyXParagraph::META_NEWLINE)
3536 if ((c != ' ') && (c != LyXParagraph::META_NEWLINE))
3539 && (c = GetChar(i)) != LyXParagraph::META_NEWLINE;
3541 font2 = GetFontSettings(i);
3542 if (font1.latex() != font2.latex()) {
3543 if (font2.latex() != LyXFont::OFF)
3548 case LyXParagraph::META_INSET:
3549 if ((inset = GetInset(i))) {
3550 fstream fs(fname2.c_str(),
3553 WriteAlert(_("LYX_ERROR:"),
3554 _("Cannot open temporary file:"),
3558 inset->Latex(fs, -1);
3571 case LyXParagraph::META_NEWLINE:
3573 case LyXParagraph::META_HFILL:
3575 case LyXParagraph::META_PROTECTED_SEPARATOR:
3584 lyxerr.debug() << "RoffAsciiTable: "
3585 "NULL char in structure."
3590 cell = table->CellHasContRow(actcell);
3596 LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
3597 string & foot, TexRow & foot_texrow,
3600 lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
3601 LyXParagraph * par = this;
3603 while (par && par->depth == depth) {
3605 lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
3606 if (textclasslist.Style(GetCurrentTextClass(),
3607 par->layout).isEnvironment()
3608 || par->pextra_type != PEXTRA_NONE)
3610 par = par->TeXEnvironment(file, texrow,
3614 par = par->TeXOnePar(file, texrow,
3619 lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
3625 LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
3626 string & foot, TexRow & foot_texrow,
3629 bool eindent_open = false;
3630 bool foot_this_level = false;
3631 // flags when footnotetext should be appended to file.
3632 static bool minipage_open = false;
3633 static int minipage_open_depth = 0;
3634 char par_sep = current_view->buffer()->params.paragraph_separation;
3636 lyxerr[Debug::LATEX] << "TeXEnvironment... " << this << endl;
3638 lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
3640 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3643 if (pextra_type == PEXTRA_INDENT) {
3644 if (!pextra_width.empty()) {
3645 file += "\\begin{LyXParagraphIndent}{"
3646 + pextra_width + "}\n";
3648 //float ib = atof(pextra_widthp.c_str())/100;
3649 // string can't handle floats at present (971109)
3650 // so I'll do a conversion by hand knowing that
3651 // the limits are 0.0 to 1.0. ARRae.
3652 file += "\\begin{LyXParagraphIndent}{";
3653 switch (pextra_widthp.length()) {
3659 file += pextra_widthp;
3663 file += pextra_widthp;
3665 file += "\\columnwidth}\n";
3668 eindent_open = true;
3670 if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3671 if (pextra_hfill && Previous() &&
3672 (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
3673 file += "\\hfill{}\n";
3676 if (par_sep == BufferParams::PARSEP_INDENT) {
3677 file += "{\\setlength\\parindent{0pt}\n";
3680 file += "\\begin{minipage}";
3681 switch(pextra_alignment) {
3682 case MINIPAGE_ALIGN_TOP:
3685 case MINIPAGE_ALIGN_MIDDLE:
3688 case MINIPAGE_ALIGN_BOTTOM:
3692 if (!pextra_width.empty()) {
3694 file += pextra_width + "}\n";
3696 //float ib = atof(par->pextra_width.c_str())/100;
3697 // string can't handle floats at present
3698 // so I'll do a conversion by hand knowing that
3699 // the limits are 0.0 to 1.0. ARRae.
3701 switch (pextra_widthp.length()) {
3707 file += pextra_widthp;
3711 file += pextra_widthp;
3713 file += "\\columnwidth}\n";
3716 if (par_sep == BufferParams::PARSEP_INDENT) {
3717 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3720 minipage_open = true;
3721 minipage_open_depth = depth;
3724 #ifdef WITH_WARNINGS
3725 #warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
3726 //I disabled it because it breaks when lists span on several
3729 if (style.isEnvironment()){
3730 if (style.latextype == LATEX_LIST_ENVIRONMENT) {
3731 #ifdef FANCY_FOOTNOTE_CODE
3732 if (foot_count < 0) {
3733 // flag that footnote[mark][text] should be
3734 // used for any footnotes from now on
3736 foot_this_level = true;
3739 file += "\\begin{" + style.latexname() + "}{"
3740 + labelwidthstring + "}\n";
3741 } else if (style.labeltype == LABEL_BIBLIO) {
3743 file += "\\begin{" + style.latexname() + "}{"
3744 + bibitemWidthest() + "}\n";
3745 } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
3746 #ifdef FANCY_FOOTNOTE_CODE
3747 if (foot_count < 0) {
3748 // flag that footnote[mark][text] should be
3749 // used for any footnotes from now on
3751 foot_this_level = true;
3754 file += "\\begin{" + style.latexname() + '}'
3755 + style.latexparam() + '\n';
3757 file += "\\begin{" + style.latexname() + '}'
3758 + style.latexparam() + '\n';
3761 LyXParagraph * par = this;
3763 par = par->TeXOnePar(file, texrow,
3764 foot, foot_texrow, foot_count);
3766 if (minipage_open && par && !style.isEnvironment() &&
3767 (par->pextra_type == PEXTRA_MINIPAGE) &&
3768 par->pextra_start_minipage) {
3769 file += "\\end{minipage}\n";
3771 if (par_sep == BufferParams::PARSEP_INDENT) {
3775 minipage_open = false;
3777 if (par && par->depth > depth) {
3778 if (textclasslist.Style(GetCurrentTextClass(),
3779 par->layout).isParagraph()
3781 && !suffixIs(file, "\n\n")) {
3782 // There should be at least one '\n' already
3783 // but we need there to be two for Standard
3784 // paragraphs that are depth-increment'ed to be
3785 // output correctly. However, tables can
3786 // also be paragraphs so don't adjust them.
3791 par = par->TeXDeeper(file, texrow,
3792 foot, foot_texrow, foot_count);
3794 if (par && par->layout == layout && par->depth == depth &&
3795 (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
3796 if (par->pextra_hfill && par->Previous() &&
3797 (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
3798 file += "\\hfill{}\n";
3801 if (par_sep == BufferParams::PARSEP_INDENT) {
3802 file += "{\\setlength\\parindent{0pt}\n";
3805 file += "\\begin{minipage}";
3806 switch(par->pextra_alignment) {
3807 case MINIPAGE_ALIGN_TOP:
3810 case MINIPAGE_ALIGN_MIDDLE:
3813 case MINIPAGE_ALIGN_BOTTOM:
3817 if (!par->pextra_width.empty()) {
3819 file += par->pextra_width;
3822 //float ib = atof(par->pextra_widthp.c_str())/100;
3823 // string can't handle floats at present
3824 // so I'll do a conversion by hand knowing that
3825 // the limits are 0.0 to 1.0. ARRae.
3827 switch (par->pextra_widthp.length()) {
3833 file += par->pextra_widthp;
3837 file += par->pextra_widthp;
3839 file += "\\columnwidth}\n";
3842 if (par_sep == BufferParams::PARSEP_INDENT) {
3843 file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
3846 minipage_open = true;
3847 minipage_open_depth = par->depth;
3850 && par->layout == layout
3851 && par->depth == depth
3852 && par->pextra_type == pextra_type);
3854 if (style.isEnvironment()) {
3855 file += "\\end{" + style.latexname() + '}';
3856 // maybe this should go after the minipage closes?
3857 if (foot_this_level) {
3858 if (foot_count >= 1) {
3859 if (foot_count > 1) {
3860 file += "\\addtocounter{footnote}{-";
3861 file += tostr(foot_count - 1);
3865 texrow += foot_texrow;
3867 foot_texrow.reset();
3872 if (minipage_open && (minipage_open_depth == depth) &&
3873 (!par || par->pextra_start_minipage ||
3874 par->pextra_type != PEXTRA_MINIPAGE)) {
3875 file += "\\end{minipage}\n";
3877 if (par_sep == BufferParams::PARSEP_INDENT) {
3881 if (par && par->pextra_type != PEXTRA_MINIPAGE) {
3882 file += "\\medskip\n\n";
3886 minipage_open = false;
3889 file += "\\end{LyXParagraphIndent}\n";
3892 if (!(par && (par->pextra_type == PEXTRA_MINIPAGE)
3893 && par->pextra_hfill)) {
3897 lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
3898 return par; // ale970302
3902 LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
3903 string & foot, TexRow & foot_texrow,
3906 lyxerr[Debug::LATEX] << "TeXFootnote... " << this << endl;
3907 if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
3908 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3909 "No footnote!" << endl;
3911 LyXParagraph * par = this;
3912 LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
3913 previous->GetLayout());
3915 if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
3916 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
3917 "Float other than footnote in command"
3918 " with moving argument is illegal" << endl;
3921 if (footnotekind != LyXParagraph::FOOTNOTE
3922 && footnotekind != LyXParagraph::MARGIN
3924 && !suffixIs(file, '\n')) {
3925 // we need to ensure that real floats like tables and figures
3926 // have their \begin{} on a new line otherwise we can get
3927 // incorrect results when using the endfloat.sty package
3928 // especially if two floats follow one another. ARRae 981022
3929 // NOTE: if the file is length 0 it must have just been
3930 // written out so we assume it ended with a '\n'
3935 BufferParams * params = ¤t_view->buffer()->params;
3936 bool footer_in_body = true;
3937 switch (footnotekind) {
3938 case LyXParagraph::FOOTNOTE:
3939 if (style.intitle) {
3940 file += "\\thanks{\n";
3941 footer_in_body = false;
3943 if (foot_count == -1) {
3944 // we're at depth 0 so we can use:
3945 file += "\\footnote{%\n";
3946 footer_in_body = false;
3948 file += "\\footnotemark{}%\n";
3950 // we only need this when there are
3951 // multiple footnotes
3952 foot += "\\stepcounter{footnote}";
3954 foot += "\\footnotetext{%\n";
3955 foot_texrow.start(this, 0);
3956 foot_texrow.newline();
3961 case LyXParagraph::MARGIN:
3962 file += "\\marginpar{\n";
3964 case LyXParagraph::FIG:
3965 if (pextra_type == PEXTRA_FLOATFLT
3966 && (!pextra_width.empty()
3967 || !pextra_widthp.empty())) {
3969 if (!pextra_width.empty())
3970 sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
3971 pextra_width.c_str());
3974 "\\begin{floatingfigure}{%f\\textwidth}\n",
3975 atoi(pextra_widthp.c_str())/100.0);
3978 file += "\\begin{figure}";
3979 if (!params->float_placement.empty()) {
3981 file += params->float_placement;
3988 case LyXParagraph::TAB:
3989 file += "\\begin{table}";
3990 if (!params->float_placement.empty()) {
3992 file += params->float_placement;
3998 case LyXParagraph::WIDE_FIG:
3999 file += "\\begin{figure*}";
4000 if (!params->float_placement.empty()) {
4002 file += params->float_placement;
4008 case LyXParagraph::WIDE_TAB:
4009 file += "\\begin{table*}";
4010 if (!params->float_placement.empty()) {
4012 file += params->float_placement;
4018 case LyXParagraph::ALGORITHM:
4019 file += "\\begin{algorithm}\n";
4024 if (footnotekind != LyXParagraph::FOOTNOTE
4025 || !footer_in_body) {
4026 // Process text for all floats except footnotes in body
4028 LyXLayout const & style =
4029 textclasslist.Style(GetCurrentTextClass(),
4032 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4034 if (style.isEnvironment()
4035 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4036 // Allows the use of minipages within float
4037 // environments. Shouldn't be circular because
4038 // we don't support footnotes inside
4039 // floats (yet). ARRae
4040 par = par->TeXEnvironment(file, texrow,
4044 par = par->TeXOnePar(file, texrow,
4049 if (par && !par->IsDummy() && par->depth > depth) {
4050 par = par->TeXDeeper(file, texrow,
4054 } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4056 // process footnotes > depth 0 or in environments separately
4057 // NOTE: Currently don't support footnotes within footnotes
4058 // even though that is possible using the \footnotemark
4060 TexRow dummy_texrow;
4061 int dummy_count = 0;
4063 LyXLayout const & style =
4064 textclasslist.Style(GetCurrentTextClass(),
4067 lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
4069 if (style.isEnvironment()
4070 || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
4071 // Allows the use of minipages within float
4072 // environments. Shouldn't be circular because
4073 // we don't support footnotes inside
4074 // floats (yet). ARRae
4075 par = par->TeXEnvironment(foot, foot_texrow,
4076 dummy, dummy_texrow,
4079 par = par->TeXOnePar(foot, foot_texrow,
4080 dummy, dummy_texrow,
4084 if (par && !par->IsDummy() && par->depth > depth) {
4085 par = par->TeXDeeper(foot, foot_texrow,
4086 dummy, dummy_texrow,
4090 && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
4092 lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
4093 "Footnote in a Footnote -- not supported"
4098 switch (footnotekind) {
4099 case LyXParagraph::FOOTNOTE:
4100 if (footer_in_body) {
4101 // This helps tell which of the multiple
4102 // footnotetexts an error was in.
4104 foot_texrow.newline();
4109 case LyXParagraph::MARGIN:
4112 case LyXParagraph::FIG:
4113 if (pextra_type == PEXTRA_FLOATFLT
4114 && (!pextra_width.empty()
4115 || !pextra_widthp.empty()))
4116 file += "\\end{floatingfigure}";
4118 file += "\\end{figure}";
4120 case LyXParagraph::TAB:
4121 file += "\\end{table}";
4123 case LyXParagraph::WIDE_FIG:
4124 file += "\\end{figure*}";
4126 case LyXParagraph::WIDE_TAB:
4127 file += "\\end{table*}";
4129 case LyXParagraph::ALGORITHM:
4130 file += "\\end{algorithm}";
4134 if (footnotekind != LyXParagraph::FOOTNOTE
4135 && footnotekind != LyXParagraph::MARGIN) {
4136 // we need to ensure that real floats like tables and figures
4137 // have their \end{} on a line of their own otherwise we can
4138 // get incorrect results when using the endfloat.sty package.
4143 lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
4148 void LyXParagraph::SetPExtraType(int type, char const * width,
4149 char const * widthp)
4152 pextra_width = width;
4153 pextra_widthp = widthp;
4155 if (textclasslist.Style(GetCurrentTextClass(),
4156 layout).isEnvironment()) {
4161 while (par && (par->layout == layout)
4162 && (par->depth == depth)) {
4164 par = par->Previous();
4166 par = par->FirstPhysicalPar();
4167 while (par && par->depth > depth) {
4168 par = par->Previous();
4170 par = par->FirstPhysicalPar();
4174 while (par && (par->layout == layout)
4175 && (par->depth == depth)) {
4176 par->pextra_type = type;
4177 par->pextra_width = width;
4178 par->pextra_widthp = widthp;
4179 par = par->NextAfterFootnote();
4180 if (par && (par->depth > depth))
4181 par->SetPExtraType(type, width, widthp);
4182 while (par && ((par->depth > depth) || par->IsDummy()))
4183 par = par->NextAfterFootnote();
4189 void LyXParagraph::UnsetPExtraType()
4191 if (pextra_type == PEXTRA_NONE)
4194 pextra_type = PEXTRA_NONE;
4195 pextra_width.clear();
4196 pextra_widthp.clear();
4198 if (textclasslist.Style(GetCurrentTextClass(),
4199 layout).isEnvironment()) {
4204 while (par && (par->layout == layout)
4205 && (par->depth == depth)) {
4207 par = par->Previous();
4209 par = par->FirstPhysicalPar();
4210 while (par && par->depth > depth) {
4211 par = par->Previous();
4213 par = par->FirstPhysicalPar();
4217 while (par && (par->layout == layout)
4218 && (par->depth == depth)) {
4219 par->pextra_type = PEXTRA_NONE;
4220 par->pextra_width.clear();
4221 par->pextra_widthp.clear();
4222 par = par->NextAfterFootnote();
4223 if (par && (par->depth > depth))
4224 par->UnsetPExtraType();
4225 while (par && ((par->depth > depth) || par->IsDummy()))
4226 par = par->NextAfterFootnote();
4232 bool LyXParagraph::IsHfill(size_type pos) const
4234 return IsHfillChar(GetChar(pos));
4238 bool LyXParagraph::IsInset(size_type pos) const
4240 return IsInsetChar(GetChar(pos));
4244 bool LyXParagraph::IsFloat(size_type pos) const
4246 return IsFloatChar(GetChar(pos));
4250 bool LyXParagraph::IsNewline(size_type pos) const
4254 tmp = IsNewlineChar(GetChar(pos));
4259 bool LyXParagraph::IsSeparator(size_type pos) const
4261 return IsSeparatorChar(GetChar(pos));
4265 bool LyXParagraph::IsLineSeparator(size_type pos) const
4267 return IsLineSeparatorChar(GetChar(pos));
4271 bool LyXParagraph::IsKomma(size_type pos) const
4273 return IsKommaChar(GetChar(pos));
4277 /// Used by the spellchecker
4278 bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) const
4280 unsigned char c = GetChar(pos);
4281 if (IsLetterChar(c))
4283 // '\0' is not a letter, allthough every string contains "" (below)
4286 // We want to pass the ' and escape chars to ispell
4287 string extra = lyxrc->isp_esc_chars + '\'';
4291 return contains(extra, ch);
4295 bool LyXParagraph::IsWord(size_type pos ) const
4297 return IsWordChar(GetChar(pos)) ;