From f077658248c6eddb7f6d05197d7b4dd52708e956 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Sun, 13 Nov 2011 19:49:50 +0000 Subject: [PATCH] Fix bug #4553: booktabs for tex2lyx git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40189 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/tex2lyx/Preamble.cpp | 4 +- src/tex2lyx/TODO.txt | 1 - src/tex2lyx/table.cpp | 120 +++++++++++++++++++++++++++++++-------- 3 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp index 6261fa54a2..4ebfbc1c1a 100644 --- a/src/tex2lyx/Preamble.cpp +++ b/src/tex2lyx/Preamble.cpp @@ -730,7 +730,9 @@ void Preamble::handle_package(Parser &p, string const & name, else if (name == "url") ; // ignore this - else if (name == "color" || name == "subscript" || name == "ulem") { + else if (name == "booktabs" || name == "color" || + name == "longtable" || name == "subscript" || + name == "ulem") { if (!in_lyx_preamble) h_preamble << package_beg_sep << name << package_mid_sep << "\\usepackage{" diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt index 2e53ac9ad2..f76c51f123 100644 --- a/src/tex2lyx/TODO.txt +++ b/src/tex2lyx/TODO.txt @@ -17,7 +17,6 @@ Format LaTeX feature LyX feature 226 transformations InsetExternal 228 draft InsetExternal 232 bibtopic InsetBibTeX -248 booktabs.sty InsetTabular 254 esint.sty \use_esint 266 armenian \language, \lang 267 XeTeX utf8 encoding diff --git a/src/tex2lyx/table.cpp b/src/tex2lyx/table.cpp index d23da08a73..45d910ac7f 100644 --- a/src/tex2lyx/table.cpp +++ b/src/tex2lyx/table.cpp @@ -16,6 +16,8 @@ #include "tex2lyx.h" +#include "Preamble.h" + #include "support/lassert.h" #include "support/convert.h" #include "support/lstrings.h" @@ -77,6 +79,12 @@ public: bool topline; /// horizontal line below bool bottomline; + /// Extra space between the top line and this row + string top_space; + /// Extra space between this row and the bottom line + string bottom_space; + /// Extra space between the bottom line and the next top line + string interline_space; /// These are for longtabulars only /// row type (head, foot, firsthead etc.) LTRowType type; @@ -471,12 +479,35 @@ bool parse_hlines(Parser & p, Token const & t, string & hlines, { LASSERT(t.cat() == catEscape, return false); - if (t.cs() == "hline") - hlines += "\\hline"; + if (t.cs() == "hline" || t.cs() == "toprule" || t.cs() == "midrule" || + t.cs() == "bottomrule") + hlines += '\\' + t.cs(); else if (t.cs() == "cline") 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) + return false; + hlines += "\\cmidrule{" + p.verbatim_item() + '}'; + } + + else if (t.cs() == "addlinespace") { + p.pushPosition(); + p.skip_spaces(true); + bool const hasArgument(p.getFullArg('{', '}').first); + p.popPosition(); + if (hasArgument) + hlines += "\\addlinespace{" + p.verbatim_item() + '}'; + else + hlines += "\\addlinespace"; + } + else if (is_long_tabular && t.cs() == "newpage") hlines += "\\newpage"; @@ -628,14 +659,20 @@ void parse_table(Parser & p, ostream & os, bool is_long_tabular, pos = IN_COLUMNS; break; case IN_HLINES_END: - // Oops, there is still cell content after hline - // stuff. This does not work in LaTeX, so we ignore - // the hlines. - cerr << "Ignoring '" << hlines << "' in a cell" - << endl; + // Oops, there is still cell content or unsupported + // booktabs commands after hline stuff. The latter are + // moved to the cell, and the first does not work in + // LaTeX, so we ignore the hlines. os << comments; - hlines.erase(); comments.erase(); + if (support::contains(hlines, "\\hline") || + support::contains(hlines, "\\cline") || + support::contains(hlines, "\\newpage")) + cerr << "Ignoring '" << hlines + << "' in a cell" << endl; + else + os << hlines; + hlines.erase(); pos = IN_COLUMNS; break; case IN_COLUMNS: @@ -774,6 +811,7 @@ void handle_tabular(Parser & p, ostream & os, string const & name, string const & tabularwidth, Context & context) { bool const is_long_tabular(name == "longtable"); + bool booktabs = false; string tabularvalignment("middle"); string posopts = p.getOpt(); if (!posopts.empty()) { @@ -841,13 +879,18 @@ void handle_tabular(Parser & p, ostream & os, string const & name, while (p1.good()) { Token t = p1.get_token(); //cerr << "read token: " << t << "\n"; - if (t.cs() == "hline") { + if (t.cs() == "hline" || t.cs() == "toprule" || + t.cs() == "midrule" || + t.cs() == "bottomrule") { + if (t.cs() != "hline") + booktabs = true; if (i == 0) { if (rowinfo[row].topline) { if (row > 0) // extra bottomline above handle_hline_below(rowinfo[row - 1], cellinfo[row - 1]); else - cerr << "dropping extra hline\n"; + cerr << "dropping extra " + << t.cs() << '\n'; //cerr << "below row: " << row-1 << endl; } else { handle_hline_above(rowinfo[row], cellinfo[row]); @@ -857,37 +900,39 @@ void handle_tabular(Parser & p, ostream & os, string const & name, //cerr << "below row: " << row << endl; handle_hline_below(rowinfo[row], cellinfo[row]); } - } else if (t.cs() == "cline") { + } else if (t.cs() == "cline" || t.cs() == "cmidrule") { + if (t.cs() == "cmidrule") + booktabs = true; string arg = p1.verbatim_item(); - //cerr << "read cline arg: '" << arg << "'\n"; - vector t; - split(arg, t, '-'); - t.resize(2); - size_t from = convert(t[0]); + //cerr << "read " << t.cs() << " arg: '" << arg << "'\n"; + vector cols; + split(arg, cols, '-'); + cols.resize(2); + size_t from = convert(cols[0]); if (from == 0) cerr << "Could not parse " - "cline start column." + << t.cs() << " start column." << endl; else // 1 based index -> 0 based --from; if (from >= colinfo.size()) { - cerr << "cline starts at non " - "existing column " + cerr << t.cs() << " starts at " + "non existing column " << (from + 1) << endl; from = colinfo.size() - 1; } - size_t to = convert(t[1]); + size_t to = convert(cols[1]); if (to == 0) cerr << "Could not parse " - "cline end column." + << t.cs() << " end column." << endl; else // 1 based index -> 0 based --to; if (to >= colinfo.size()) { - cerr << "cline ends at non " - "existing column " + cerr << t.cs() << " ends at " + "non existing column " << (to + 1) << endl; to = colinfo.size() - 1; } @@ -901,6 +946,26 @@ void handle_tabular(Parser & p, ostream & os, string const & name, cellinfo[row][col].bottomline = true; } } + } else if (t.cs() == "addlinespace") { + booktabs = true; + string const opt = p.next_token().cat() == catBegin ? + p.verbatim_item() : string(); + if (i == 0) { + if (opt.empty()) + rowinfo[row].top_space = "default"; + else + rowinfo[row].top_space = translate_len(opt); + } else if (rowinfo[row].bottomline) { + if (opt.empty()) + rowinfo[row].bottom_space = "default"; + else + rowinfo[row].bottom_space = translate_len(opt); + } else { + if (opt.empty()) + rowinfo[row].interline_space = "default"; + else + rowinfo[row].interline_space = translate_len(opt); + } } else if (t.cs() == "endhead") { if (i > 0) rowinfo[row].type = LT_HEAD; @@ -1107,12 +1172,18 @@ void handle_tabular(Parser & p, ostream & os, string const & name, } } + if (booktabs) + preamble.registerAutomaticallyLoadedPackage("booktabs"); + if (is_long_tabular) + preamble.registerAutomaticallyLoadedPackage("longtable"); + //cerr << "// output what we have\n"; // output what we have os << "\n\n"; os << "