diff --git a/doc/lib/BackRestDoc/Html/DocHtmlPage.pm b/doc/lib/BackRestDoc/Html/DocHtmlPage.pm index 6f5ebbd29..e457e819c 100644 --- a/doc/lib/BackRestDoc/Html/DocHtmlPage.pm +++ b/doc/lib/BackRestDoc/Html/DocHtmlPage.pm @@ -394,6 +394,57 @@ sub sectionProcess $oSectionBodyElement->addNew( HTML_PRE, 'code-block', {strContent => $strValue, bPre => true}); } + # Add table + elsif ($oChild->nameGet() eq 'table') + { + my $oTableTitle; + if ($oChild->nodeTest('title')) + { + $oTableTitle = $oChild->nodeGet('title'); + } + + my $oTableElement = $oSectionBodyElement->addNew(HTML_TABLE, 'table'); + my @oyColumn; + + # Build the header + if ($oChild->nodeTest('table-header')) + { + my $oHeader = $oChild->nodeGet('table-header'); + @oyColumn = $oHeader->nodeList('table-column'); + + my $oHeaderRowElement = $oTableElement->addNew(HTML_TR, 'table-header-row'); + + foreach my $oColumn (@oyColumn) + { + # Each column can have different alignment properties - if not set, then default to align left + my $strAlign = $oColumn->paramGet("align", false, 'left'); + my $bFill = $oColumn->paramTest('fill', 'y'); + + $oHeaderRowElement->addNew( + HTML_TH, + "table-header-${strAlign}" . ($bFill ? ",table-header-fill" : ""), + {strContent => $self->processText($oColumn->textGet())}); + } + } + + # Build the rows + foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row')) + { + my $oRowElement = $oTableElement->addNew(HTML_TR, 'table-row'); + my @oRowCellList = $oRow->nodeList('table-cell'); + + for (my $iRowCellIdx = 0; $iRowCellIdx < @oRowCellList; $iRowCellIdx++) + { + my $oRowCell = $oRowCellList[$iRowCellIdx]; + + # If a header row was defined, then get the column alignment, else default to left + my $strAlign = @oyColumn > 0 ? $oyColumn[$iRowCellIdx]->paramGet("align", false, 'left') : 'left'; + + $oRowElement->addNew( + HTML_TD, "table-data-${strAlign}", {strContent => $self->processText($oRowCell->textGet())}); + } + } + } # Add descriptive text elsif ($oChild->nameGet() eq 'p') { diff --git a/doc/lib/BackRestDoc/Latex/DocLatexSection.pm b/doc/lib/BackRestDoc/Latex/DocLatexSection.pm index 0c5bc33bc..4affa6fd4 100644 --- a/doc/lib/BackRestDoc/Latex/DocLatexSection.pm +++ b/doc/lib/BackRestDoc/Latex/DocLatexSection.pm @@ -228,23 +228,31 @@ sub sectionProcess # Add table elsif ($oChild->nameGet() eq 'table') { - my $oHeader = $oChild->nodeGet('table-header'); - my @oyColumn = $oHeader->nodeList('table-column'); + my $oHeader; + my @oyColumn; + + if ($oChild->nodeTest('table-header')) + { + $oHeader = $oChild->nodeGet('table-header'); + @oyColumn = $oHeader->nodeList('table-column'); + } my $strWidth = - '{' . ($oHeader->paramTest('width') ? ($oHeader->paramGet('width') / 100) . '\textwidth' : '\textwidth') . '}'; + '{' . (defined($oHeader) && $oHeader->paramTest('width') ? ($oHeader->paramGet('width') / 100) . + '\textwidth' : '\textwidth') . '}'; # Build the table header $strLatex .= "\\vspace{1em}\\newline\n"; - $strLatex .= "\\begin{tabularx}${strWidth}{ | "; + $strLatex .= "\\begin{tabularx}${strWidth}{|"; foreach my $oColumn (@oyColumn) { my $strAlignCode; my $strAlign = $oColumn->paramGet("align", false); - if ($oColumn->paramGet('fill', false, 'y') eq 'y') + # If fill is specified then use X or the custom designed alignments in the preamble to fill and justify the columns. + if ($oColumn->paramTest('fill') && $oColumn->paramGet('fill', false) eq 'y') { if (!defined($strAlign) || $strAlign eq 'left') { @@ -254,6 +262,10 @@ sub sectionProcess { $strAlignCode = 'R'; } + elsif ($strAlign eq 'center') + { + $strAlignCode = 'C'; + } else { confess &log(ERROR, "align '${strAlign}' not valid when fill=y"); @@ -283,6 +295,16 @@ sub sectionProcess $strLatex .= $strAlignCode . ' | '; } + # If table-header not provided then default the column alignment and fill by using the number of columns in the 1st row + if (!defined($oHeader)) + { + my @oyRow = $oChild->nodeGet('table-data')->nodeList('table-row'); + foreach my $oRowCell ($oyRow[0]->nodeList('table-cell')) + { + $strLatex .= 'X|'; + } + } + $strLatex .= "}\n"; if ($oChild->nodeGet("title", false)) @@ -290,17 +312,20 @@ sub sectionProcess $strLatex .= "\\caption{" . $self->processText($oChild->nodeGet("title")->textGet()) . ":}\\\\\n"; } - $strLatex .= "\\hline"; - $strLatex .= "\\rowcolor{ltgray}\n"; - my $strLine; - foreach my $oColumn (@oyColumn) + if (defined($oHeader)) { - $strLine .= (defined($strLine) ? ' & ' : '') . '\textbf{' . $self->processText($oColumn->textGet()) . '}'; - } + $strLatex .= "\\hline"; + $strLatex .= "\\rowcolor{ltgray}\n"; - $strLatex .= "${strLine}\\\\"; + foreach my $oColumn (@oyColumn) + { + $strLine .= (defined($strLine) ? ' & ' : '') . '\textbf{' . $self->processText($oColumn->textGet()) . '}'; + } + + $strLatex .= "${strLine}\\\\"; + } # Build the rows foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row')) diff --git a/doc/lib/BackRestDoc/Markdown/DocMarkdownRender.pm b/doc/lib/BackRestDoc/Markdown/DocMarkdownRender.pm index de213cd8b..acd6462aa 100644 --- a/doc/lib/BackRestDoc/Markdown/DocMarkdownRender.pm +++ b/doc/lib/BackRestDoc/Markdown/DocMarkdownRender.pm @@ -365,8 +365,15 @@ sub sectionProcess $oTableTitle = $oChild->nodeGet('title'); } - my $oHeader = $oChild->nodeGet('table-header'); - my @oyColumn = $oHeader->nodeList('table-column'); + my $oHeader; + my @oyColumn; + + if ($oChild->nodeTest('table-header')) + { + $oHeader = $oChild->nodeGet('table-header'); + @oyColumn = $oHeader->nodeList('table-column'); + } + if (defined($oTableTitle)) { # Print the label (e.g. Table 1:) in front of the title if one exists @@ -379,35 +386,49 @@ sub sectionProcess $strMarkdown .= "\n\n"; } - my ($strHeaderText, $strHeaderIndicator); + my $strHeaderText = "| "; + my $strHeaderIndicator = "| "; for (my $iColCellIdx = 0; $iColCellIdx < @oyColumn; $iColCellIdx++) { my $strAlign = $oyColumn[$iColCellIdx]->paramGet("align", false, 'left'); $strHeaderText .= $self->processText($oyColumn[$iColCellIdx]->textGet()) . - (($iColCellIdx < @oyColumn - 1) ? " | " : "\n"); + (($iColCellIdx < @oyColumn - 1) ? " | " : " |\n"); $strHeaderIndicator .= ($strAlign eq 'left' || $strAlign eq 'center') ? ":---" : "---"; $strHeaderIndicator .= ($strAlign eq 'right' || $strAlign eq 'center') ? "---:" : ""; - $strHeaderIndicator .= ($iColCellIdx < @oyColumn - 1) ? " | " : "\n"; + $strHeaderIndicator .= ($iColCellIdx < @oyColumn - 1) ? " | " : " |\n"; } - $strMarkdown .= $strHeaderText .$strHeaderIndicator; + # Markdown requires a table header so if not provided then create an empty header row and default the column alignment + # left by using the number of columns in the 1st row + if (!defined($oHeader)) + { + my @oyRow = $oChild->nodeGet('table-data')->nodeList('table-row'); + foreach my $oRowCell ($oyRow[0]->nodeList('table-cell')) + { + $strHeaderText .= " | "; + $strHeaderIndicator .= ":--- | "; + } + $strHeaderText .= "\n"; + $strHeaderIndicator .= "\n"; + } + + $strMarkdown .= (defined($strHeaderText) ? $strHeaderText : '') . $strHeaderIndicator; # Build the rows foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row')) { my @oRowCellList = $oRow->nodeList('table-cell'); + $strMarkdown .= "| "; for (my $iRowCellIdx = 0; $iRowCellIdx < @oRowCellList; $iRowCellIdx++) { my $oRowCell = $oRowCellList[$iRowCellIdx]; $strMarkdown .= $self->processText($oRowCell->textGet()) . - (($iRowCellIdx < @oRowCellList -1) ? " | " : ""); + (($iRowCellIdx < @oRowCellList -1) ? " | " : " |\n"); } - - $strMarkdown .= "\n"; } } # Check if the child can be processed by a parent diff --git a/doc/resource/html/default.css b/doc/resource/html/default.css index 7861222d2..1f3732db9 100644 --- a/doc/resource/html/default.css +++ b/doc/resource/html/default.css @@ -298,6 +298,56 @@ Section /*.section-body*/ +/******************************************************************************* +Table Elements +*******************************************************************************/ +.table +{ +} + +.table-header-row +{ +} + +.table-header-left +{ + text-align: left; +} + +.table-header-center +{ + text-align: center; +} + +.table-header-right +{ + text-align: right; +} + +.table-header-fill +{ + width: 100%; +} + +.table-row +{ +} + +.table-data-left +{ + text-align: left; +} + +.table-data-center +{ + text-align: center; +} + +.table-data-right +{ + text-align: right; +} + /******************************************************************************* Config, Execute, Code Block, Release Elements *******************************************************************************/ diff --git a/doc/resource/latex/preamble.tex b/doc/resource/latex/preamble.tex index 519e9aa2b..6ba598f99 100644 --- a/doc/resource/latex/preamble.tex +++ b/doc/resource/latex/preamble.tex @@ -52,6 +52,7 @@ % ---------------------------------------------------------------------------------------------------------------------------------- \usepackage{tabularx} \newcolumntype{R}{>{\raggedleft\arraybackslash}X}% +\newcolumntype{C}{>{\centering\arraybackslash}X}% \renewcommand{\arraystretch}{1.3} % \usepackage{ltablex} diff --git a/doc/xml/dtd/doc.dtd b/doc/xml/dtd/doc.dtd index 4344e19c5..ee9e72ad3 100644 --- a/doc/xml/dtd/doc.dtd +++ b/doc/xml/dtd/doc.dtd @@ -206,7 +206,7 @@ - + diff --git a/doc/xml/release.xml b/doc/xml/release.xml index 154b8982a..5b48867e8 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -235,6 +235,14 @@ + + + + + +

Add HTML table rendering and update PDF/Markdown renderers to support header-less tables.

+
+