mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Allow paragraph and line breaks in multirow (#12083)
This commit is contained in:
parent
526d2841df
commit
5979a01b1d
@ -4154,11 +4154,11 @@ def revert_vcolumns2(document):
|
||||
endcell = find_token(document.body, "</cell>", begcell)
|
||||
vcand = False
|
||||
if find_token(document.body, "\\begin_inset Newline", begcell, endcell) != -1:
|
||||
vcand = not fixedwidth and not multirow
|
||||
vcand = not fixedwidth
|
||||
elif count_pars_in_inset(document.body, begcell + 2) > 1:
|
||||
vcand = not fixedwidth and not multirow
|
||||
vcand = not fixedwidth
|
||||
elif get_value(document.body, "\\begin_layout", begcell) != "Plain Layout":
|
||||
vcand = not fixedwidth and not multirow
|
||||
vcand = not fixedwidth
|
||||
colalignment = col_info[col][2]
|
||||
colvalignment = col_info[col][3]
|
||||
if vcand:
|
||||
@ -4174,13 +4174,12 @@ def revert_vcolumns2(document):
|
||||
document.body[col_line] = document.body[col_line][:-1] + " special=\"" + vval + "\">"
|
||||
else:
|
||||
alarg = ""
|
||||
if multicolumn:
|
||||
if multicolumn or multirow:
|
||||
if cellvalign == "middle":
|
||||
alarg = "[m]"
|
||||
elif cellvalign == "bottom":
|
||||
alarg = "[b]"
|
||||
else:
|
||||
document.warning("col: %i, alignment: %s" % (col, colvalignment))
|
||||
if colvalignment == "middle":
|
||||
alarg = "[m]"
|
||||
elif colvalignment == "bottom":
|
||||
@ -4209,6 +4208,20 @@ def revert_vcolumns2(document):
|
||||
document.body[nl:nl+1] = put_cmd_in_ert("\\linebreak{}")
|
||||
else:
|
||||
document.body[nl:nl+1] = put_cmd_in_ert("\\\\")
|
||||
# Replace parbreaks in multirow with \\endgraf
|
||||
if multirow == True:
|
||||
flt = find_token(document.body, "\\begin_layout", begcell, endcell)
|
||||
if flt != -1:
|
||||
while True:
|
||||
elt = find_end_of_layout(document.body, flt)
|
||||
if elt == -1:
|
||||
document.warning("Malformed LyX document! Missing layout end.")
|
||||
break
|
||||
endcell = find_token(document.body, "</cell>", begcell)
|
||||
flt = find_token(document.body, "\\begin_layout", elt, endcell)
|
||||
if flt == -1:
|
||||
break
|
||||
document.body[elt : flt + 1] = put_cmd_in_ert("\\endgraf{}")
|
||||
m += 1
|
||||
|
||||
i = j
|
||||
|
@ -245,6 +245,11 @@ public:
|
||||
*/
|
||||
mutable docstring post_macro;
|
||||
|
||||
/** Whether we in a command that is not \\long (i.e. cannot have multiple
|
||||
* paragraphs)
|
||||
*/
|
||||
mutable bool isNonLong = false;
|
||||
|
||||
/** Whether we are entering a display math inset.
|
||||
* Needed to correctly strike out deleted math in change tracking.
|
||||
*/
|
||||
|
@ -1321,24 +1321,7 @@ void toggleFixedWidth(Cursor & cur, InsetTableCell * inset,
|
||||
if (!multirow)
|
||||
return;
|
||||
|
||||
// merge all paragraphs to one
|
||||
BufferParams const & bp = cur.bv().buffer().params();
|
||||
while (inset->paragraphs().size() > 1)
|
||||
mergeParagraph(bp, inset->paragraphs(), 0);
|
||||
|
||||
// This is relevant for multirows
|
||||
if (fixedWidth)
|
||||
return;
|
||||
|
||||
// remove newlines
|
||||
ParagraphList::iterator pit = inset->paragraphs().begin();
|
||||
for (; pit != inset->paragraphs().end(); ++pit) {
|
||||
for (pos_type j = 0; j != pit->size(); ++j) {
|
||||
if (pit->isNewline(j))
|
||||
pit->eraseChar(j, bp.track_changes);
|
||||
}
|
||||
}
|
||||
|
||||
// reset layout
|
||||
cur.push(*inset);
|
||||
// undo information has already been recorded
|
||||
@ -3165,6 +3148,8 @@ void Tabular::TeXRow(otexstream & os, row_type row,
|
||||
} else if (!isPartOfMultiRow(row, c)) {
|
||||
if (!runparams.nice)
|
||||
os.texrow().start(par.id(), 0);
|
||||
if (isMultiRow(cell))
|
||||
newrp.isNonLong = true;
|
||||
inset->latex(os, newrp);
|
||||
}
|
||||
|
||||
@ -5723,8 +5708,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s,
|
||||
// fall through
|
||||
case Tabular::VALIGN_TOP:
|
||||
status.setEnabled((!tabular.getPWidth(cur.idx()).zero()
|
||||
|| tabular.getUsebox(cur.idx()) == Tabular::BOX_VARWIDTH)
|
||||
&& !tabular.isMultiRow(cur.idx()));
|
||||
|| tabular.getUsebox(cur.idx()) == Tabular::BOX_VARWIDTH));
|
||||
status.setOnOff(
|
||||
tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_TOP);
|
||||
break;
|
||||
@ -5734,8 +5718,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s,
|
||||
// fall through
|
||||
case Tabular::VALIGN_BOTTOM:
|
||||
status.setEnabled((!tabular.getPWidth(cur.idx()).zero()
|
||||
|| tabular.getUsebox(cur.idx()) == Tabular::BOX_VARWIDTH)
|
||||
&& !tabular.isMultiRow(cur.idx()));
|
||||
|| tabular.getUsebox(cur.idx()) == Tabular::BOX_VARWIDTH));
|
||||
status.setOnOff(
|
||||
tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_BOTTOM);
|
||||
break;
|
||||
@ -5745,8 +5728,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s,
|
||||
// fall through
|
||||
case Tabular::VALIGN_MIDDLE:
|
||||
status.setEnabled((!tabular.getPWidth(cur.idx()).zero()
|
||||
|| tabular.getUsebox(cur.idx()) == Tabular::BOX_VARWIDTH)
|
||||
&& !tabular.isMultiRow(cur.idx()));
|
||||
|| tabular.getUsebox(cur.idx()) == Tabular::BOX_VARWIDTH));
|
||||
status.setOnOff(
|
||||
tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_MIDDLE);
|
||||
break;
|
||||
@ -6047,20 +6029,8 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
return cell(cur.idx())->getStatus(cur, cmd, status);
|
||||
}
|
||||
|
||||
// disable in non-fixed-width cells
|
||||
case LFUN_PARAGRAPH_BREAK:
|
||||
// multirow does not allow paragraph breaks
|
||||
if (tabular.isMultiRow(cur.idx())) {
|
||||
status.setEnabled(false);
|
||||
return true;
|
||||
}
|
||||
// fall through
|
||||
case LFUN_NEWLINE_INSERT:
|
||||
if (tabular.isMultiRow(cur.idx())
|
||||
&& tabular.getPWidth(cur.idx()).zero()) {
|
||||
status.setEnabled(false);
|
||||
return true;
|
||||
}
|
||||
return cell(cur.idx())->getStatus(cur, cmd, status);
|
||||
|
||||
case LFUN_NEWPAGE_INSERT:
|
||||
|
@ -1455,12 +1455,17 @@ void TeXOnePar(Buffer const & buf,
|
||||
// Note from JMarc: we will re-add a \n explicitly in
|
||||
// TeXEnvironment, because it is needed in this case
|
||||
if (nextpar && !os.afterParbreak() && !last_was_separator) {
|
||||
Layout const & next_layout = nextpar->layout();
|
||||
if (!text.inset().getLayout().parbreakIgnored() && !merged_par)
|
||||
if (runparams.isNonLong)
|
||||
// This is to allow parbreak in multirow
|
||||
// It could also be used for other non-long
|
||||
// contexts
|
||||
os << "\\endgraf";
|
||||
else if (!text.inset().getLayout().parbreakIgnored() && !merged_par)
|
||||
// Make sure to start a new line
|
||||
os << breakln;
|
||||
// A newline '\n' is always output before a command,
|
||||
// so avoid doubling it.
|
||||
Layout const & next_layout = nextpar->layout();
|
||||
if (!next_layout.isCommand()) {
|
||||
// Here we now try to avoid spurious empty lines by
|
||||
// outputting a paragraph break only if: (case 1) the
|
||||
|
@ -59,7 +59,7 @@ enum {
|
||||
FLAG_END = 1 << 3, // next \\end ends the parsing process
|
||||
FLAG_BRACK_LAST = 1 << 4, // next closing bracket ends the parsing
|
||||
FLAG_TEXTMODE = 1 << 5, // we are in a box
|
||||
FLAG_ITEM = 1 << 6, // read a (possibly braced token)
|
||||
FLAG_ITEM = 1 << 6, // read a (possibly braced) token
|
||||
FLAG_LEAVE = 1 << 7, // leave the loop at the end
|
||||
FLAG_SIMPLE = 1 << 8, // next $ leaves the loop
|
||||
FLAG_EQUATION = 1 << 9, // next \] leaves the loop
|
||||
|
@ -934,6 +934,67 @@ void handle_hline_below(RowInfo & ri, vector<CellInfo> & ci)
|
||||
}
|
||||
|
||||
|
||||
void parse_cell_content(ostringstream & os2, Parser & parse, Context & newcontext,
|
||||
vector< vector<CellInfo> > cellinfo, vector<ColInfo> colinfo,
|
||||
size_t const row, size_t const col)
|
||||
{
|
||||
bool turn = false;
|
||||
int rotate = 0;
|
||||
bool varwidth = false;
|
||||
if (parse.next_token().cs() == "begin") {
|
||||
parse.pushPosition();
|
||||
parse.get_token();
|
||||
string const env = parse.getArg('{', '}');
|
||||
if (env == "sideways" || env == "turn") {
|
||||
string angle = "90";
|
||||
if (env == "turn") {
|
||||
turn = true;
|
||||
angle = parse.getArg('{', '}');
|
||||
}
|
||||
active_environments.push_back(env);
|
||||
parse.ertEnvironment(env);
|
||||
active_environments.pop_back();
|
||||
parse.skip_spaces();
|
||||
if (!parse.good() && support::isStrInt(angle))
|
||||
rotate = convert<int>(angle);
|
||||
} else if (env == "cellvarwidth") {
|
||||
active_environments.push_back(env);
|
||||
parse.ertEnvironment(env);
|
||||
active_environments.pop_back();
|
||||
parse.skip_spaces();
|
||||
varwidth = true;
|
||||
}
|
||||
parse.popPosition();
|
||||
}
|
||||
if (rotate != 0) {
|
||||
cellinfo[row][col].rotate = rotate;
|
||||
parse.get_token();
|
||||
active_environments.push_back(parse.getArg('{', '}'));
|
||||
if (turn)
|
||||
parse.getArg('{', '}');
|
||||
parse_text_in_inset(parse, os2, FLAG_END, false, newcontext);
|
||||
active_environments.pop_back();
|
||||
preamble.registerAutomaticallyLoadedPackage("rotating");
|
||||
} else if (varwidth) {
|
||||
parse.get_token();
|
||||
active_environments.push_back(parse.getArg('{', '}'));
|
||||
// valign arg
|
||||
if (parse.hasOpt())
|
||||
cellinfo[row][col].valign = parse.getArg('[', ']')[1];
|
||||
newcontext.in_table_cell = true;
|
||||
parse_text_in_inset(parse, os2, FLAG_END, false, newcontext);
|
||||
if (cellinfo[row][col].multi == CELL_NORMAL)
|
||||
colinfo[col].align = newcontext.cell_align;
|
||||
else
|
||||
cellinfo[row][col].align = newcontext.cell_align;
|
||||
active_environments.pop_back();
|
||||
preamble.registerAutomaticallyLoadedPackage("varwidth");
|
||||
} else {
|
||||
parse_text_in_inset(parse, os2, FLAG_CELL, false, newcontext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
@ -1284,7 +1345,11 @@ void handle_tabular(Parser & p, ostream & os, string const & name,
|
||||
cellinfo[row][col].mrxnum = ncells - 1;
|
||||
|
||||
ostringstream os2;
|
||||
parse_text_in_inset(parse, os2, FLAG_ITEM, false, newcontext);
|
||||
parse.get_token();// skip {
|
||||
parse_cell_content(os2, parse, newcontext,
|
||||
cellinfo, colinfo,
|
||||
row, col);
|
||||
parse.get_token();// skip }
|
||||
if (!cellinfo[row][col].content.empty()) {
|
||||
// This may or may not work in LaTeX,
|
||||
// but it does not work in LyX.
|
||||
@ -1321,7 +1386,11 @@ void handle_tabular(Parser & p, ostream & os, string const & name,
|
||||
cellinfo[row][col].leftlines = ci.leftlines;
|
||||
cellinfo[row][col].rightlines = ci.rightlines;
|
||||
ostringstream os2;
|
||||
parse_text_in_inset(parse, os2, FLAG_ITEM, false, newcontext);
|
||||
parse.get_token();// skip {
|
||||
parse_cell_content(os2, parse, newcontext,
|
||||
cellinfo, colinfo,
|
||||
row, col);
|
||||
parse.get_token();// skip }
|
||||
if (!cellinfo[row][col].content.empty()) {
|
||||
// This may or may not work in LaTeX,
|
||||
// but it does not work in LyX.
|
||||
@ -1416,64 +1485,13 @@ void handle_tabular(Parser & p, ostream & os, string const & name,
|
||||
for (size_t c = 1; c < colinfo.size(); ++c)
|
||||
cellinfo[row][c].multi = CELL_PART_OF_MULTICOLUMN;
|
||||
} else {
|
||||
bool turn = false;
|
||||
int rotate = 0;
|
||||
bool varwidth = false;
|
||||
if (parse.next_token().cs() == "begin") {
|
||||
parse.pushPosition();
|
||||
parse.get_token();
|
||||
string const env = parse.getArg('{', '}');
|
||||
if (env == "sideways" || env == "turn") {
|
||||
string angle = "90";
|
||||
if (env == "turn") {
|
||||
turn = true;
|
||||
angle = parse.getArg('{', '}');
|
||||
}
|
||||
active_environments.push_back(env);
|
||||
parse.ertEnvironment(env);
|
||||
active_environments.pop_back();
|
||||
parse.skip_spaces();
|
||||
if (!parse.good() && support::isStrInt(angle))
|
||||
rotate = convert<int>(angle);
|
||||
} else if (env == "cellvarwidth") {
|
||||
active_environments.push_back(env);
|
||||
parse.ertEnvironment(env);
|
||||
active_environments.pop_back();
|
||||
parse.skip_spaces();
|
||||
varwidth = true;
|
||||
}
|
||||
parse.popPosition();
|
||||
}
|
||||
ostringstream os2;
|
||||
parse_cell_content(os2, parse, newcontext,
|
||||
cellinfo, colinfo,
|
||||
row, col);
|
||||
cellinfo[row][col].leftlines = colinfo[col].leftlines;
|
||||
cellinfo[row][col].rightlines = colinfo[col].rightlines;
|
||||
cellinfo[row][col].align = colinfo[col].align;
|
||||
ostringstream os2;
|
||||
if (rotate != 0) {
|
||||
cellinfo[row][col].rotate = rotate;
|
||||
parse.get_token();
|
||||
active_environments.push_back(parse.getArg('{', '}'));
|
||||
if (turn)
|
||||
parse.getArg('{', '}');
|
||||
parse_text_in_inset(parse, os2, FLAG_END, false, newcontext);
|
||||
active_environments.pop_back();
|
||||
preamble.registerAutomaticallyLoadedPackage("rotating");
|
||||
} else if (varwidth) {
|
||||
parse.get_token();
|
||||
active_environments.push_back(parse.getArg('{', '}'));
|
||||
// valign arg
|
||||
if (parse.hasOpt())
|
||||
cellinfo[row][col].valign = parse.getArg('[', ']')[1];
|
||||
newcontext.in_table_cell = true;
|
||||
parse_text_in_inset(parse, os2, FLAG_END, false, newcontext);
|
||||
if (cellinfo[row][col].multi == CELL_NORMAL)
|
||||
colinfo[col].align = newcontext.cell_align;
|
||||
else
|
||||
cellinfo[row][col].align = newcontext.cell_align;
|
||||
active_environments.pop_back();
|
||||
preamble.registerAutomaticallyLoadedPackage("varwidth");
|
||||
} else {
|
||||
parse_text_in_inset(parse, os2, FLAG_CELL, false, newcontext);
|
||||
}
|
||||
cellinfo[row][col].content += os2.str();
|
||||
}
|
||||
}
|
||||
|
@ -5105,6 +5105,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t.cs() == "endgraf" && context.in_table_cell) {
|
||||
context.new_paragraph(os);
|
||||
context.check_layout(os);
|
||||
skip_spaces_braces(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t.cs() == "input" || t.cs() == "include"
|
||||
|| t.cs() == "verbatiminput"
|
||||
|| t.cs() == "lstinputlisting"
|
||||
|
Loading…
Reference in New Issue
Block a user