1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

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

Contributed by Cynthia Shang.
This commit is contained in:
Cynthia Shang 2018-12-18 21:56:39 +02:00 committed by David Steele
parent b85e51d6d5
commit 96028073cb
7 changed files with 178 additions and 22 deletions

View File

@ -394,6 +394,57 @@ sub sectionProcess
$oSectionBodyElement->addNew( $oSectionBodyElement->addNew(
HTML_PRE, 'code-block', {strContent => $strValue, bPre => true}); 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 # Add descriptive text
elsif ($oChild->nameGet() eq 'p') elsif ($oChild->nameGet() eq 'p')
{ {

View File

@ -228,11 +228,18 @@ sub sectionProcess
# Add table # Add table
elsif ($oChild->nameGet() eq 'table') elsif ($oChild->nameGet() eq 'table')
{ {
my $oHeader = $oChild->nodeGet('table-header'); my $oHeader;
my @oyColumn = $oHeader->nodeList('table-column'); my @oyColumn;
if ($oChild->nodeTest('table-header'))
{
$oHeader = $oChild->nodeGet('table-header');
@oyColumn = $oHeader->nodeList('table-column');
}
my $strWidth = 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 # Build the table header
$strLatex .= "\\vspace{1em}\\newline\n"; $strLatex .= "\\vspace{1em}\\newline\n";
@ -244,7 +251,8 @@ sub sectionProcess
my $strAlignCode; my $strAlignCode;
my $strAlign = $oColumn->paramGet("align", false); 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') if (!defined($strAlign) || $strAlign eq 'left')
{ {
@ -254,6 +262,10 @@ sub sectionProcess
{ {
$strAlignCode = 'R'; $strAlignCode = 'R';
} }
elsif ($strAlign eq 'center')
{
$strAlignCode = 'C';
}
else else
{ {
confess &log(ERROR, "align '${strAlign}' not valid when fill=y"); confess &log(ERROR, "align '${strAlign}' not valid when fill=y");
@ -283,6 +295,16 @@ sub sectionProcess
$strLatex .= $strAlignCode . ' | '; $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"; $strLatex .= "}\n";
if ($oChild->nodeGet("title", false)) if ($oChild->nodeGet("title", false))
@ -290,17 +312,20 @@ sub sectionProcess
$strLatex .= "\\caption{" . $self->processText($oChild->nodeGet("title")->textGet()) . ":}\\\\\n"; $strLatex .= "\\caption{" . $self->processText($oChild->nodeGet("title")->textGet()) . ":}\\\\\n";
} }
my $strLine;
if (defined($oHeader))
{
$strLatex .= "\\hline"; $strLatex .= "\\hline";
$strLatex .= "\\rowcolor{ltgray}\n"; $strLatex .= "\\rowcolor{ltgray}\n";
my $strLine;
foreach my $oColumn (@oyColumn) foreach my $oColumn (@oyColumn)
{ {
$strLine .= (defined($strLine) ? ' & ' : '') . '\textbf{' . $self->processText($oColumn->textGet()) . '}'; $strLine .= (defined($strLine) ? ' & ' : '') . '\textbf{' . $self->processText($oColumn->textGet()) . '}';
} }
$strLatex .= "${strLine}\\\\"; $strLatex .= "${strLine}\\\\";
}
# Build the rows # Build the rows
foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row')) foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row'))

View File

@ -365,8 +365,15 @@ sub sectionProcess
$oTableTitle = $oChild->nodeGet('title'); $oTableTitle = $oChild->nodeGet('title');
} }
my $oHeader = $oChild->nodeGet('table-header'); my $oHeader;
my @oyColumn = $oHeader->nodeList('table-column'); my @oyColumn;
if ($oChild->nodeTest('table-header'))
{
$oHeader = $oChild->nodeGet('table-header');
@oyColumn = $oHeader->nodeList('table-column');
}
if (defined($oTableTitle)) if (defined($oTableTitle))
{ {
# Print the label (e.g. Table 1:) in front of the title if one exists # Print the label (e.g. Table 1:) in front of the title if one exists
@ -379,35 +386,49 @@ sub sectionProcess
$strMarkdown .= "\n\n"; $strMarkdown .= "\n\n";
} }
my ($strHeaderText, $strHeaderIndicator); my $strHeaderText = "| ";
my $strHeaderIndicator = "| ";
for (my $iColCellIdx = 0; $iColCellIdx < @oyColumn; $iColCellIdx++) for (my $iColCellIdx = 0; $iColCellIdx < @oyColumn; $iColCellIdx++)
{ {
my $strAlign = $oyColumn[$iColCellIdx]->paramGet("align", false, 'left'); my $strAlign = $oyColumn[$iColCellIdx]->paramGet("align", false, 'left');
$strHeaderText .= $self->processText($oyColumn[$iColCellIdx]->textGet()) . $strHeaderText .= $self->processText($oyColumn[$iColCellIdx]->textGet()) .
(($iColCellIdx < @oyColumn - 1) ? " | " : "\n"); (($iColCellIdx < @oyColumn - 1) ? " | " : " |\n");
$strHeaderIndicator .= ($strAlign eq 'left' || $strAlign eq 'center') ? ":---" : "---"; $strHeaderIndicator .= ($strAlign eq 'left' || $strAlign eq 'center') ? ":---" : "---";
$strHeaderIndicator .= ($strAlign eq 'right' || $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 # Build the rows
foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row')) foreach my $oRow ($oChild->nodeGet('table-data')->nodeList('table-row'))
{ {
my @oRowCellList = $oRow->nodeList('table-cell'); my @oRowCellList = $oRow->nodeList('table-cell');
$strMarkdown .= "| ";
for (my $iRowCellIdx = 0; $iRowCellIdx < @oRowCellList; $iRowCellIdx++) for (my $iRowCellIdx = 0; $iRowCellIdx < @oRowCellList; $iRowCellIdx++)
{ {
my $oRowCell = $oRowCellList[$iRowCellIdx]; my $oRowCell = $oRowCellList[$iRowCellIdx];
$strMarkdown .= $self->processText($oRowCell->textGet()) . $strMarkdown .= $self->processText($oRowCell->textGet()) .
(($iRowCellIdx < @oRowCellList -1) ? " | " : ""); (($iRowCellIdx < @oRowCellList -1) ? " | " : " |\n");
} }
$strMarkdown .= "\n";
} }
} }
# Check if the child can be processed by a parent # Check if the child can be processed by a parent

View File

@ -298,6 +298,56 @@ Section
/*.section-body*/ /*.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 Config, Execute, Code Block, Release Elements
*******************************************************************************/ *******************************************************************************/

View File

@ -52,6 +52,7 @@
% ---------------------------------------------------------------------------------------------------------------------------------- % ----------------------------------------------------------------------------------------------------------------------------------
\usepackage{tabularx} \usepackage{tabularx}
\newcolumntype{R}{>{\raggedleft\arraybackslash}X}% \newcolumntype{R}{>{\raggedleft\arraybackslash}X}%
\newcolumntype{C}{>{\centering\arraybackslash}X}%
\renewcommand{\arraystretch}{1.3} \renewcommand{\arraystretch}{1.3}
% \usepackage{ltablex} % \usepackage{ltablex}

View File

@ -206,7 +206,7 @@
<!ATTLIST host-add mount CDATA ""> <!ATTLIST host-add mount CDATA "">
<!-- Table elements --> <!-- Table elements -->
<!ELEMENT table (title?, table-header, table-data)> <!ELEMENT table (title?, table-header?, table-data)>
<!ELEMENT table-header (table-column+)> <!ELEMENT table-header (table-column+)>
<!ATTLIST table-header width CDATA ""> <!ATTLIST table-header width CDATA "">

View File

@ -235,6 +235,14 @@
</release-improvement-list> </release-improvement-list>
<release-development-list> <release-development-list>
<release-item>
<release-item-contributor-list>
<release-item-contributor id="cynthia.shang"/>
</release-item-contributor-list>
<p>Add HTML table rendering and update PDF/Markdown renderers to support header-less tables.</p>
</release-item>
<release-item> <release-item>
<release-item-contributor-list> <release-item-contributor-list>
<release-item-contributor id="cynthia.shang"/> <release-item-contributor id="cynthia.shang"/>