From 9e387aea07846a96da2236f42b1b0ca83a5efbcf Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sun, 24 Jun 2018 18:13:03 +0200 Subject: [PATCH] tex2lyx: Add support for multirow Fixes: #11164 (cherry picked from commit c33506555f5f7193b0cbce6c9878d62a18f37cc9) --- src/tex2lyx/Preamble.cpp | 2 +- src/tex2lyx/TODO.txt | 2 - src/tex2lyx/table.cpp | 105 +++++++++++++++++++++++++++++++++++---- status.23x | 2 + 4 files changed, 98 insertions(+), 13 deletions(-) diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp index 5c2c349fb6..436c961545 100644 --- a/src/tex2lyx/Preamble.cpp +++ b/src/tex2lyx/Preamble.cpp @@ -205,7 +205,7 @@ const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian", const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb", "amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color", "float", "fontspec", "framed", "graphicx", "hhline", "ifthen", "longtable", -"makeidx", "minted", "nomencl", "pdfpages", "prettyref", "refstyle", +"makeidx", "minted", "multirow", "nomencl", "pdfpages", "prettyref", "refstyle", "rotating", "rotfloat", "splitidx", "setspace", "subscript", "textcomp", "tipa", "tipx", "tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xunicode", 0}; diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt index be5d770021..60ba373416 100644 --- a/src/tex2lyx/TODO.txt +++ b/src/tex2lyx/TODO.txt @@ -39,14 +39,12 @@ Format LaTeX feature LyX feature 363 horizontal longtable alignment InsetTabular 364 branch file name suffix \filename_suffix 371 automatic mhchem loading \use_mhchem -377 multirow.sty InsetTabular 378 revision info InsetInfo 380 ? InsetPreview 386 LyX version InsetInfo 390 forward/reverse search \forward_search, \forward_macro 391 decimal alignment in tables InsetTabular 399 automatic mathdots loading \use_mathdots -407 vertical offset for multirows InsetTabular 411 support for polyglossia \language_package (the cases of no package, of babel and of custom package is supported) 415 automatic undertilde loading \use_package undertilde 443 unicode-math.sty InsetMath* diff --git a/src/tex2lyx/table.cpp b/src/tex2lyx/table.cpp index e8b6a4ad7b..a3cabfd20c 100644 --- a/src/tex2lyx/table.cpp +++ b/src/tex2lyx/table.cpp @@ -101,14 +101,18 @@ public: /// the numeric values are part of the file format! -enum Multicolumn { +enum Multi { /// A normal cell CELL_NORMAL = 0, /// A multicolumn cell. The number of columns is 1 + number /// of CELL_PART_OF_MULTICOLUMN cells that follow directly - CELL_BEGIN_OF_MULTICOLUMN = 1, + CELL_BEGIN_OF_MULTICOLUMN, /// This is a dummy cell (part of a multicolumn cell) - CELL_PART_OF_MULTICOLUMN = 2 + CELL_PART_OF_MULTICOLUMN, + /// + CELL_BEGIN_OF_MULTIROW, + /// + CELL_PART_OF_MULTIROW }; @@ -116,11 +120,11 @@ class CellInfo { public: CellInfo() : multi(CELL_NORMAL), align('n'), valign('n'), leftlines(0), rightlines(0), topline(false), - bottomline(false), rotate(0) {} + bottomline(false), rotate(0), mrxnum(0) {} /// cell content string content; /// multicolumn flag - Multicolumn multi; + Multi multi; /// cell alignment char align; /// vertical cell alignment @@ -139,6 +143,10 @@ public: string width; /// special formatting for multicolumn cells string special; + /// multirow offset + string mroffset; + /// number of further multirows + int mrxnum; }; @@ -395,6 +403,8 @@ void handle_colalign(Parser & p, vector & colinfo, break; } case '*': { + if (p.next_token().character() != '{') + continue; // *{n}{arg} means 'n' columns of type 'arg' string const num = p.verbatim_item(); string const arg = p.verbatim_item(); @@ -1123,7 +1133,57 @@ void handle_tabular(Parser & p, ostream & os, string const & name, Parser p(cells[cell]); p.skip_spaces(); //cells[cell] << "'\n"; - if (p.next_token().cs() == "multicolumn") { + if (p.next_token().cs() == "multirow") { + // We do not support the vpos arg yet. + if (p.hasOpt()) { + string const vpos = p.getArg('[', ']'); + p.skip_spaces(true); + cerr << "Ignoring multirow's vpos arg '" + << vpos << "'!" << endl; + } + // how many cells? + p.get_token(); + size_t const ncells = + convert(p.verbatim_item()); + // We do not support the bigstrut arg yet. + if (p.hasOpt()) { + string const bs = p.getArg('[', ']'); + p.skip_spaces(true); + cerr << "Ignoring multirow's bigstrut arg '" + << bs << "'!" << endl; + } + // the width argument + string const width = p.getArg('{', '}'); + // the vmove arg + string vmove; + if (p.hasOpt()) { + vmove = p.getArg('[', ']'); + p.skip_spaces(true); + } + + if (width != "*") + colinfo[col].width = width; + if (!vmove.empty()) + cellinfo[row][col].mroffset = vmove; + cellinfo[row][col].multi = CELL_BEGIN_OF_MULTIROW; + cellinfo[row][col].leftlines = colinfo[col].leftlines; + cellinfo[row][col].rightlines = colinfo[col].rightlines; + cellinfo[row][col].mrxnum = ncells - 1; + + ostringstream os2; + parse_text_in_inset(p, os2, FLAG_ITEM, false, context); + if (!cellinfo[row][col].content.empty()) { + // This may or may not work in LaTeX, + // but it does not work in LyX. + // FIXME: Handle it correctly! + cerr << "Moving cell content '" + << cells[cell] + << "' into a multirow cell. " + "This will probably not work." + << endl; + } + cellinfo[row][col].content += os2.str(); + } else if (p.next_token().cs() == "multicolumn") { // how many cells? p.get_token(); size_t const ncells = @@ -1272,13 +1332,23 @@ void handle_tabular(Parser & p, ostream & os, string const & name, // and cellinfo. // Unfortunately LyX has some limitations that we need to work around. - // Convert cells with special content to multicolumn cells - // (LyX ignores the special field for non-multicolumn cells). + // Some post work for (size_t row = 0; row < rowinfo.size(); ++row) { for (size_t col = 0; col < cellinfo[row].size(); ++col) { + // Convert cells with special content to multicolumn cells + // (LyX ignores the special field for non-multicolumn cells). if (cellinfo[row][col].multi == CELL_NORMAL && !cellinfo[row][col].special.empty()) cellinfo[row][col].multi = CELL_BEGIN_OF_MULTICOLUMN; + // Add multirow dummy cells + if (row > 1 && (cellinfo[row - 1][col].multi == CELL_PART_OF_MULTIROW + || cellinfo[row - 1][col].multi == CELL_BEGIN_OF_MULTIROW) + && cellinfo[row - 1][col].mrxnum > 0) { + // add dummy cells for multirow + cellinfo[row][col].multi = CELL_PART_OF_MULTIROW; + cellinfo[row][col].align = 'c'; + cellinfo[row][col].mrxnum = cellinfo[row - 1][col].mrxnum - 1; + } } } @@ -1308,6 +1378,16 @@ void handle_tabular(Parser & p, ostream & os, string const & name, cellinfo[row][col].rightlines = colinfo[col].rightlines; if (col > 0 && cellinfo[row][col-1].multi == CELL_NORMAL) cellinfo[row][col].leftlines = colinfo[col].leftlines; + } else if (cellinfo[row][col].multi == CELL_BEGIN_OF_MULTIROW) { + size_t s = row + 1; + while (s < rowinfo.size() && + cellinfo[s][col].multi == CELL_PART_OF_MULTIROW) + s++; + if (s < cellinfo[row].size() && + cellinfo[s][col].multi != CELL_BEGIN_OF_MULTIROW) + cellinfo[row][col].bottomline = rowinfo[row].bottomline; + if (row > 0 && cellinfo[row - 1][col].multi == CELL_NORMAL) + cellinfo[row][col].topline = rowinfo[row].topline; } } } @@ -1373,8 +1453,12 @@ void handle_tabular(Parser & p, ostream & os, string const & name, for (size_t col = 0; col < colinfo.size(); ++col) { CellInfo const & cell = cellinfo[row][col]; os << " 0) << write_attribute("rightline", cell.rightlines > 0) - << write_attribute("rotate", cell.rotate); + << write_attribute("rotate", cell.rotate) + << write_attribute("mroffset", cell.mroffset); //cerr << "\nrow: " << row << " col: " << col; //if (cell.topline) // cerr << " topline=\"true\""; diff --git a/status.23x b/status.23x index 6a043fe363..4844c19a74 100644 --- a/status.23x +++ b/status.23x @@ -29,6 +29,8 @@ What's new * TEX2LYX IMPROVEMENTS +- Add support for multirow (bug 11164). + - Improve import of titling commands other than \maketitle (bug 6461).