From 1f370a33536008c80c8e363a8097a9daef772c65 Mon Sep 17 00:00:00 2001 From: Thibaut Cuvelier Date: Mon, 9 Jan 2023 01:50:05 +0100 Subject: [PATCH] LyXHTML: avoid using v/align HTML attributes in tables, they are deprecated (like most attributes for td). Also implement alignment at character in CSS. --- src/insets/InsetTabular.cpp | 103 ++++++++++++++++++++++++++---------- src/insets/InsetTabular.h | 10 ++-- 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index 18481a598d..265a0165f8 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -3628,31 +3628,63 @@ std::string Tabular::getVAlignAsXmlAttribute(idx_type cell) const } -std::string Tabular::getHAlignAsXmlAttribute(idx_type cell, const XmlOutputFormat output_format) const +std::string Tabular::getVAlignAsCssAttribute(idx_type cell) const +{ + switch (getVAlignment(cell)) { + case LYX_VALIGN_TOP: + return "vertical-align: top"; + case LYX_VALIGN_BOTTOM: + return "vertical-align: bottom"; + case LYX_VALIGN_MIDDLE: + return "vertical-align: middle"; + default: + // This case only silences a compiler warning, as all the cases are covered above. + return ""; + } +} + + +std::string Tabular::getHAlignAsXmlAttribute(idx_type cell) const { switch (getAlignment(cell)) { case LYX_ALIGN_LEFT: return "align='left'"; case LYX_ALIGN_RIGHT: return "align='right'"; + case LYX_ALIGN_BLOCK: + return "align='justify'"; + case LYX_ALIGN_DECIMAL: { + Language const *lang = buffer().paragraphs().front().getParLanguage(buffer().params()); + return "align='char' char='" + to_utf8(lang->decimalSeparator()) + "'"; + } + default: + return "align='center'"; + } +} + +std::string Tabular::getHAlignAsCssAttribute(idx_type cell) const +{ + switch (getAlignment(cell)) { + case LYX_ALIGN_LEFT: + return "text-align: left"; + case LYX_ALIGN_RIGHT: + return "text-align: right"; + case LYX_ALIGN_BLOCK: + return "text-align: justify"; + case LYX_ALIGN_DECIMAL: { + // In theory, character-level alignment is supported for CSS4, but it's + // experimental. + // https://www.w3.org/TR/css-text-4/#character-alignment + Language const *lang = buffer().paragraphs().front().getParLanguage(buffer().params()); + return "text-align: '" + to_utf8(lang->decimalSeparator()) + "'"; + } default: - // HTML only supports left, right, and center. - if (output_format == XmlOutputFormat::XHTML) - return "align='center'"; - - // DocBook also has justify and decimal. - if (getAlignment(cell) == LYX_ALIGN_BLOCK) { - return "align='justify'"; - } else if (getAlignment(cell) == LYX_ALIGN_DECIMAL) { - Language const *tlang = buffer().paragraphs().front().getParLanguage(buffer().params()); - return "align='char' char='" + to_utf8(tlang->decimalSeparator()) + "'"; - } else { - return "align='center'"; - } + return "text-align: center"; } } + Tabular::XmlRowWiseBorders Tabular::computeXmlBorders(row_type row) const { Tabular::XmlRowWiseBorders borders; @@ -3755,25 +3787,24 @@ docstring Tabular::xmlRow(XMLStream & xs, const row_type row, OutputParams const if (isPartOfMultiColumn(row, c) || isPartOfMultiRow(row, c)) continue; - stringstream attr; - - if (is_xhtml_table) { - 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 << "' "; - } + stringstream attr; // Tag-level attributes, both for HTML and CALS. + stringstream style; // Tag-level CSS, only for HTML tables output in HTML. if (is_cals_table) { if (!cals_row_has_rowsep && bottomLine(cell)) attr << "rowsep='1' "; } - attr << getHAlignAsXmlAttribute(cell, output_format) << " " << getVAlignAsXmlAttribute(cell); + if (output_format == XmlOutputFormat::XHTML) { + // In HTML5, prefer to use CSS instead of attributes for alignment + // (align and valign). + style << getHAlignAsCssAttribute(cell) << " " + << getVAlignAsCssAttribute(cell); + } else { + // In DocBook, both for HTML and CALS tables, stick to attributes. + attr << getHAlignAsXmlAttribute(cell) << " " + << getVAlignAsXmlAttribute(cell); + } if (is_xhtml_table) { if (isMultiColumn(cell)) @@ -3789,8 +3820,24 @@ docstring Tabular::xmlRow(XMLStream & xs, const row_type row, OutputParams const attr << " colname='c" << (c + 1) << "'"; // CALS column numbering starts at 1. } + // Final step: prepend the CSS style. + std::string attr_str = attr.str(); + if (is_xhtml_table) { + const std::vector styles = computeCssStylePerCell(row, c, cell); + + std::string attr_str_prefix = "style='" ; + for (auto it = styles.begin(); it != styles.end(); ++it) { + attr << *it; + if (it != styles.end() - 1) + attr_str_prefix += "; "; + } + attr_str_prefix += "' "; + + attr_str.insert(0, attr_str_prefix); + } + // Render the cell as either XHTML or DocBook. - xs << xml::StartTag(cell_tag, attr.str(), true); + xs << xml::StartTag(cell_tag, attr_str, true); if (output_format == XmlOutputFormat::XHTML) { ret += cellInset(cell)->xhtml(xs, runparams); } else if (output_format == XmlOutputFormat::DOCBOOK) { diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h index 6c63cbc1d3..f189714e1b 100644 --- a/src/insets/InsetTabular.h +++ b/src/insets/InsetTabular.h @@ -945,9 +945,13 @@ private: DOCBOOK = false }; - /// Transforms the vertical alignment of the given cell as a prebaked XML attribute (for HTML and CALS). - std::string getHAlignAsXmlAttribute(idx_type cell, XmlOutputFormat output_format) const; - /// Transforms the vertical alignment of the given cell as a prebaked XML attribute (for HTML and CALS). + /// Transforms the vertical alignment of the given cell as prebaked CSS (for HTML tables in HTML output). + std::string getHAlignAsXmlAttribute(idx_type cell) const; + /// Transforms the vertical alignment of the given cell as a prebaked XML attribute (for CALS or HTML tables in DocBook). + std::string getHAlignAsCssAttribute(idx_type cell) const; + /// Transforms the vertical alignment of the given cell as prebaked CSS (for HTML tables in HTML output). + std::string getVAlignAsCssAttribute(idx_type cell) const; + /// Transforms the vertical alignment of the given cell as a prebaked XML attribute (for CALS or HTML tables in DocBook). std::string getVAlignAsXmlAttribute(idx_type cell) const; /// Helpers for XML tables (XHTML or DocBook). -- 2.39.5