diff --git a/autotests/export/xhtml/table_borders.lyx b/autotests/export/xhtml/table_borders.lyx
new file mode 100644
index 0000000000..7b59f5fe11
--- /dev/null
+++ b/autotests/export/xhtml/table_borders.lyx
@@ -0,0 +1,235 @@
+#LyX 2.4 created this file. For more info see https://www.lyx.org/
+\lyxformat 609
+\begin_document
+\begin_header
+\save_transient_properties true
+\origin unavailable
+\textclass scrbook
+\begin_preamble
+% Added by lyx2lyx
+\setlength{\parskip}{\medskipamount}
+\setlength{\parindent}{0pt}
+\end_preamble
+\use_default_options true
+\maintain_unincluded_children no
+\language ngerman
+\language_package default
+\inputencoding auto-legacy
+\fontencoding auto
+\font_roman "lmodern" "default"
+\font_sans "lmss" "default"
+\font_typewriter "lmtt" "default"
+\font_math "auto" "auto"
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_roman_osf false
+\font_sans_osf false
+\font_typewriter_osf false
+\font_sf_scale 100 100
+\font_tt_scale 100 100
+\use_microtype false
+\use_dash_ligatures true
+\graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
+\paperfontsize default
+\spacing single
+\use_hyperref false
+\papersize default
+\use_geometry false
+\use_package amsmath 1
+\use_package amssymb 1
+\use_package cancel 1
+\use_package esint 1
+\use_package mathdots 0
+\use_package mathtools 0
+\use_package mhchem 1
+\use_package stackrel 1
+\use_package stmaryrd 1
+\use_package undertilde 0
+\cite_engine basic
+\cite_engine_type default
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date false
+\justification true
+\use_refstyle 0
+\use_minted 0
+\use_lineno 0
+\branch Test
+\selected 1
+\filename_suffix 0
+\color #e9c792 #16386d
+\end_branch
+\index Stichwortverzeichnis
+\shortcut idx
+\color #008000
+\end_index
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\paragraph_indentation default
+\is_math_indent 0
+\math_numbering_side default
+\quotes_style english
+\dynamic_quotes 0
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tablestyle default
+\tracking_changes false
+\output_changes false
+\change_bars false
+\postpone_fragile_content false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict false
+\docbook_table_output 0
+\docbook_mathml_prefix 1
+\html_latex_start
+\html_latex_end
+\end_header
+
+\begin_body
+
+\begin_layout Title
+Check HTML export
+\end_layout
+
+\begin_layout Standard
+\begin_inset Tabular
+
+
+
+
+
+
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+a
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+d
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+s
+\end_layout
+
+\end_inset
+ |
+
+
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+
+
+\end_inset
+
+
+\end_layout
+
+\end_body
+\end_document
diff --git a/autotests/export/xhtml/table_borders.xhtml b/autotests/export/xhtml/table_borders.xhtml
new file mode 100644
index 0000000000..7e0602e22d
--- /dev/null
+++ b/autotests/export/xhtml/table_borders.xhtml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+Check HTML export
+
+
+
+Check HTML export
+
+1 here
+
+
+
+
+
+a
+ |
+d
+ |
+s
+ |
+
+
+
+ |
+
+ |
+
+ |
+
+
+
+ |
+
+ |
+
+ |
+
+
+
+ |
+
+ |
+
+ |
+
+
+
+
+
+
+
diff --git a/lib/layouts/stdinsets.inc b/lib/layouts/stdinsets.inc
index 32a0af3996..074b2748d5 100644
--- a/lib/layouts/stdinsets.inc
+++ b/lib/layouts/stdinsets.inc
@@ -776,7 +776,6 @@ InsetLayout Tabular
display: inline-block;
}
td {
- border: 1px solid black;
padding: 0.5ex;
}
EndHTMLStyle
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index 0832054bc3..478ecf1fa6 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -3654,6 +3654,77 @@ std::string Tabular::getHAlignAsXmlAttribute(idx_type cell, bool is_xhtml) const
}
}
+Tabular::XmlRowWiseBorders Tabular::computeXmlBorders(row_type row) const
+{
+ Tabular::XmlRowWiseBorders borders;
+
+ // Determine whether borders are required.
+ for (col_type c = 0; c < ncols(); ++c) {
+ if (row < nrows() - 1) {
+ if (!bottomLine(cellIndex(row, c))
+ || !topLine(cellIndex(row + 1, c))) {
+ borders.completeBorder = false;
+ }
+ if (!bottomLine(cellIndex(row, c))
+ && !topLine(cellIndex(row + 1, c))) {
+ borders.completeBorderBelow = false;
+ }
+ } else if (row == nrows() - 1 && !bottomLine(cellIndex(row, c))) {
+ borders.completeBorderBelow = false;
+ }
+
+ if ((row > 0 && !bottomLine(cellIndex(row - 1, c)) && !topLine(cellIndex(row, c))) ||
+ (row == 0 && !topLine(cellIndex(row, c)))) {
+ borders.completeBorderAbove = false;
+ }
+ }
+
+ // Size of booktabs borders.
+ if (use_booktabs) {
+ if (borders.completeBorderAbove)
+ borders.borderTopWidth = row == 0 ? 2 : 1.5;
+ if (borders.completeBorderBelow) {
+ borders.borderBottomWidth = row == nrows() - 1 ? 2 : 1.5;
+ borders.borderBottomWidthComplete = 3 * borders.borderBottomWidth;
+ }
+ }
+
+ return borders;
+}
+
+
+std::vector Tabular::computeCssStylePerCell(row_type row, col_type col, idx_type cell) const
+{
+ std::vector styles;
+
+ // Fixed width.
+ Length const col_width = column_info[col].p_width;
+ if (!col_width.zero())
+ styles.emplace_back("width: " + col_width.asHTMLString());
+
+ // Borders and booktabs.
+ const Tabular::XmlRowWiseBorders borders = computeXmlBorders(row);
+
+ if (bottomLine(cell)) {
+ if (row < nrows() - 1 && borders.completeBorder)
+ styles.emplace_back("border-bottom: " + to_string(borders.borderBottomWidthComplete) + "px double");
+ else
+ styles.emplace_back("border-bottom: " + to_string(borders.borderBottomWidth) + "px solid");
+ }
+ if (rightLine(cell)) {
+ if (col < ncols() - 1 && leftLine(cell + 1))
+ styles.emplace_back("border-right: 3px double");
+ else
+ styles.emplace_back("border-right: 1px solid");
+ }
+ if (leftLine(cell))
+ styles.emplace_back("border-left: 1px solid");
+ if (topLine(cell))
+ styles.emplace_back("border-top: " + to_string(borders.borderTopWidth) + "px solid");
+
+ return styles;
+}
+
docstring Tabular::xmlRow(XMLStream & xs, row_type row, OutputParams const & runparams,
bool header, bool is_xhtml, BufferParams::TableOutput docbook_table_output) const
@@ -3663,22 +3734,26 @@ docstring Tabular::xmlRow(XMLStream & xs, row_type row, OutputParams const & run
std::string const row_tag = is_xhtml_table ? "tr" : "row";
std::string const cell_tag = is_xhtml_table ? (header ? "th" : "td") : "entry";
+ Tabular::XmlRowWiseBorders const borders = computeXmlBorders(row);
idx_type cell = getFirstCellInRow(row);
xs << xml::StartTag(row_tag);
xs << xml::CR();
- for (col_type c = 0; c < ncols(); ++c) {
+ for (col_type c = 0; c < ncols(); ++c, ++cell) {
if (isPartOfMultiColumn(row, c) || isPartOfMultiRow(row, c))
continue;
stringstream attr;
if (is_xhtml_table) {
- Length const cwidth = column_info[c].p_width;
- if (!cwidth.zero()) {
- string const hwidth = cwidth.asHTMLString();
- attr << "style='width: " << hwidth << ";' ";
- }
+ const std::vector styles = computeCssStylePerCell(row, c, cell);
+ attr << "style='" ;
+ for (auto it = styles.begin(); it != styles.end(); ++it) {
+ attr << *it;
+ if (it != styles.end() - 1)
+ attr << "; ";
+ }
+ attr << "' ";
}
attr << getHAlignAsXmlAttribute(cell, false) << " " << getVAlignAsXmlAttribute(cell);
@@ -3707,7 +3782,6 @@ docstring Tabular::xmlRow(XMLStream & xs, row_type row, OutputParams const & run
}
xs << xml::EndTag(cell_tag);
xs << xml::CR();
- ++cell;
}
xs << xml::EndTag(row_tag);
xs << xml::CR();
diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h
index 8a99ef4086..0fbafa8ede 100644
--- a/src/insets/InsetTabular.h
+++ b/src/insets/InsetTabular.h
@@ -850,6 +850,24 @@ public:
///
typedef std::vector column_vector;
+private:
+ // Determines the style of borders, per row.
+ class XmlRowWiseBorders {
+ public:
+ // Whether to draw double bottom line.
+ bool completeBorder = true;
+
+ // Whether to draw booktabs' thicker lines.
+ bool completeBorderAbove = true;
+ bool completeBorderBelow = true;
+
+ // Size of the borders.
+ double borderBottomWidth = 1.0;
+ double borderBottomWidthComplete = 3.0;
+ double borderTopWidth = 1.0;
+ };
+
+public:
///
idx_type numberofcells;
///
@@ -939,6 +957,8 @@ public:
docstring xmlRow(XMLStream & xs, row_type row, OutputParams const &,
bool header = false, bool is_xhtml = true,
BufferParams::TableOutput docbook_table_output = BufferParams::TableOutput::HTMLTable) const;
+ XmlRowWiseBorders computeXmlBorders(row_type row) const;
+ std::vector computeCssStylePerCell(row_type row, col_type col, idx_type cell) const;
/// Transforms the vertical alignment of the given cell as a prebaked XML attribute (for HTML and CALS).
std::string getHAlignAsXmlAttribute(idx_type cell, bool is_xhtml = true) const;