X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetTabular.cpp;h=69f9e73e59f0f0f11e125f2c80e4ba5449048455;hb=8124e6c02ea1fd6779bb6c47ffe2bca2c8bd2d97;hp=18481a598d8381b1fbbf1e36fc2361b00f351197;hpb=0bb25ee3cd66c5ac78127a7ccc0d6014cb27edf4;p=lyx.git diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index 18481a598d..69f9e73e59 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,26 @@ 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='" + style.str(); + if (!styles.empty()) + attr_str_prefix += "; "; + for (auto it = styles.begin(); it != styles.end(); ++it) { + attr_str_prefix += *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) { @@ -7467,10 +7516,15 @@ docstring InsetTabular::asString(idx_type stidx, idx_type enidx, { LASSERT(stidx <= enidx, return docstring()); docstring retval; - col_type const col1 = tabular.cellColumn(stidx); - col_type const col2 = tabular.cellColumn(enidx); - row_type const row1 = tabular.cellRow(stidx); - row_type const row2 = tabular.cellRow(enidx); + col_type col1 = tabular.cellColumn(stidx); + col_type col2 = tabular.cellColumn(enidx); + row_type row1 = tabular.cellRow(stidx); + row_type row2 = tabular.cellRow(enidx); + // stidx might be in a later column or row than enidx + if (col1 > col2) + swap(col1, col2); + if (row1 > row2) + swap(row1, row2); bool first = true; for (col_type col = col1; col <= col2; col++) for (row_type row = row1; row <= row2; row++) { @@ -7488,10 +7542,15 @@ ParagraphList InsetTabular::asParList(idx_type stidx, idx_type enidx) { LASSERT(stidx <= enidx, return ParagraphList()); ParagraphList retval; - col_type const col1 = tabular.cellColumn(stidx); - col_type const col2 = tabular.cellColumn(enidx); - row_type const row1 = tabular.cellRow(stidx); - row_type const row2 = tabular.cellRow(enidx); + col_type col1 = tabular.cellColumn(stidx); + col_type col2 = tabular.cellColumn(enidx); + row_type row1 = tabular.cellRow(stidx); + row_type row2 = tabular.cellRow(enidx); + // stidx might be in a later column or row than enidx + if (col1 > col2) + swap(col1, col2); + if (row1 > row2) + swap(row1, row2); for (col_type col = col1; col <= col2; col++) for (row_type row = row1; row <= row2; row++) for (auto const & par : tabular.cellInset(row, col)->paragraphs())