X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftex2lyx%2Ftable.cpp;h=411fd5b6ab5534f929684b38458cc727856d2f6a;hb=a2b21e3cd4bbfd42e59161143eba6e7681aaa93f;hp=2007c1c5394dd25ff0236b56991638131e20e88e;hpb=650bb156d9e4ddb815bd9cf674a37f9f04f51c05;p=lyx.git diff --git a/src/tex2lyx/table.cpp b/src/tex2lyx/table.cpp index 2007c1c539..411fd5b6ab 100644 --- a/src/tex2lyx/table.cpp +++ b/src/tex2lyx/table.cpp @@ -16,6 +16,7 @@ #include "tex2lyx.h" +#include "Context.h" #include "Preamble.h" #include "support/lassert.h" @@ -37,7 +38,8 @@ namespace { class ColInfo { public: - ColInfo() : align('n'), valign('n'), rightlines(0), leftlines(0), varwidth(false) {} + ColInfo() : align('n'), valign('n'), rightlines(0), leftlines(0), + varwidth(false), decimal_point('\0'), vcolumn(false) {} /// column alignment char align; /// vertical alignment @@ -52,6 +54,10 @@ public: int leftlines; /// varwidth column bool varwidth; + /// decimal separator + char decimal_point; + /// V column type + bool vcolumn; }; @@ -122,7 +128,9 @@ class CellInfo { public: CellInfo() : multi(CELL_NORMAL), align('n'), valign('n'), leftlines(0), rightlines(0), topline(false), - bottomline(false), rotate(0), mrxnum(0) {} + bottomline(false), topline_ltrim(false), + topline_rtrim(false), bottomline_ltrim(false), + bottomline_rtrim(false), rotate(0), mrxnum(0) {} /// cell content string content; /// multicolumn flag @@ -139,6 +147,14 @@ public: bool topline; /// do we have a line below? bool bottomline; + /// Left trimming of top line + bool topline_ltrim; + /// Right trimming of top line + bool topline_rtrim; + /// Left trimming of bottom line + bool bottomline_ltrim; + /// Right trimming of top line + bool bottomline_rtrim; /// how is the cell rotated? int rotate; /// width for multicolumn cells @@ -179,6 +195,8 @@ inline char const * verbose_align(char c) return "right"; case 'l': return "left"; + case 'd': + return "decimal"; default: return "none"; } @@ -266,6 +284,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()) { string arraybackslash; if (ci.varwidth) @@ -281,7 +310,9 @@ void ci2special(ColInfo & ci) ci.special += ">{\\centering" + arraybackslash + "}"; break; } - if (ci.varwidth) + if (ci.vcolumn) + ci.special += 'V'; + else if (ci.varwidth) ci.special += 'X'; else if (ci.valign == 'n') ci.special += 'p'; @@ -345,8 +376,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; @@ -358,14 +398,38 @@ void handle_colalign(Parser & p, vector & colinfo, colinfo.push_back(next); next = ColInfo(); break; + case 'V': { + // V column type (varwidth package) + string const s = trimSpaceAndEol(p.verbatim_item()); + // V{\linewidth} is treated as a normal column + // (which allows for line breaks). The V type is + // automatically set by LyX in this case + if (s != "\\linewidth" || !next.special.empty()) { + next.vcolumn = true; + next.width = s; + ci2special(next); + } + colinfo.push_back(next); + next = ColInfo(); + break; + } case 'p': case 'b': case 'm': // 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; @@ -378,7 +442,7 @@ void handle_colalign(Parser & p, vector & colinfo, next.special += '|'; } else if (colinfo.back().special.empty()) ++colinfo.back().rightlines; - else if (next.special.empty()) + else if (next.special.empty() && p.next_token().cat() != catEnd) ++next.leftlines; else colinfo.back().special += '|'; @@ -441,11 +505,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 @@ -542,14 +611,21 @@ bool parse_hlines(Parser & p, Token const & t, string & hlines, hlines += "\\cline{" + p.verbatim_item() + '}'; else if (t.cs() == "cmidrule") { - // We cannot handle the \cmidrule(l){3-4} form p.pushPosition(); p.skip_spaces(true); - bool const hasParentheses(p.getFullArg('(', ')').first); - p.popPosition(); - if (hasParentheses) + // We do not support the optional height argument + if (p.hasOpt()) return false; - hlines += "\\cmidrule{" + p.verbatim_item() + '}'; + // We support the \cmidrule(l){3-4} form but + // not the trim length parameters (l{}r{}) + string const trim = p.getFullParentheseArg(); + string const range = p.verbatim_item(); + if (!trim.empty()) { + if (support::contains(trim, "{")) + return false; + hlines += "\\cmidrule" + trim + "{" + range + "}"; + } else + hlines += "\\cmidrule{" + range + '}'; } else if (t.cs() == "addlinespace") { @@ -931,7 +1007,7 @@ void handle_tabular(Parser & p, ostream & os, string const & name, for (int i = 0; i <= 2; i += 2) { //cerr << " reading from line string '" << dummy[i] << "'\n"; - Parser p1(dummy[i]); + Parser p1(dummy[size_type(i)]); while (p1.good()) { Token t = p1.get_token(); //cerr << "read token: " << t << "\n"; @@ -957,10 +1033,13 @@ void handle_tabular(Parser & p, ostream & os, string const & name, handle_hline_below(rowinfo[row], cellinfo[row]); } } else if (t.cs() == "cline" || t.cs() == "cmidrule") { - if (t.cs() == "cmidrule") + string trim; + if (t.cs() == "cmidrule") { booktabs = true; + trim = p1.getFullParentheseArg(); + } string arg = p1.verbatim_item(); - //cerr << "read " << t.cs() << " arg: '" << arg << "'\n"; + //cerr << "read " << t.cs() << " arg: '" << arg << "', trim: '" << trim << "'\n"; vector cols; split(arg, cols, '-'); cols.resize(2); @@ -997,9 +1076,25 @@ void handle_tabular(Parser & p, ostream & os, string const & name, if (i == 0) { rowinfo[row].topline = true; cellinfo[row][col].topline = true; + if (support::contains(trim, 'l') && col == from) { + //rowinfo[row].topline_ltrim = true; + cellinfo[row][col].topline_ltrim = true; + } + else if (support::contains(trim, 'r') && col == to) { + //rowinfo[row].topline_rtrim = true; + cellinfo[row][col].topline_rtrim = true; + } } else { rowinfo[row].bottomline = true; cellinfo[row][col].bottomline = true; + if (support::contains(trim, 'l') && col == from) { + //rowinfo[row].bottomline_ltrim = true; + cellinfo[row][col].bottomline_ltrim = true; + } + else if (support::contains(trim, 'r') && col == to) { + //rowinfo[row].bottomline_rtrim = true; + cellinfo[row][col].bottomline_rtrim = true; + } } } } else if (t.cs() == "addlinespace") { @@ -1142,7 +1237,12 @@ void handle_tabular(Parser & p, ostream & os, string const & name, << cells[cell] << "'." << endl; continue; } - Parser parse(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 parse(cellcont); parse.skip_spaces(); //cells[cell] << "'\n"; if (parse.next_token().cs() == "multirow") { @@ -1415,11 +1515,15 @@ 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)