namespace {
int const WIDTH_OF_LINE = 5;
+int const default_line_space = 10;
+
template <class T>
string const write_attribute(string const & name, T const & t)
}
+bool getTokenValue(string const & str, char const * token, LyXLength & len, bool & flag)
+{
+ len = LyXLength();
+ flag = false;
+ string tmp;
+ if (!getTokenValue(str, token, tmp))
+ return false;
+ if (tmp == "default") {
+ flag = true;
+ return true;
+ }
+ return isValidLength(tmp, &len);
+}
+
+
void l_getline(istream & is, string & str)
{
str.erase();
descent_of_row(0),
top_line(true),
bottom_line(false),
+ top_space_default(false),
+ bottom_space_default(false),
+ interline_space_default(false),
endhead(false),
endfirsthead(false),
endfoot(false),
column_info.back().right_line = true;
is_long_tabular = false;
rotate = false;
+ use_booktabs = false;
}
}
-// returns 1 if there is a topline, returns 0 if not
bool LyXTabular::topLine(idx_type const cell, bool const onlycolumn) const
{
- if (!onlycolumn && isMultiColumn(cell))
+ if (!onlycolumn && isMultiColumn(cell) &&
+ !(use_booktabs && row_of_cell(cell) == 0))
return cellinfo_of_cell(cell).top_line;
return row_info[row_of_cell(cell)].top_line;
}
bool LyXTabular::bottomLine(idx_type const cell, bool onlycolumn) const
{
- if (!onlycolumn && isMultiColumn(cell))
+ if (!onlycolumn && isMultiColumn(cell) &&
+ !(use_booktabs && isLastRow(cell)))
return cellinfo_of_cell(cell).bottom_line;
return row_info[row_of_cell(cell)].bottom_line;
}
bool LyXTabular::leftLine(idx_type cell, bool onlycolumn) const
{
+ if (use_booktabs)
+ return false;
if (!onlycolumn && isMultiColumn(cell) &&
(isFirstCellInRow(cell) || isMultiColumn(cell-1)))
{
bool LyXTabular::rightLine(idx_type cell, bool onlycolumn) const
{
+ if (use_booktabs)
+ return false;
if (!onlycolumn && isMultiColumn(cell) &&
(isLastCellInRow(cell) || isMultiColumn(cell + 1)))
{
top = row_info[row].top_line;
}
}
+ int const interline_space = row_info[row - 1].interline_space_default ?
+ default_line_space :
+ row_info[row - 1].interline_space.inPixels(width_of_tabular);
if (top && bottom)
- return WIDTH_OF_LINE;
- return 0;
+ return interline_space + WIDTH_OF_LINE;
+ return interline_space;
}
// global longtable options
os << "<features"
<< write_attribute("rotate", rotate)
+ << write_attribute("booktabs", use_booktabs)
<< write_attribute("islongtable", is_long_tabular)
<< write_attribute("firstHeadTopDL", endfirsthead.topDL)
<< write_attribute("firstHeadBottomDL", endfirsthead.bottomDL)
for (row_type i = 0; i < rows_; ++i) {
os << "<row"
<< write_attribute("topline", row_info[i].top_line)
- << write_attribute("bottomline", row_info[i].bottom_line)
- << write_attribute("endhead", row_info[i].endhead)
+ << write_attribute("bottomline", row_info[i].bottom_line);
+ static const string def("default");
+ if (row_info[i].top_space_default)
+ os << write_attribute("topspace", def);
+ else
+ os << write_attribute("topspace", row_info[i].top_space);
+ if (row_info[i].bottom_space_default)
+ os << write_attribute("bottomspace", def);
+ else
+ os << write_attribute("bottomspace", row_info[i].bottom_space);
+ if (row_info[i].interline_space_default)
+ os << write_attribute("interlinespace", def);
+ else
+ os << write_attribute("interlinespace", row_info[i].interline_space);
+ os << write_attribute("endhead", row_info[i].endhead)
<< write_attribute("endfirsthead", row_info[i].endfirsthead)
<< write_attribute("endfoot", row_info[i].endfoot)
<< write_attribute("endlastfoot", row_info[i].endlastfoot)
return;
}
getTokenValue(line, "rotate", rotate);
+ getTokenValue(line, "booktabs", use_booktabs);
getTokenValue(line, "islongtable", is_long_tabular);
getTokenValue(line, "firstHeadTopDL", endfirsthead.topDL);
getTokenValue(line, "firstHeadBottomDL", endfirsthead.bottomDL);
}
getTokenValue(line, "topline", row_info[i].top_line);
getTokenValue(line, "bottomline", row_info[i].bottom_line);
+ getTokenValue(line, "topspace", row_info[i].top_space,
+ row_info[i].top_space_default);
+ getTokenValue(line, "bottomspace", row_info[i].bottom_space,
+ row_info[i].bottom_space_default);
+ getTokenValue(line, "interlinespace", row_info[i].interline_space,
+ row_info[i].interline_space_default);
getTokenValue(line, "endfirsthead", row_info[i].endfirsthead);
getTokenValue(line, "endhead", row_info[i].endhead);
getTokenValue(line, "endfoot", row_info[i].endfoot);
}
+void LyXTabular::setBookTabs(bool what)
+{
+ use_booktabs = what;
+}
+
+
+bool LyXTabular::useBookTabs() const
+{
+ return use_booktabs;
+}
+
+
void LyXTabular::setLongTabular(bool what)
{
is_long_tabular = what;
if (topLine(i))
++tmp;
}
- if (tmp == n - fcell) {
- os << "\\hline ";
+ if (use_booktabs && row == 0) {
+ os << "\\toprule ";
+ } else if (tmp == n - fcell) {
+ os << (use_booktabs ? "\\midrule " : "\\hline ");
} else if (tmp) {
for (idx_type i = fcell; i < n; ++i) {
if (topLine(i)) {
- os << "\\cline{"
+ os << (use_booktabs ? "\\cmidrule{" : "\\cline{")
<< column_of_cell(i) + 1
<< '-'
<< right_column_of_cell(i) + 1
if (bottomLine(i))
++tmp;
}
- if (tmp == n - fcell) {
- os << "\\hline";
+ if (use_booktabs && row == rows_ - 1) {
+ os << "\\bottomrule";
+ } else if (tmp == n - fcell) {
+ os << (use_booktabs ? "\\midrule" : "\\hline");
} else if (tmp) {
for (idx_type i = fcell; i < n; ++i) {
if (bottomLine(i)) {
- os << "\\cline{"
+ os << (use_booktabs ? "\\cmidrule{" : "\\cline{")
<< column_of_cell(i) + 1
<< '-'
<< right_column_of_cell(i) + 1
OutputParams const & runparams) const
{
idx_type cell = getCellNumber(i, 0);
-
int ret = TeXTopHLine(os, i);
+ if (row_info[i].top_space_default) {
+ if (use_booktabs)
+ os << "\\addlinespace\n";
+ else
+ os << "\\noalign{\\vskip\\doublerulesep}\n";
+ } else if(!row_info[i].top_space.zero()) {
+ if (use_booktabs)
+ os << "\\addlinespace["
+ << row_info[i].top_space.asLatexString() << "]\n";
+ else {
+ os << "\\noalign{\\vskip"
+ << row_info[i].top_space.asLatexString() << "}\n";
+ }
+ ++ret;
+ }
+
for (col_type j = 0; j < columns_; ++j) {
if (isPartOfMultiColumn(i, j))
continue;
}
++cell;
}
- os << "\\tabularnewline\n";
+ os << "\\tabularnewline";
+ if (row_info[i].bottom_space_default) {
+ if (use_booktabs)
+ os << "\\addlinespace";
+ else
+ os << "[\\doublerulesep]";
+ } else if (!row_info[i].bottom_space.zero()) {
+ if (use_booktabs)
+ os << "\\addlinespace";
+ os << '[' << row_info[i].bottom_space.asLatexString() << ']';
+ }
+ os << '\n';
++ret;
ret += TeXBottomHLine(os, i);
+ if (row_info[i].interline_space_default) {
+ if (use_booktabs)
+ os << "\\addlinespace\n";
+ else
+ os << "\\noalign{\\vskip\\doublerulesep}\n";
+ } else if (!row_info[i].interline_space.zero()) {
+ if (use_booktabs)
+ os << "\\addlinespace["
+ << row_info[i].interline_space.asLatexString()
+ << "]\n";
+ else
+ os << "\\noalign{\\vskip"
+ << row_info[i].interline_space.asLatexString()
+ << "}\n";
+ ++ret;
+ }
return ret;
}
if (!column_info[i].align_special.empty()) {
os << column_info[i].align_special;
} else {
- if (column_info[i].left_line)
+ if (!use_booktabs && column_info[i].left_line)
os << '|';
if (!column_info[i].p_width.zero()) {
switch (column_info[i].alignment) {
break;
}
}
- if (column_info[i].right_line)
+ if (!use_booktabs && column_info[i].right_line)
os << '|';
}
}
}
-int LyXTabular::linuxdoc(Buffer const & buf, ostream & os,
- const OutputParams & runparams) const
-{
- os << "<tabular ca=\"";
- for (col_type i = 0; i < columns_; ++i) {
- switch (column_info[i].alignment) {
- case LYX_ALIGN_LEFT:
- os << 'l';
- break;
- case LYX_ALIGN_RIGHT:
- os << 'r';
- break;
- default:
- os << 'c';
- break;
- }
- }
- os << "\">\n";
- idx_type cell = 0;
- int ret = 0;
- for (row_type i = 0; i < rows_; ++i) {
- for (col_type j = 0; j < columns_; ++j) {
- if (isPartOfMultiColumn(i, j))
- continue;
- shared_ptr<InsetText> inset = getCellInset(cell);
-
- ret += inset->linuxdoc(buf, os, runparams);
-
- if (isLastCellInRow(cell)) {
- os << "@\n";
- ++ret;
- } else {
- os << "|";
- }
- ++cell;
- }
- }
- os << "</tabular>\n";
- return ret;
-}
-
-
int LyXTabular::docbookRow(Buffer const & buf, ostream & os, row_type row,
OutputParams const & runparams) const
{
void LyXTabular::validate(LaTeXFeatures & features) const
{
features.require("NeedTabularnewline");
+ if (useBookTabs())
+ features.require("booktabs");
if (isLongTabular())
features.require("longtable");
if (needRotating())