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:
parent
b85e51d6d5
commit
96028073cb
@ -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')
|
||||||
{
|
{
|
||||||
|
@ -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'))
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -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}
|
||||||
|
@ -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 "">
|
||||||
|
@ -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"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user