/* This file is part of *====================================================== * *LyX,TheDocumentProcessor * *Copyright(C)1995MatthiasEttrich *Copyright(C)1995-1998TheLyXTeam. *
*======================================================*/
#define INITIAL_SIZE_PAR 10/*Number of bytes in one paragraph*/ #define STEP_SIZE_PAR 10/*Number of bytes added when reallocated*/
externunsignedchar GetCurrentTextClass(); // this should be fixed/removed int tex_code_break_column = 72; // needs non-zero initialization. set later. // this is a bad idea, but how can LyXParagraph find its buffer to get // parameters? (JMarc) extern BufferView *current_view; extern LyXRC *lyxrc;
// ale970405 extern LString bibitemWidthest();
/* this is a minibuffer */ staticchar minibuffer_char; static LyXFont minibuffer_font; static Inset *minibuffer_inset;
// Initialization of the counter for the paragraph id's, // declared in lyxparagraph.h unsignedint LyXParagraph::paragraph_id = 0;
bibkey = NULL; // ale970302 // ale970302 // fprintf(stderr, "new bib "); fflush(stderr); // if (par->bibkey) { // bibkey = new InsetBibKey(par->bibkey); // }
Clear();
}
/// Used by the spellchecker bool LyXParagraph::IsLetter(int pos){ unsignedchar c = GetChar(pos); if (IsLetterChar(c)) returntrue; // '\0' is not a letter, allthough every string contains "" (below) if( c == '\0') returnfalse; // We want to pass the ' and escape chars to ispell
LString extra = lyxrc->isp_esc_chars + '\''; char ch[2];
ch[0] = c;
ch[1] = 0; return extra.contains(ch);
}
void LyXParagraph::writeFile(FILE *file, BufferParams ¶ms, char footflag, char dth)
{
LyXFont font1, font2;
Inset *inset; int column = 0; int h = 0; char c = 0;
if (footnoteflag != LyXParagraph::NO_FOOTNOTE
|| !previous
|| previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
/* The beginning or the end of a footnote environment? */ if (footflag != footnoteflag) {
footflag = footnoteflag; if (footflag) {
fprintf(file, "\n\\begin_float %s ",
string_footnotekinds[footnotekind]);
} else {
fprintf(file, "\n\\end_float ");
}
}
/* The beginning or end of a deeper (i.e. nested) area? */ if (dth != depth) { if (depth > dth) { while (depth > dth) {
fprintf(file, "\n\\begin_deeper ");
dth++;
}
} else { while (depth < dth) {
fprintf(file, "\n\\end_deeper ");
dth--;
}
}
}
/* First write the layout */
fprintf(file, "\n\\layout %s\n",
lyxstyle.NameOfLayout(params.textclass,layout).c_str());
/* maybe some vertical spaces */ if (added_space_top.kind() != VSpace::NONE)
fprintf(file, "\\added_space_top %s ",
added_space_top.asLyXCommand().c_str()); if (added_space_bottom.kind() != VSpace::NONE)
fprintf(file, "\\added_space_bottom %s ",
added_space_bottom.asLyXCommand().c_str());
/* The labelwidth string used in lists */ if (!labelwidthstring.empty())
fprintf(file, "\\labelwidthstring %s\n",
labelwidthstring.c_str());
/* Lines above or below? */ if (line_top)
fprintf(file, "\\line_top "); if (line_bottom)
fprintf(file, "\\line_bottom ");
/* Pagebreaks above or below? */ if (pagebreak_top)
fprintf(file, "\\pagebreak_top "); if (pagebreak_bottom)
fprintf(file, "\\pagebreak_bottom ");
/* Start of appendix? */ if (start_of_appendix)
fprintf(file, "\\start_of_appendix ");
/* Noindent? */ if (noindent)
fprintf(file, "\\noindent ");
/* Alignment? */ if (align != LYX_ALIGN_LAYOUT) { switch (align) { case LYX_ALIGN_LEFT: h = 1; break; case LYX_ALIGN_RIGHT: h = 2; break; case LYX_ALIGN_CENTER: h = 3; break; default: h = 0; break;
}
fprintf(file, "\\align %s ", string_align[h]);
} if (pextra_type != PEXTRA_NONE) {
fprintf(file, "\\pextra_type %d", pextra_type); if (pextra_type == PEXTRA_MINIPAGE) {
fprintf(file, " \\pextra_alignment %d",
pextra_alignment); if (pextra_hfill)
fprintf(file, " \\pextra_hfill %d",
pextra_hfill); if (pextra_start_minipage)
fprintf(file, " \\pextra_start_minipage %d",
pextra_start_minipage);
} if (!pextra_width.empty()) {
fprintf(file, " \\pextra_width %s",
VSpace(pextra_width).asLyXCommand().c_str());
} elseif (!pextra_widthp.empty()) {
fprintf(file, " \\pextra_widthp %s",pextra_widthp.c_str());
}
fprintf(file,"\n");
}
} else { /* Dummy layout. This means that a footnote ended */
fprintf(file, "\n\\end_float ");
footflag = LyXParagraph::NO_FOOTNOTE;
}
/* It might be a table */ if (table){
fprintf(file, "\\LyXTable\n");
table->Write(file);
}
// bibitem ale970302 if (bibkey)
bibkey->Write(file);
font1 = LyXFont(LyXFont::ALL_INHERIT);
column = 0; for (int i = 0; i < last; i++) { if (!i){
fprintf(file, "\n");
column = 0;
}
c = GetChar(i); switch (c) { case LYX_META_INSET:
inset = GetInset(i); if (inset) if (inset->DirectWrite()) { // international char, let it write // code directly so it's shorter in // the file
inset->Write(file);
} else {
fprintf(file, "\n\\begin_inset ");
inset->Write(file);
fprintf(file, "\n\\end_inset \n");
fprintf(file, "\n");
column = 0;
} break; case LYX_META_NEWLINE:
fprintf(file, "\n\\newline \n");
column = 0; break; case LYX_META_HFILL:
fprintf(file, "\n\\hfill \n");
column = 0; break; case LYX_META_PROTECTED_SEPARATOR:
fprintf(file, "\n\\protected_separator \n");
column = 0; break; case'\\':
fprintf(file, "\n\\backslash \n");
column = 0; break; case'.': if (i + 1 < last && GetChar(i + 1) == ' ') {
fprintf(file, ".\n");
column = 0;
} else
fprintf(file, "."); break; default: if ((column > 70 && c==' ')
|| column > 79){
fprintf(file, "\n");
column = 0;
} // this check is to amend a bug. LyX sometimes // inserts '\0' this could cause problems. if (c != '\0')
fprintf(file, "%c", c); else
lyxerr.print("ERROR (LyXParagraph::writeFile):" " NULL char in structure.");
column++; break;
}
}
// now write the next paragraph if (next)
next->writeFile(file, params, footflag, dth);
}
void LyXParagraph::validate(LaTeXFeatures &features)
{ // this will be useful later
LyXLayout *layout = lyxstyle.Style(GetCurrentTextClass(),
GetLayout());
// check the params. if (line_top || line_bottom)
features.lyxline = true;
// then the layouts
features.layout[GetLayout()] = true;
// then the fonts
FontTable *tmpfonttable = fonttable; while (tmpfonttable) { if (tmpfonttable->font.noun() == LyXFont::ON) {
lyxerr.debug(LString("font.noun: ")
+ int(tmpfonttable->font.noun()),
Error::LATEX);
features.noun = true;
lyxerr.debug("Noun enabled. Font: "
+tmpfonttable->font.stateText(),
Error::LATEX);
} switch (tmpfonttable->font.color()) { case LyXFont::NONE: case LyXFont::INHERIT_COLOR: case LyXFont::IGNORE_COLOR: break; default:
features.color = true;
lyxerr.debug("Color enabled. Font: "
+tmpfonttable->font.stateText(),
Error::LATEX);
}
tmpfonttable = tmpfonttable->next;
}
// then the insets
InsetTable *tmpinsettable = insettable; while (tmpinsettable) { if (tmpinsettable->inset) {
tmpinsettable->inset->Validate(features);
}
tmpinsettable = tmpinsettable->next;
} if (table && table->IsLongTable())
features.longtable = true; if (pextra_type == PEXTRA_INDENT)
features.LyXParagraphIndent = true; if (pextra_type == PEXTRA_FLOATFLT)
features.floatflt = true; if (layout->needprotect
&& next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
features.NeedLyXFootnoteCode = true; if ((current_view->currentBuffer()->params.paragraph_separation == LYX_PARSEP_INDENT) &&
(pextra_type == PEXTRA_MINIPAGE))
features.NeedLyXMinipageIndent = true; if (table && table->NeedRotating())
features.rotating = true;
}
/* first few functions needed for cut and paste and paragraph breaking */ void LyXParagraph::CopyIntoMinibuffer(int pos)
{
minibuffer_char = GetChar(pos);
minibuffer_font = GetFontSettings(pos);
minibuffer_inset = 0; if (minibuffer_char == LYX_META_INSET) { if (GetInset(pos)) {
minibuffer_inset = GetInset(pos)->Clone();
} else {
minibuffer_inset = NULL;
minibuffer_char = ' '; // This reflects what GetInset() does (ARRae)
}
}
}
void LyXParagraph::CutIntoMinibuffer(int pos)
{
minibuffer_char = GetChar(pos);
minibuffer_font = GetFontSettings(pos);
minibuffer_inset = 0; if (minibuffer_char == LYX_META_INSET) { if (GetInset(pos)) {
minibuffer_inset = GetInset(pos); /* This is a little hack since I want exactly the inset, notjustaclone.Otherwisetheinsetwouldbedeleted
when calling Erase(pos) */
/* find the entry */
InsetTable *tmpi = insettable; while (tmpi && tmpi->pos != pos) {
tmpi=tmpi->next;
} if (tmpi) { /* This should always be true */
tmpi->inset = NULL;
}
} else {
minibuffer_inset = NULL;
minibuffer_char = ' '; // This reflects what GetInset() does (ARRae)
}
}
/* Erase(pos); now the caller is responsible for that*/
}
/* the destructor removes the new paragraph from the list */
LyXParagraph::~LyXParagraph()
{ if (previous)
previous->next = next; if (next)
next->previous = previous;
if (text) delete[] text;
InsetTable *tmpinset; while (insettable) {
tmpinset = insettable;
insettable = insettable->next; if (tmpinset->inset) delete tmpinset->inset; delete tmpinset; if (insettable && insettable->next == insettable) { // somehow this recursion appears occasionally // but I can't find where. This bandaid // helps but isn't the best fix. (ARRae) if (insettable->inset) { delete insettable->inset;
} delete insettable; break;
}
}
/* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
NextAfterFootnote()->Erase(pos - last - 1); else
lyxerr.debug("ERROR (LyXParagraph::Erase): position does not exist."); return;
} if (pos < last) { // last is free for insertation, but should be empty
/* if it is an inset, delete the inset entry */ if (text[pos] == LYX_META_INSET) { /* find the entry */
InsetTable *tmpi = insettable;
InsetTable *tmpi2 = tmpi; while (tmpi && tmpi->pos != pos) {
tmpi2=tmpi;
tmpi=tmpi->next;
} if (tmpi) { // this should always be true if (tmpi->inset) // delete the inset if it exists delete tmpi->inset; if (tmpi == insettable)
insettable = tmpi->next; else
tmpi2->next = tmpi->next; delete tmpi;
}
}
// Shift rest of text for (i = pos; i < last - 1; i++) {
text[i]=text[i+1];
}
last--;
/* erase entries in the tables */ int found = 0;
FontTable *tmp = fonttable;
FontTable *prev = NULL; while (tmp && !found) { if (pos >= tmp->pos && pos <= tmp->pos_end)
found = 1; else {
prev = tmp;
tmp = tmp->next;
}
}
if (found && tmp->pos == tmp->pos_end) { /* if it is a multi-character font entry, we just make *itsmaller(seeupdatebelow),otherwiseweshould
* delete it */ if (prev)
prev->next = tmp->next; else
fonttable = tmp->next;
delete tmp;
}
/* update all other entries */
tmp = fonttable; while (tmp) { if (tmp->pos > pos)
tmp->pos--; if (tmp->pos_end >= pos)
tmp->pos_end--;
tmp = tmp->next;
}
/* update the inset table */
InsetTable *tmpi = insettable; while (tmpi) { if (tmpi->pos > pos)
tmpi->pos--;
tmpi=tmpi->next;
}
/* pos is needed to specify the paragraph correctly. Remember the
* closed footnotes */ void LyXParagraph::Enlarge(int pos, int number)
{ int i;
/* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
NextAfterFootnote()->Enlarge(pos - last - 1, number); else
lyxerr.print("ERROR (LyXParagraph::Enlarge): position does not exist."); return;
}
if (size - last < number) {
size += number - size + last + STEP_SIZE_PAR; char *tmp = newchar[size]; for (i = 0; i < last; i++)
tmp[i] = text[i]; delete[] text;
text = tmp;
}
}
/* make the allocated memory fit to the needed size */ /* used to make a paragraph smaller */ void LyXParagraph::FitSize()
{ int i;
if (size - last > STEP_SIZE_PAR) {
size = last + STEP_SIZE_PAR; char *tmp = newchar[size]; for (i = 0; i < last; i++)
tmp[i] = text[i]; delete[] text;
text = tmp;
}
}
void LyXParagraph::InsertChar(int pos, char c)
{ registerint i;
/* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
NextAfterFootnote()->InsertChar(pos - last - 1, c); else
lyxerr.debug("ERROR (LyXParagraph::InsertChar): " "position does not exist."); return;
}
// Are we full? If so, enlarge. if (last == size) {
size += STEP_SIZE_PAR; char *tmp = newchar[size]; for (i = 0; i < last; i++)
tmp[i] = text[i]; delete[] text;
text = tmp;
}
// Shift rest of character for (i = last; i>pos; i--) {
text[i]=text[i-1];
}
text[pos]=c;
last++;
/* update the font table */
FontTable *tmp = fonttable; while (tmp) { if (tmp->pos >= pos)
tmp->pos++; if (tmp->pos_end >= pos)
tmp->pos_end++;
tmp = tmp->next;
}
/* update the inset table */
InsetTable *tmpi = insettable; while (tmpi) { if (tmpi->pos >= pos)
tmpi->pos++;
tmpi=tmpi->next;
}
}
void LyXParagraph::InsertInset(int pos, Inset *inset)
{ /* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
NextAfterFootnote()->InsertInset(pos - last - 1, inset); else
lyxerr.print("ERROR (LyXParagraph::InsertInset): " "position does not exist: " + pos); return;
}
if (text[pos]!=LYX_META_INSET) {
lyxerr.print("ERROR (LyXParagraph::InsertInset): " "there is no LYX_META_INSET"); return;
}
if (inset) { /* add a new entry in the inset table */
InsetTable *tmpi = new InsetTable;
tmpi->pos = pos;
tmpi->inset = inset;
tmpi->next = insettable;
insettable = tmpi;
}
}
Inset* LyXParagraph::GetInset(int pos)
{ if (pos >= last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) return NextAfterFootnote()->GetInset(pos - last - 1); else {
lyxerr.print(LString("ERROR (LyXParagraph::GetInset): position does not exist: ") + pos);
} return NULL;
}
/* find the inset */
InsetTable *tmpi = insettable;
while (tmpi && tmpi->pos != pos)
tmpi = tmpi->next;
if (tmpi) return tmpi->inset; else {
lyxerr.print(LString("ERROR (LyXParagraph::GetInset): " "Inset does not exist: ") + pos);
text[pos] = ' '; /// WHY!!! does this set the pos to ' '???? // Did this commenting out introduce a bug? So far I have not // seen any, please enlighten me. (Lgb) // My guess is that since the inset does not exist, we might // as well replace it with a space to prevent crashes. (Asger) return NULL;
}
}
// Gets uninstantiated font setting at position. // Optimized after profiling. (Asger)
LyXFont LyXParagraph::GetFontSettings(int pos)
{ if (pos < last) {
FontTable *tmp = fonttable; while (tmp) { if (pos >= tmp->pos && pos <= tmp->pos_end) return tmp->font;
tmp = tmp->next;
}
}
/* > because last is the next unused position, and you can
* use it if you want */ elseif (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) return NextAfterFootnote()->GetFontSettings(pos - last - 1); else { // Why is it an error to ask for the font of a // position that does not exist? Would it be // enough for this to be anable on debug? // We want strict error checking, but it's ok to only // have it when debugging. (Asger)
lyxerr.print(
LString("ERROR (LyXParagraph::GetFontSettings): " "position does not exist. ") + pos);
}
} elseif (pos) { return GetFontSettings(pos - 1);
} return LyXFont(LyXFont::ALL_INHERIT);
}
// Gets the fully instantiated font at a given position in a paragraph // This is basically the same function as LyXText::GetFont() in text2.C. // The difference is that this one is used for generating the LaTeX file, // and thus cosmetic "improvements" are disallowed: This has to deliver // the true picture of the buffer. (Asger) // If position is -1, we get the layout font of the paragraph. // If position is -2, we get the font of the manual label of the paragraph.
LyXFont LyXParagraph::getFont(int pos)
{
LyXFont tmpfont;
LyXLayout *layout = lyxstyle.Style(GetCurrentTextClass(),
GetLayout());
int main_body=0; if (layout->labeltype == LABEL_MANUAL)
main_body = BeginningOfMainBody();
if (pos >= 0){
LyXFont layoutfont; if (pos < main_body)
layoutfont = layout->labelfont; else
layoutfont = layout->font;
tmpfont = GetFontSettings(pos);
tmpfont.realize(layoutfont);
} else { // process layoutfont for pos == -1 and labelfont for pos < -1 if (pos == -1)
tmpfont = layout->font; else
tmpfont = layout->labelfont;
}
// check for environment font information char par_depth = GetDepth();
LyXParagraph * par = this; while (par && par_depth && !tmpfont.resolved()) {
par = par->DepthHook(par_depth - 1); if (par) {
tmpfont.realize(lyxstyle.
Style(GetCurrentTextClass(),
par->GetLayout())->font);
par_depth = par->GetDepth();
}
}
/// Returns the height of the highest font in range
LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(int startpos, int endpos) const
{
LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
char LyXParagraph::GetChar(int pos)
{ #ifdef DEVEL_VERSION /* a workaround to 'fix' some bugs in text-class */ if (pos < 0) { // This function is important. It should not work around bugs. // Let's find the bugs instead and fix them. (Asger)
lyxerr.print(LString("FATAL ERROR (LyXParagraph::GetChar):" " bad position ") + pos);
abort();
} #endif
if (pos < last) { return text[pos];
}
/* > because last is the next unused position, and you can
* use it if you want */ elseif (pos > last) { if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) return NextAfterFootnote()->GetChar(pos - last - 1); else
lyxerr.print("ERROR (LyXParagraph::GetChar): " "position does not exist."); return'\0';
} else { // pos==last /* we should have a footnote environment */ if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) { // Notice that LyX does request the last char from time to time. (Asger) // lyxerr.print("ERROR (LyXParagraph::GetChar): " // "expected footnote."); return'\0';
} switch (next->footnotekind) { case LyXParagraph::FOOTNOTE: return LYX_META_FOOTNOTE; case LyXParagraph::MARGIN: return LYX_META_MARGIN; case LyXParagraph::FIG: case LyXParagraph::WIDE_FIG: return LYX_META_FIG; case LyXParagraph::TAB: case LyXParagraph::WIDE_TAB: return LYX_META_TAB; case LyXParagraph::ALGORITHM: return LYX_META_ALGORITHM;
} // if (next->footnotekind == LyXParagraph::FOOTNOTE) // return LYX_META_FOOTNOTE; // if (next->footnotekind == LyXParagraph::MARGIN) // return LYX_META_MARGIN; // if (next->footnotekind == LyXParagraph::FIG) // return LYX_META_FIG; // if (next->footnotekind == LyXParagraph::TAB) // return LYX_META_TAB; // if (next->footnotekind == LyXParagraph::ALGORITHM) // return LYX_META_ALGORITHM; // lyxerr.print("ERROR (LyXParagraph::GetChar): " // "unknown footnote kind."); // return 'F'; /* this should not happen! */ // This _can_ not happen, due to the type of next->footnotekind // being LyXParagraph::footnot_kind return'\0'; // to shut up gcc
}
}
LString LyXParagraph::GetWord(int & lastpos)
//Added 98/9/21 by REH // return an LString of the current word, and the end of the word // in lastpos.
// the current word is defined as starting at the first character from // the immediate left of lastpospos which meets the definition of IsLetter(), // continuing to the last character to the right of this meeting // IsLetter.
// i just left this in from GetChar()
{ #ifdef DEVEL_VERSION /* a workaround to 'fix' some bugs in text-class */ if (lastpos < 0) { // This function is important. It should not work around bugs. // Let's find the bugs instead and fix them. (Asger)
lyxerr.print(LString("FATAL ERROR (LyXParagraph::GetWord):" " bad position ") + lastpos);
abort();
} #endif
LString theword;
// grab a word
//i think the devcode aborts before this, but why not be // versatile? if (lastpos < 0) lastpos=0;
// move back until we have a letter
//there's no real reason to have firstpos & lastpos as //separate variables as this is written, but maybe someon // will want to return firstpos in the future.
//since someone might have typed a punctuation first int firstpos = lastpos;
// the above is no pointing to the preceeding non-letter
firstpos++;
lastpos=firstpos;
// so copy characters into theword until we get a nonletter // note that this can easily exceed lastpos, wich means // that if used in the middle of a word, the whole word // is included
while (IsLetter(lastpos)) theword += text[lastpos++];
return theword;
}
int LyXParagraph::Last()
{ if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) return last + NextAfterFootnote()->Last() + 1; /* the 1 is the symbol
* for the footnote */ else return last;
}
LyXParagraph *LyXParagraph::ParFromPos(int pos)
{ /* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) return NextAfterFootnote()->ParFromPos(pos - last - 1); else
lyxerr.print("ERROR (LyXParagraph::ParFromPos): " "position does not exist."); returnthis;
} else returnthis;
}
int LyXParagraph::PositionInParFromPos(int pos)
{ /* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) return NextAfterFootnote()->PositionInParFromPos(pos - last - 1); else
lyxerr.print( "ERROR (LyXParagraph::PositionInParFromPos): " "position does not exist."); return pos;
} else return pos;
}
void LyXParagraph::SetFont(int pos, LyXFont const & font)
{ /* > because last is the next unused position, and you can
* use it if you want */ if (pos > last) { if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
NextAfterFootnote()->SetFont(pos - last - 1, font);
} else {
lyxerr.print("ERROR (LyXParagraph::SetFont): " "position does not exist.");
} return;
}
LyXFont patternfont(LyXFont::ALL_INHERIT);
// First, reduce font against layout/label font // Update: The SetCharFont() routine in text2.C already reduces font, so // we don't need to do that here. (Asger) // No need to simplify this because it will disappear in a new kernel. (Asger)
// Next search font table
FontTable *tmp2;
bool found = false;
FontTable *tmp = fonttable; while (tmp && !found) { if (pos >= tmp->pos && pos <= tmp->pos_end)
found = true; else
tmp = tmp->next;
}
if (!found) { /* if we did not find a font entry, but if the font at hand
* is the same as default, we just forget it */ if (font == patternfont) return;
/* ok, we did not find a font entry. But maybe there is exactly
* the needed font entry one position left */
found = false;
tmp2 = fonttable; while (tmp2 && !found) { if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
found = true; else
tmp2 = tmp2->next;
} if (found) { /* ok there is one. maybe it is exactly the needed font */ if (tmp2->font == font) { /* put the position under the font */
tmp2->pos_end++; return;
}
} /* Add a new entry in the
* fonttable for the position */
tmp = new FontTable;
tmp->pos = pos;
tmp->pos_end = pos;
tmp->font = patternfont;
tmp->next = fonttable;
fonttable = tmp;
} else { /* we found a font entry. maybe we have to split it and create
* a new one */
if (tmp->pos != tmp->pos_end) { /* more than one character */
if (pos == tmp->pos) { /* maybe we could enlarge the left fonttable */
found = false;
tmp2 = fonttable; while (tmp2 && !found) { if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
found = true; else
tmp2 = tmp2->next;
}
/* Is there is one, and is it exactly the needed font? */ if (found && tmp2->font == font) { /* put the position under the font */
tmp2->pos_end++;
tmp->pos++; return;
}
/* Add a new entry in the
* fonttable for the position */
tmp2 = new FontTable;
tmp2->pos = pos + 1;
tmp2->pos_end = tmp->pos_end;
tmp2->font = tmp->font;
tmp->pos_end = pos;
tmp2->next = fonttable;
fonttable = tmp2;
} elseif (pos == tmp->pos_end) { /* Add a new entry in the
* fonttable for the position */
tmp2 = new FontTable;
tmp2->pos = tmp->pos;
tmp2->pos_end = tmp->pos_end - 1;
tmp2->font = tmp->font;
tmp->pos = tmp->pos_end;
tmp2->next = fonttable;
fonttable = tmp2;
} else { /* Add a new entry in the
* fonttable for the position */
tmp2 = new FontTable;
tmp2->pos = tmp->pos;
tmp2->pos_end = pos - 1;
tmp2->font = tmp->font;
tmp2->next = fonttable;
fonttable = tmp2;
/* this function is able to hide closed footnotes */
LyXParagraph *LyXParagraph::Next()
{
LyXParagraph *tmp; if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
tmp = next; while (tmp && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
tmp = tmp->next; if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) return tmp->Next(); /* there can be more than one footnote
* in a logical paragraph */ else return next; /* this should never happen! */
} else return next;
}
LyXParagraph *LyXParagraph::NextAfterFootnote()
{
LyXParagraph *tmp; if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
tmp = next; while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
tmp = tmp->next; if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) return tmp; /* there can be more than one footnote
* in a logical paragraph */ else return next; /* this should never happen! */
} else return next;
}
LyXParagraph *LyXParagraph::PreviousBeforeFootnote()
{
LyXParagraph *tmp; if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
tmp = next; while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
tmp = tmp->previous; if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) return tmp; /* there can be more than one footnote
* in a logical paragraph */ else return previous; /* this should never happen! */
} else return previous;
}
LyXParagraph *LyXParagraph::LastPhysicalPar()
{
LyXParagraph *tmp; if (footnoteflag != LyXParagraph::NO_FOOTNOTE) returnthis;
/* this is an idea for a more userfriendly layout handling, I will
* see what the users say */
/* layout stays the same with latex-environments */ if (flag) {
tmp->SetOnlyLayout(firstpar->layout);
tmp->SetLabelWidthString(firstpar->labelwidthstring);
}
if (Last() > pos || !Last() || flag == 2) {
tmp->SetOnlyLayout(firstpar->layout);
tmp->align = firstpar->align;
tmp->SetLabelWidthString(firstpar->labelwidthstring);
/* copy everything behind the break-position to the new paragraph */
pos_first = 0; while (ParFromPos(pos_first) != par)
pos_first++;
pos_end = pos_first + par->last - 1;
/* make sure there is enough memory for the now larger paragraph.Thisisnotneccessary,because InsertFromMinibufferwillenlargethememory(ituses InsertCharofcourse).Butdoingitbyhand
is MUCH faster! (only one time, not thousend times!!) */
tmp->Enlarge(0, pos_end - pos);
for (i = pos; i <= pos_end; i++) {
par->CutIntoMinibuffer(i - pos_first);
tmp->InsertFromMinibuffer(i - pos);
}
for (i = pos_end; i >= pos; i--)
par->Erase(i - pos_first); /* free memory of the now shorter paragraph*/
par->FitSize();
}
/* just an idea of me */ if (!pos) {
tmp->line_top = firstpar->line_top;
tmp->pagebreak_top = firstpar->pagebreak_top;
tmp->added_space_top = firstpar->added_space_top;
tmp->bibkey = firstpar->bibkey;
firstpar->Clear(); /* layout stays the same with latex-environments */ if (flag) {
firstpar->SetOnlyLayout(tmp->layout);
firstpar->SetLabelWidthString(tmp->labelwidthstring);
firstpar->depth = tmp->depth;
}
}
}
// ale970302
result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
/* copy everything behind the break-position to the new paragraph */
/* make shure there is enough memory for the now larger paragraph. *Thisisnotneccessary,becauseInsertFromMinibufferwillenlarge *thememory(itusesInsertCharofcourse).Butdoingitbyhand
* is MUCH faster! (only one time, not thousend times!!) */
result->Enlarge(0, last+2);
for (i = 0; i < last; i++) {
CopyIntoMinibuffer(i);
result->InsertFromMinibuffer(i);
} return result;
}
bool LyXParagraph::HasSameLayout(LyXParagraph* par)
{
par = par->FirstPhysicalPar();
void LyXParagraph::BreakParagraphConservative(int pos)
{ int i, pos_end, pos_first;
/* create a new paragraph */
LyXParagraph *par = ParFromPos(pos);
LyXParagraph *tmp = new LyXParagraph(par);
tmp->MakeSameLayout(par);
if (Last() > pos) { /* copy everything behind the break-position to the new
paragraph */
pos_first = 0; while (ParFromPos(pos_first) != par)
pos_first++;
pos_end = pos_first + par->last - 1;
/* make shure there is enough memory for the now larger paragraph.Thisisnotneccessary,because InsertFromMinibufferwillenlargethememory(ituses InsertCharofcourse).Butdoingitbyhand
is MUCH faster! (only one time, not thousend times!!) */
tmp->Enlarge(0, pos_end - pos);
for (i = pos; i <= pos_end; i++) {
par->CutIntoMinibuffer(i - pos_first);
tmp->InsertFromMinibuffer(i - pos);
} for (i = pos_end; i >= pos; i--)
par->Erase(i - pos_first);
/* free memory of the now shorter paragraph*/
par->FitSize();
}
}
/* be carefull, this does not make any check at all */ void LyXParagraph::PasteParagraph()
{ int i, pos_end, pos_insert;
LyXParagraph *the_next;
/* copy the next paragraph to this one */
the_next = Next();
LyXParagraph *firstpar = FirstPhysicalPar();
/* first the DTP-stuff */
firstpar->line_bottom = the_next->line_bottom;
firstpar->added_space_bottom = the_next->added_space_bottom;
firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
/* the next two functions are for the manual labels */
LString LyXParagraph::GetLabelWidthString()
{ if (!FirstPhysicalPar()->labelwidthstring.empty()) return FirstPhysicalPar()->labelwidthstring; else return _("Senseless with this layout!");
}
/* if the layout of a paragraph contains a manual label, the beginning of the *mainbodyisthebeginningofthesecondword.Thisiswhatthepar- *functionreturns.Ifthelayoutdoesnotcontainalabel,themain *bodyalwaysstartswithposition0.Thisdifferentiationisnecessary, *becausetherecannotbeanewlineorablank<=thebeginningofthe
* main body in TeX. */
int LyXParagraph::BeginningOfMainBody()
{ if (FirstPhysicalPar() != this) return -1;
int i = 0;
// while (i < last && !(i > 1 && GetChar(i-1)==' ') // && GetChar(i)!=LYX_META_NEWLINE) // i++; // Unroll the first two cycles of this loop // and remember the previous character to remove unnecessary GetChar() calls
if (i < last
&& GetChar(i) != LYX_META_NEWLINE) {
++i; char previous_char, temp; if (i < last
&& (previous_char = GetChar(i)) != LYX_META_NEWLINE) { // Yes, this ^ is supposed to be "=" not "=="
++i; while (i < last
&& previous_char != ' '
&& (temp = GetChar(i)) != LYX_META_NEWLINE) {
++i;
previous_char = temp;
}
}
}
if (i==0 && i == last &&
!(footnoteflag==LyXParagraph::NO_FOOTNOTE
&& next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
)
i++; /* the cursor should not jump *tothemainbodyifthere
* is nothing in! */ return i;
}
FileInfo fileInfo(fileno(myfile)); long file_size = fileInfo.getSize(); /* it is horrible, I know, but faster.
* I should not use InsertString for that :-( */
/* I will write a better insertion in the future */
Enlarge(0, file_size + 10);
rewind(myfile);
if (!feof(myfile)) { do {
c = fgetc(myfile);
InsertChar(last,c);
} while (!feof(myfile));
if (further_blank_line){
file += '\n';
texrow.newline();
}
switch (style->latextype) { case LATEX_COMMAND:
file += '\\';
file += style->latexname;
file += style->latexparam; break; case LATEX_ITEM_ENVIRONMENT: if (bibkey)
bibkey->Latex(file, false); else
file += "\\item "; break; case LATEX_LIST_ENVIRONMENT:
file += "\\item "; break; default: break;
}
bool need_par = SimpleTeXOnePar(file, texrow);
// Spit out footnotes while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
&& par->footnoteflag != footnoteflag) {
par = par->TeXFootnote(file, texrow,
foot, foot_texrow, foot_count);
par->SimpleTeXOnePar(file, texrow);
par = par->next;
}
// Make sure that \\par is done with the font of the last // character if this has another size as the default. // This is necessary because LaTeX (and LyX on the screen) // calculates the space between the baselines according // to this font. (Matthias)
LyXFont font = getFont(Last()-1); if (need_par) { if (style->resfont.size() != font.size()) {
file += '\\';
file += font.latexSize();
file += ' ';
}
file += "\\par}";
} elseif (lyxstyle.Style(GetCurrentTextClass(),
GetLayout())->isCommand()){ if (style->resfont.size() != font.size()) {
file += '\\';
file += font.latexSize();
file += ' ';
}
file += '}';
} elseif (style->resfont.size() != font.size()){
file += "{\\" + font.latexSize() + " \\par}";
}
switch (style->latextype) { case LATEX_ITEM_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: if (par && (depth < par->depth)) {
file += '\n';
texrow.newline();
} break; case LATEX_ENVIRONMENT: // if its the last paragraph of the current environment // skip it otherwise fall through if (par
&& !par->HasSameLayout(this)) { break;
} default: if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
&& footnotekind != LyXParagraph::FOOTNOTE
&& footnotekind != LyXParagraph::MARGIN
&& (table
|| (par
&& par->table)))) { // don't insert this if we would be adding it // before or after a table in a float. This // little trick is needed in order to allow // use of tables in \subfigures or \subtables.
file += '\n';
texrow.newline();
}
}
// This one spits out the text of the paragraph bool LyXParagraph::SimpleTeXOnePar(LString &file, TexRow &texrow)
{
lyxerr.debug(LString("SimpleTeXOnePar... ")+(long)this, Error::LATEX); if (table) return SimpleTeXOneTablePar(file, texrow); char c; int main_body; int column;
// Which font is currently active?
LyXFont running_font = basefont; // Do we have an open font change? bool open_font = false;
texrow.start(this, 0);
for (int i = 0; i < last; i++) {
column++; // First char in paragraph or after label? if (i == main_body && !IsDummy()) { if (main_body > 0) { if (open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
open_font = false;
}
basefont = getFont(-1); // Now use the layout font
running_font = basefont;
file += ']';
column++;
} if (style->isCommand()) {
file += '{';
column++;
} elseif (align != LYX_ALIGN_LAYOUT) {
file += "{\\par";
column += 4;
return_value = true;
}
if (noindent) {
file += "\\noindent ";
column += 10;
} switch (align) { case LYX_ALIGN_LEFT:
file += "\\raggedright ";
column+=13; break; case LYX_ALIGN_RIGHT:
file += "\\raggedleft ";
column+=12; break; case LYX_ALIGN_CENTER:
file += "\\centering ";
column+=11; break;
}
}
c = GetChar(i);
// Fully instantiated font
LyXFont font = getFont(i);
// Spaces at end of font change are simulated to be // outside font change, i.e. we write "\textXX{text} " // rather than "\textXX{text }". (Asger) if (open_font && c == ' ' && i <= last-2
&& !getFont(i+1).equalExceptLatex(running_font)
&& !getFont(i+1).equalExceptLatex(font)) {
font = getFont(i+1);
}
// We end font definition before blanks if (!font.equalExceptLatex(running_font) && open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
running_font = basefont;
open_font = false;
}
// Blanks are printed before start of fontswitch if (c == ' '){ // Do not print the separation of the optional argument if (i != main_body - 1) {
SimpleTeXBlanks(file, texrow, i, column, font, style);
}
}
// Do we need to change font? if (!font.equalExceptLatex(running_font)
&& i != main_body-1) {
column += font.latexWriteStartChanges(file, basefont);
running_font = font;
open_font = true;
}
if (c == LYX_META_NEWLINE) { // newlines are handled differently here than // the default in SimpleTeXSpecialChars(). if (!style->newline_allowed
|| font.latex() == LyXFont::ON) {
file += '\n';
} else { if (open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
open_font = false;
}
basefont = getFont(-1);
running_font = basefont; if (font.family() ==
LyXFont::TYPEWRITER_FAMILY) {
file += "~";
}
file += "\\\\\n";
}
texrow.newline();
texrow.start(this, i+1);
column = 0;
} else {
SimpleTeXSpecialChars(file, texrow,
font, running_font, basefont,
open_font, style, i, column, c);
}
}
// If we have an open font definition, we have to close it if (open_font) {
running_font.latexWriteEndChanges(file, basefont);
}
/* needed if there is an optional argument but no contents */ if (main_body > 0 && main_body == last) {
file += "]~";
return_value = false;
}
// This one spits out the text of a table paragraph bool LyXParagraph::SimpleTeXOneTablePar(LString &file, TexRow &texrow)
{
lyxerr.debug(LString("SimpleTeXOneTablePar... ")+(long)this, Error::LATEX); char c; int column, tmp;
bool return_value = false; int current_cell_number = -1;
basefont = getFont(-1); // Get layout font // Which font is currently active?
LyXFont running_font = basefont; // Do we have an open font change? bool open_font = false;
for (int i = 0; i < last; i++) {
c = GetChar(i); if (table->IsContRow(current_cell_number+1)) { if (c == LYX_META_NEWLINE)
current_cell_number++; continue;
}
column++;
// Fully instantiated font
LyXFont font = getFont(i);
// Spaces at end of font change are simulated to be outside font change. // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger) if (open_font && c == ' ' && i <= last-2
&& getFont(i+1) != running_font && getFont(i+1) != font) {
font = getFont(i+1);
}
// We end font definition before blanks if (font != running_font && open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
running_font = basefont;
open_font = false;
} // Blanks are printed before start of fontswitch if (c == ' '){
SimpleTeXBlanks(file, texrow, i, column, font, style);
} // Do we need to change font? if (font != running_font) {
column += font.latexWriteStartChanges(file, basefont);
running_font = font;
open_font = true;
} // Do we need to turn on LaTeX mode? if (font.latex() != running_font.latex()) { if (font.latex() == LyXFont::ON
&& style->needprotect)
{
file += "\\protect ";
column += 9;
}
} if (c == LYX_META_NEWLINE) { // special case for inside a table // different from default case in SimpleTeXSpecialChars() if (open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
open_font = false;
}
basefont = getFont(-1);
running_font = basefont;
current_cell_number++; if (table->CellHasContRow(current_cell_number) >= 0) {
TeXContTableRows(file, i+1, current_cell_number, column, texrow);
} // if this cell follow only ContRows till end don't // put the EndOfCell because it is put after the // for(...) if (table->ShouldBeVeryLastCell(current_cell_number)) {
current_cell_number--; break;
} int tmp = table->TexEndOfCell(file, current_cell_number); if (tmp>0) {
column = 0;
} elseif (tmp < 0) {
tmp = -tmp;
} for (;tmp--;) {
texrow.newline();
}
texrow.start(this, i+1);
} else {
SimpleTeXSpecialChars(file, texrow,
font, running_font, basefont,
open_font, style, i, column, c);
}
}
// If we have an open font definition, we have to close it if (open_font) {
running_font.latexWriteEndChanges(file, basefont);
}
current_cell_number++;
tmp = table->TexEndOfCell(file, current_cell_number); for (;tmp>0;tmp--)
texrow.newline();
lyxerr.debug(LString("SimpleTeXOneTablePar...done ")+(long)this, Error::LATEX); return return_value;
}
// This one spits out the text off ContRows in tables bool LyXParagraph::TeXContTableRows(LString &file, int i, int current_cell_number, int &column, TexRow &texrow)
{
lyxerr.debug(LString("TeXContTableRows... ")+(long)this, Error::LATEX); if (!table) returnfalse;
basefont = getFont(-1); // Get layout font // Which font is currently active?
LyXFont running_font = basefont; // Do we have an open font change? bool open_font = false;
lastpos = i;
cell = table->CellHasContRow(current_cell_number);
current_cell_number++; while(cell >= 0) { // first find the right position
i = lastpos; for (; (i<last) && (current_cell_number<cell); i++) {
c = GetChar(i); if (c == LYX_META_NEWLINE)
current_cell_number++;
}
lastpos = i;
c=GetChar(i); if (table->Linebreaks(table->FirstVirtualCell(cell))) {
file += " \\\\\n";
texrow.newline();
column = 0;
} elseif ((c != ' ') && (c != LYX_META_NEWLINE)) {
file += ' ';
} for (; (i < last) && ((c=GetChar(i)) != LYX_META_NEWLINE); i++) {
column++;
// Fully instantiated font
LyXFont font = getFont(i);
// Spaces at end of font change are simulated to be outside font change. // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger) if (open_font && c == ' ' && i <= last-2
&& getFont(i+1) != running_font && getFont(i+1) != font) {
font = getFont(i+1);
}
// We end font definition before blanks if (font != running_font && open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
running_font = basefont;
open_font = false;
} // Blanks are printed before start of fontswitch if (c == ' '){
SimpleTeXBlanks(file, texrow, i, column, font, style);
} // Do we need to change font? if (font != running_font) {
column += font.latexWriteStartChanges(file, basefont);
running_font = font;
open_font = true;
} // Do we need to turn on LaTeX mode? if (font.latex() != running_font.latex()) { if (font.latex() == LyXFont::ON
&& style->needprotect)
{
file += "\\protect ";
column += 9;
}
}
SimpleTeXSpecialChars(file, texrow, font, running_font, basefont,
open_font, style, i, column, c);
} // If we have an open font definition, we have to close it if (open_font) {
running_font.latexWriteEndChanges(file, basefont);
open_font = false;
}
basefont = getFont(-1);
running_font = basefont;
cell = table->CellHasContRow(current_cell_number);
}
lyxerr.debug(LString("TeXContTableRows...done ")+(long)this, Error::LATEX); return return_value;
}
// void LyXParagraph::SimpleTeXBlanks(LString &file, TexRow &texrow, intconst i, int &column, LyXFont const &font,
LyXLayout const * const style)
{ if (column > tex_code_break_column
&& i
&& GetChar(i-1) != ' '
&& (i < last-1) // In LaTeX mode, we don't want to // break lines since some commands // do not like this
&& ! (font.latex() == LyXFont::ON) // same in FreeSpacing mode
&& !style->free_spacing // In typewriter mode, we want to avoid // ! . ? : at the end of a line
&& !(font.family() == LyXFont::TYPEWRITER_FAMILY
&& (GetChar(i-1) == '.'
|| GetChar(i-1) == '?'
|| GetChar(i-1) == ':'
|| GetChar(i-1) == '!'))) { if (tex_code_break_column == 0) { // in batchmode we need LaTeX to still // see it as a space not as an extra '\n'
file += " %\n";
} else {
file += '\n';
}
texrow.newline();
texrow.start(this, i+1);
column = 0;
} elseif (font.latex() == LyXFont::OFF) { if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
file += '~';
} else {
file += ' ';
}
}
}
// void LyXParagraph::SimpleTeXSpecialChars(LString &file, TexRow &texrow,
LyXFont &font, LyXFont &running_font, LyXFont &basefont, bool &open_font, LyXLayout const * const style, int &i, int &column, charconst c)
{
Inset* inset;
// Two major modes: LaTeX or plain // Handle here those cases common to both modes // and then split to handle the two modes separately. switch (c) { case LYX_META_INSET:
inset = GetInset(i); if (inset) { int len = file.length(); int tmp = inset->Latex(file, style->isCommand());
case LYX_META_NEWLINE: if (open_font) {
column += running_font.latexWriteEndChanges(file, basefont);
open_font = false;
}
basefont = getFont(-1);
running_font = basefont; break;
case LYX_META_HFILL:
file += "\\hfill{}";
column += 7; break;
default: // And now for the special cases within each mode // Are we in LaTeX mode? if (font.latex() == LyXFont::ON) { // at present we only have one option // but I'll leave it as a switch statement // so its simpler to extend. (ARRae) switch (c) { case LYX_META_PROTECTED_SEPARATOR:
file += ' '; break;
default: // make sure that we will not print // error generating chars to the tex // file. This test would not be needed // if it were done in the buffer // itself. if (c != '\0') {
file += c;
} break;
}
} else { // Plain mode (i.e. not LaTeX) switch (c) { case LYX_META_PROTECTED_SEPARATOR:
file += '~'; break;
case' ': /* blanks are printed before font switching */ // Sure? I am not! (try nice-latex) // I am sure it's correct. LyX might be smarter // in the future, but for now, nothing wrong is // written. (Asger) break;
if (style->needprotect && footnotekind != LyXParagraph::FOOTNOTE){
lyxerr.print("ERROR (LyXParagraph::TeXFootnote): " "Float other than footnote in command" " with moving argument is illegal");
}
if (footnotekind != LyXParagraph::FOOTNOTE
&& footnotekind != LyXParagraph::MARGIN
&& file.length()
&& !file.suffixIs('\n')) { // we need to ensure that real floats like tables and figures // have their \begin{} on a new line otherwise we can get // incorrect results when using the endfloat.sty package // especially if two floats follow one another. ARRae 981022 // NOTE: if the file is length 0 it must have just been // written out so we assume it ended with a '\n'
file += '\n';
texrow.newline();
}
BufferParams *params = ¤t_view->currentBuffer()->params; bool footer_in_body = true; switch (footnotekind) { case LyXParagraph::FOOTNOTE: if (style->intitle) {
file += "\\thanks{\n";
footer_in_body = false;
} else { if (foot_count == -1) { // we're at depth 0 so we can use:
file += "\\footnote{\n";
footer_in_body = false;
} else {
file += "\\footnotemark{}%\n"; if (foot_count) { // we only need this when there are // multiple footnotes
foot += "\\stepcounter{footnote}";
}
foot += "\\footnotetext{\n";
foot_texrow.start(this,0);
foot_texrow.newline();
++foot_count;
}
} break; case LyXParagraph::MARGIN:
file += "\\marginpar{\n"; break; case LyXParagraph::FIG: if (pextra_type == PEXTRA_FLOATFLT
&& (!pextra_width.empty()
|| !pextra_widthp.empty())) { char bufr[80]; if (!pextra_width.empty())
sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
pextra_width.c_str()); else
sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
atoi(pextra_widthp.c_str())/100.0);
file += bufr;
} else {
file += "\\begin{figure}"; if (!params->float_placement.empty()) {
file += '[';
file += params->float_placement;
file += "]\n";
} else {
file += '\n';
}
} break; case LyXParagraph::TAB:
file += "\\begin{table}"; if (!params->float_placement.empty()) {
file += '[';
file += params->float_placement;
file += "]\n";
} else {
file += '\n';
} break; case LyXParagraph::WIDE_FIG:
file += "\\begin{figure*}"; if (!params->float_placement.empty()) {
file += '[';
file += params->float_placement;
file += "]\n";
} else {
file += '\n';
} break; case LyXParagraph::WIDE_TAB:
file += "\\begin{table*}"; if (!params->float_placement.empty()) {
file += '[';
file += params->float_placement;
file += "]\n";
} else {
file += '\n';
} break; case LyXParagraph::ALGORITHM:
file += "\\begin{algorithm}\n"; break;
}
texrow.newline();
if (footnotekind != LyXParagraph::FOOTNOTE
|| !footer_in_body) { // Process text for all floats except footnotes in body do {
LyXLayout *style = lyxstyle.Style(GetCurrentTextClass(),
par->layout); if (par->IsDummy())
lyxerr.print("ERROR (LyXParagraph::TeXFootnote)"); if (style->isEnvironment()
|| par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */ // Allows the use of minipages within float environments. // Shouldn't be circular because we don't support // footnotes inside floats (yet). ARRae
par = par->TeXEnvironment(file, texrow,
foot, foot_texrow,
foot_count);
} else {
par = par->TeXOnePar(file, texrow,
foot, foot_texrow,
foot_count);
}
if (par && !par->IsDummy() && par->depth > depth) {
par = par->TeXDeeper(file, texrow,
foot, foot_texrow,
foot_count);
}
} while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
} else { // process footnotes > depth 0 or in environments separately // NOTE: Currently don't support footnotes within footnotes // even though that is possible using the \footnotemark
LString dummy;
TexRow dummy_texrow; int dummy_count = 0; do {
LyXLayout *style = lyxstyle.Style(GetCurrentTextClass(),
par->layout); if (par->IsDummy())
lyxerr.print("ERROR (LyXParagraph::TeXFootnote)"); if (style->isEnvironment()
|| par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */ // Allows the use of minipages within float environments. // Shouldn't be circular because we don't support // footnotes inside floats (yet). ARRae
par = par->TeXEnvironment(foot, foot_texrow,
dummy, dummy_texrow,
dummy_count);
} else {
par = par->TeXOnePar(foot, foot_texrow,
dummy, dummy_texrow,
dummy_count);
}
if (par && !par->IsDummy() && par->depth > depth) {
par = par->TeXDeeper(foot, foot_texrow,
dummy, dummy_texrow,
dummy_count);
}
} while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE); if (dummy_count) {
lyxerr.print("ERROR (LyXParagraph::TeXFootnote): " "Footnote in a Footnote -- not supported");
}
}
switch (footnotekind) { case LyXParagraph::FOOTNOTE: if (footer_in_body) { // This helps tell which of the multiple // footnotetexts an error was in.
foot += "}%\n";
foot_texrow.newline();
} else {
file += '}';
} break; case LyXParagraph::MARGIN:
file += '}'; break; case LyXParagraph::FIG: if (pextra_type == PEXTRA_FLOATFLT
&& (!pextra_width.empty()
|| !pextra_widthp.empty()))
file += "\\end{floatingfigure}"; else
file += "\\end{figure}"; break; case LyXParagraph::TAB:
file += "\\end{table}"; break; case LyXParagraph::WIDE_FIG:
file += "\\end{figure*}"; break; case LyXParagraph::WIDE_TAB:
file += "\\end{table*}"; break; case LyXParagraph::ALGORITHM:
file += "\\end{algorithm}"; break;
}
if (footnotekind != LyXParagraph::FOOTNOTE
&& footnotekind != LyXParagraph::MARGIN) { // we need to ensure that real floats like tables and figures // have their \end{} on a line of their own otherwise we can // get incorrect results when using the endfloat.sty package.
file += "\n";
texrow.newline();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.