X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftex2lyx%2Ftable.cpp;h=98f3e03e3a7a37c87aad13758b3e677d901f032b;hb=51239977c5a7cfec9ede5894218883e8f09cb23f;hp=e8b6a4ad7b5808cf0aa08792af30202f3bdf8eb0;hpb=bcb002039b1a0e4893f18a032e02b6f6368924f9;p=lyx.git diff --git a/src/tex2lyx/table.cpp b/src/tex2lyx/table.cpp index e8b6a4ad7b..98f3e03e3a 100644 --- a/src/tex2lyx/table.cpp +++ b/src/tex2lyx/table.cpp @@ -37,7 +37,8 @@ namespace { class ColInfo { public: - ColInfo() : align('n'), valign('n'), rightlines(0), leftlines(0) {} + ColInfo() : align('n'), valign('n'), rightlines(0), leftlines(0), + decimal_point('\0') {} /// column alignment char align; /// vertical alignment @@ -50,6 +51,8 @@ public: int rightlines; /// number of lines on the left int leftlines; + /// decimal separator + char decimal_point; }; @@ -101,14 +104,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 +123,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 +146,10 @@ public: string width; /// special formatting for multicolumn cells string special; + /// multirow offset + string mroffset; + /// number of further multirows + int mrxnum; }; @@ -169,6 +180,8 @@ inline char const * verbose_align(char c) return "right"; case 'l': return "left"; + case 'd': + return "decimal"; default: return "none"; } @@ -256,6 +269,17 @@ void ci2special(ColInfo & ci) // this case. return; + if (ci.decimal_point != '\0') { + // we only support decimal point natively + // with 'l' alignment in or 'n' alignment + // with width in second row + if (ci.align != 'l' && ci.align != 'n') { + ci.decimal_point = '\0'; + return; + } else + ci.special.clear(); + } + if (!ci.width.empty()) { switch (ci.align) { case 'l': @@ -330,8 +354,17 @@ void handle_colalign(Parser & p, vector & colinfo, case 'r': // new column, horizontal aligned next.align = t.character(); - if (!next.special.empty()) + if (!next.special.empty()) { ci2special(next); + // handle decimal separator + if (next.decimal_point != '\0') { + if (!colinfo.empty() && colinfo.back().align == 'r') { + colinfo.back().align = 'd'; + colinfo.back().decimal_point = next.decimal_point; + } else + next.decimal_point = '\0'; + } + } colinfo.push_back(next); next = ColInfo(); break; @@ -341,8 +374,17 @@ void handle_colalign(Parser & p, vector & colinfo, // new column, vertical aligned box next.valign = t.character(); next.width = p.verbatim_item(); - if (!next.special.empty()) + if (!next.special.empty()) { ci2special(next); + // handle decimal separator + if (next.decimal_point != '\0') { + if (!colinfo.empty() && colinfo.back().align == 'r') { + colinfo.back().align = 'd'; + colinfo.back().decimal_point = next.decimal_point; + } else + next.decimal_point = '\0'; + } + } colinfo.push_back(next); next = ColInfo(); break; @@ -395,6 +437,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(); @@ -416,11 +460,16 @@ void handle_colalign(Parser & p, vector & colinfo, } case '@': // text instead of the column spacing - case '!': + case '!': { // text in addition to the column spacing + string const arg = p.verbatim_item(); next.special += t.character(); - next.special += '{' + p.verbatim_item() + '}'; + next.special += '{' + arg + '}'; + string const sarg = arg.size() > 2 ? arg.substr(0, arg.size() - 1) : string(); + if (t.character() == '@' && sarg == "\\extracolsep{0pt}") + next.decimal_point = arg.back(); break; + } default: { // try user defined column types // unknown column types (nargs == -1) are @@ -837,7 +886,8 @@ void handle_hline_below(RowInfo & ri, vector & ci) void handle_tabular(Parser & p, ostream & os, string const & name, - string const & tabularwidth, Context & context) + string const & tabularwidth, string const & halign, + Context & context) { bool const is_long_tabular(name == "longtable"); bool booktabs = false; @@ -1120,10 +1170,65 @@ void handle_tabular(Parser & p, ostream & os, string const & name, << cells[cell] << "'." << endl; continue; } - Parser p(cells[cell]); + string cellcont = cells[cell]; + // For decimal cells, ass the content of the second one to the first one + // of a pair. + if (colinfo[col].decimal_point != '\0' && colinfo[col].align == 'd' && cell < cells.size() - 1) + cellcont += colinfo[col].decimal_point + cells[cell + 1]; + Parser p(cellcont); 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 +1377,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 +1423,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; } } } @@ -1320,8 +1445,13 @@ void handle_tabular(Parser & p, ostream & os, string const & name, //cerr << "// output what we have\n"; // output what we have string const rotate = "0"; + size_type cols = colinfo.size(); + for (size_t col = 0; col < colinfo.size(); ++col) { + if (colinfo[col].decimal_point != '\0' && colinfo[col].align != 'd') + --cols; + } os << "\n\n"; + << "\" columns=\"" << cols << "\">\n"; os << "\n"; for (size_t col = 0; col < colinfo.size(); ++col) { CellInfo const & cell = cellinfo[row][col]; + if (colinfo[col].decimal_point != '\0' && colinfo[col].align != 'd') + // These are the second columns in a salign pair. Skip. + continue; 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\"";