diff --git a/lib/lyx2lyx/lyx_2_4.py b/lib/lyx2lyx/lyx_2_4.py index 93500d0f75..ec6622cb6f 100644 --- a/lib/lyx2lyx/lyx_2_4.py +++ b/lib/lyx2lyx/lyx_2_4.py @@ -4154,11 +4154,11 @@ def revert_vcolumns2(document): endcell = find_token(document.body, "", 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, "", 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 diff --git a/src/OutputParams.h b/src/OutputParams.h index 5113e0a6d2..aeac6ddd6a 100644 --- a/src/OutputParams.h +++ b/src/OutputParams.h @@ -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. */ diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index bbc35757e9..244fbd4b38 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -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: diff --git a/src/output_latex.cpp b/src/output_latex.cpp index e98936de42..c5306d74ac 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -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 diff --git a/src/tex2lyx/Parser.h b/src/tex2lyx/Parser.h index d28036710e..a99b40f5dc 100644 --- a/src/tex2lyx/Parser.h +++ b/src/tex2lyx/Parser.h @@ -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 diff --git a/src/tex2lyx/table.cpp b/src/tex2lyx/table.cpp index e86eeb4620..8db0e23f9d 100644 --- a/src/tex2lyx/table.cpp +++ b/src/tex2lyx/table.cpp @@ -934,6 +934,67 @@ void handle_hline_below(RowInfo & ri, vector & ci) } +void parse_cell_content(ostringstream & os2, Parser & parse, Context & newcontext, + vector< vector > cellinfo, vector 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(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(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(); } } diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index 99bb93c1b5..76d11a7cb8 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -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"