Skip to content

Commit b14f81b

Browse files
committed
Add a latex-longtable output format to psql
latex longtable is more powerful than the 'tabular' output format 'latex' uses. Also add border=3 support to 'latex'.
1 parent 8ef6961 commit b14f81b

File tree

4 files changed

+199
-14
lines changed

4 files changed

+199
-14
lines changed

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,6 +1890,9 @@ lo_import 152801
18901890
into the <literal>border=...</literal> attribute; in the
18911891
other formats only values 0 (no border), 1 (internal dividing lines),
18921892
and 2 (table frame) make sense.
1893+
<literal>latex</literal> and <literal>latex-longtable</literal>
1894+
also support a <literal>border</literal> value of 3 which adds
1895+
a dividing line between each row.
18931896
</para>
18941897
</listitem>
18951898
</varlistentry>
@@ -1979,7 +1982,9 @@ lo_import 152801
19791982
Sets the output format to one of <literal>unaligned</literal>,
19801983
<literal>aligned</literal>, <literal>wrapped</literal>,
19811984
<literal>html</literal>,
1982-
<literal>latex</literal>, or <literal>troff-ms</literal>.
1985+
<literal>latex</literal> (uses <literal>tabular</literal>),
1986+
<literal>latex-longtable</literal>, or
1987+
<literal>troff-ms</literal>.
19831988
Unique abbreviations are allowed. (That would mean one letter
19841989
is enough.)
19851990
</para>
@@ -2005,12 +2010,16 @@ lo_import 152801
20052010
</para>
20062011

20072012
<para>
2008-
The <literal>html</>, <literal>latex</>, and <literal>troff-ms</>
2013+
The <literal>html</>, <literal>latex</>,
2014+
<literal>latex-longtable</literal>, and <literal>troff-ms</>
20092015
formats put out tables that are intended to
20102016
be included in documents using the respective mark-up
2011-
language. They are not complete documents! (This might not be
2012-
so dramatic in <acronym>HTML</acronym>, but in <application>LaTeX</application> you must
2013-
have a complete document wrapper.)
2017+
language. They are not complete documents! This might not be
2018+
necessary in <acronym>HTML</acronym>, but in
2019+
<application>LaTeX</application> you must have a complete
2020+
document wrapper. <literal>latex-longtable</literal>
2021+
also requires the <application>LaTeX</application>
2022+
<literal>longtable</literal> and <literal>booktabs</> packages.
20142023
</para>
20152024
</listitem>
20162025
</varlistentry>
@@ -2141,9 +2150,8 @@ lo_import 152801
21412150
<term><literal>tableattr</literal> (or <literal>T</literal>)</term>
21422151
<listitem>
21432152
<para>
2144-
Specifies attributes to be placed inside the
2145-
<acronym>HTML</acronym> <sgmltag>table</sgmltag> tag in
2146-
<literal>html</> output format. This
2153+
In <acronym>HTML</acronym> format, this specifies attributes
2154+
to be placed inside the <sgmltag>table</sgmltag> tag. This
21472155
could for example be <literal>cellpadding</literal> or
21482156
<literal>bgcolor</literal>. Note that you probably don't want
21492157
to specify <literal>border</literal> here, as that is already
@@ -2152,6 +2160,13 @@ lo_import 152801
21522160
<replaceable class="parameter">value</replaceable> is given,
21532161
the table attributes are unset.
21542162
</para>
2163+
<para>
2164+
In <literal>latex-longtable</literal> format, this controls
2165+
the proportional width of each column containing a left-aligned
2166+
data type. It is specified as a space-separated list of values,
2167+
e.g. <literal>'0.2 0.2 0.6'</>. Unspecified output columns
2168+
use the last specified value.
2169+
</para>
21552170
</listitem>
21562171
</varlistentry>
21572172

src/bin/psql/command.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,9 @@ _align2string(enum printFormat in)
21642164
case PRINT_LATEX:
21652165
return "latex";
21662166
break;
2167+
case PRINT_LATEX_LONGTABLE:
2168+
return "latex-longtable";
2169+
break;
21672170
case PRINT_TROFF_MS:
21682171
return "troff-ms";
21692172
break;
@@ -2197,6 +2200,8 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
21972200
popt->topt.format = PRINT_HTML;
21982201
else if (pg_strncasecmp("latex", value, vallen) == 0)
21992202
popt->topt.format = PRINT_LATEX;
2203+
else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
2204+
popt->topt.format = PRINT_LATEX_LONGTABLE;
22002205
else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
22012206
popt->topt.format = PRINT_TROFF_MS;
22022207
else

src/bin/psql/print.c

Lines changed: 170 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,8 +1612,8 @@ print_latex_text(const printTableContent *cont, FILE *fout)
16121612
if (cancel_pressed)
16131613
return;
16141614

1615-
if (opt_border > 2)
1616-
opt_border = 2;
1615+
if (opt_border > 3)
1616+
opt_border = 3;
16171617

16181618
if (cont->opt->start_table)
16191619
{
@@ -1628,20 +1628,20 @@ print_latex_text(const printTableContent *cont, FILE *fout)
16281628
/* begin environment and set alignments and borders */
16291629
fputs("\\begin{tabular}{", fout);
16301630

1631-
if (opt_border == 2)
1631+
if (opt_border >= 2)
16321632
fputs("| ", fout);
16331633
for (i = 0; i < cont->ncolumns; i++)
16341634
{
16351635
fputc(*(cont->aligns + i), fout);
16361636
if (opt_border != 0 && i < cont->ncolumns - 1)
16371637
fputs(" | ", fout);
16381638
}
1639-
if (opt_border == 2)
1639+
if (opt_border >= 2)
16401640
fputs(" |", fout);
16411641

16421642
fputs("}\n", fout);
16431643

1644-
if (!opt_tuples_only && opt_border == 2)
1644+
if (!opt_tuples_only && opt_border >= 2)
16451645
fputs("\\hline\n", fout);
16461646

16471647
/* print headers */
@@ -1668,6 +1668,8 @@ print_latex_text(const printTableContent *cont, FILE *fout)
16681668
if ((i + 1) % cont->ncolumns == 0)
16691669
{
16701670
fputs(" \\\\\n", fout);
1671+
if (opt_border == 3)
1672+
fputs("\\hline\n", fout);
16711673
if (cancel_pressed)
16721674
break;
16731675
}
@@ -1679,7 +1681,7 @@ print_latex_text(const printTableContent *cont, FILE *fout)
16791681
{
16801682
printTableFooter *footers = footers_with_default(cont);
16811683

1682-
if (opt_border == 2)
1684+
if (opt_border >= 2)
16831685
fputs("\\hline\n", fout);
16841686

16851687
fputs("\\end{tabular}\n\n\\noindent ", fout);
@@ -1701,6 +1703,162 @@ print_latex_text(const printTableContent *cont, FILE *fout)
17011703
}
17021704

17031705

1706+
static void
1707+
print_latex_text_longtable(const printTableContent *cont, FILE *fout)
1708+
{
1709+
bool opt_tuples_only = cont->opt->tuples_only;
1710+
unsigned short opt_border = cont->opt->border;
1711+
unsigned int i;
1712+
const char *opt_table_attr = cont->opt->tableAttr;
1713+
const char *next_opt_table_attr_char = opt_table_attr;
1714+
const char *last_opt_table_attr_char = NULL;
1715+
const char *const * ptr;
1716+
1717+
if (cancel_pressed)
1718+
return;
1719+
1720+
if (opt_border > 3)
1721+
opt_border = 3;
1722+
1723+
if (cont->opt->start_table)
1724+
{
1725+
/* begin environment and set alignments and borders */
1726+
fputs("\\begin{longtable}{", fout);
1727+
1728+
if (opt_border >= 2)
1729+
fputs("| ", fout);
1730+
1731+
for (i = 0; i < cont->ncolumns; i++)
1732+
{
1733+
/* longtable supports either a width (p) or an alignment (l/r) */
1734+
/* Are we left-justified and was a proportional width specified? */
1735+
if (*(cont->aligns + i) == 'l' && opt_table_attr)
1736+
{
1737+
#define LONGTABLE_WHITESPACE " \t\n"
1738+
1739+
/* advance over whitespace */
1740+
next_opt_table_attr_char += strspn(next_opt_table_attr_char,
1741+
LONGTABLE_WHITESPACE);
1742+
/* We have a value? */
1743+
if (next_opt_table_attr_char[0] != '\0')
1744+
{
1745+
fputs("p{", fout);
1746+
fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
1747+
LONGTABLE_WHITESPACE), 1, fout);
1748+
last_opt_table_attr_char = next_opt_table_attr_char;
1749+
next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
1750+
LONGTABLE_WHITESPACE);
1751+
fputs("\\textwidth}", fout);
1752+
}
1753+
/* use previous value */
1754+
else if (last_opt_table_attr_char != NULL)
1755+
{
1756+
fputs("p{", fout);
1757+
fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
1758+
LONGTABLE_WHITESPACE), 1, fout);
1759+
fputs("\\textwidth}", fout);
1760+
}
1761+
else
1762+
fputc('l', fout);
1763+
}
1764+
else
1765+
fputc(*(cont->aligns + i), fout);
1766+
1767+
if (opt_border != 0 && i < cont->ncolumns - 1)
1768+
fputs(" | ", fout);
1769+
}
1770+
1771+
if (opt_border >= 2)
1772+
fputs(" |", fout);
1773+
1774+
fputs("}\n", fout);
1775+
1776+
/* print headers */
1777+
if (!opt_tuples_only)
1778+
{
1779+
/* firsthead */
1780+
if (opt_border >= 2)
1781+
fputs("\\toprule\n", fout);
1782+
for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
1783+
{
1784+
if (i != 0)
1785+
fputs(" & ", fout);
1786+
fputs("\\small\\textbf{\\textit{", fout);
1787+
latex_escaped_print(*ptr, fout);
1788+
fputs("}}", fout);
1789+
}
1790+
fputs(" \\\\\n", fout);
1791+
fputs("\\midrule\n\\endfirsthead\n", fout);
1792+
1793+
/* secondary heads */
1794+
if (opt_border >= 2)
1795+
fputs("\\toprule\n", fout);
1796+
for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
1797+
{
1798+
if (i != 0)
1799+
fputs(" & ", fout);
1800+
fputs("\\small\\textbf{\\textit{", fout);
1801+
latex_escaped_print(*ptr, fout);
1802+
fputs("}}", fout);
1803+
}
1804+
fputs(" \\\\\n", fout);
1805+
/* If the line under the row already appeared, don't do another */
1806+
if (opt_border != 3)
1807+
fputs("\\midrule\n", fout);
1808+
fputs("\\endhead\n", fout);
1809+
1810+
/* table name, caption? */
1811+
if (!opt_tuples_only && cont->title)
1812+
{
1813+
/* Don't output if we are printing a line under each row */
1814+
if (opt_border == 2)
1815+
fputs("\\bottomrule\n", fout);
1816+
fputs("\\caption[", fout);
1817+
latex_escaped_print(cont->title, fout);
1818+
fputs(" (Continued)]{", fout);
1819+
latex_escaped_print(cont->title, fout);
1820+
fputs("}\n\\endfoot\n", fout);
1821+
if (opt_border == 2)
1822+
fputs("\\bottomrule\n", fout);
1823+
fputs("\\caption[", fout);
1824+
latex_escaped_print(cont->title, fout);
1825+
fputs("]{", fout);
1826+
latex_escaped_print(cont->title, fout);
1827+
fputs("}\n\\endlastfoot\n", fout);
1828+
}
1829+
/* output bottom table line? */
1830+
else if (opt_border >= 2)
1831+
{
1832+
fputs("\\bottomrule\n\\endfoot\n", fout);
1833+
fputs("\\bottomrule\n\\endlastfoot\n", fout);
1834+
}
1835+
}
1836+
}
1837+
1838+
/* print cells */
1839+
for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
1840+
{
1841+
/* Add a line under each row? */
1842+
if (i != 0 && i % cont->ncolumns != 0)
1843+
fputs("\n&\n", fout);
1844+
fputs("\\raggedright{", fout);
1845+
latex_escaped_print(*ptr, fout);
1846+
fputc('}', fout);
1847+
if ((i + 1) % cont->ncolumns == 0)
1848+
{
1849+
fputs(" \\tabularnewline\n", fout);
1850+
if (opt_border == 3)
1851+
fputs(" \\hline\n", fout);
1852+
}
1853+
if (cancel_pressed)
1854+
break;
1855+
}
1856+
1857+
if (cont->opt->stop_table)
1858+
fputs("\\end{longtable}\n", fout);
1859+
}
1860+
1861+
17041862
static void
17051863
print_latex_vertical(const printTableContent *cont, FILE *fout)
17061864
{
@@ -2394,6 +2552,12 @@ printTable(const printTableContent *cont, FILE *fout, FILE *flog)
23942552
else
23952553
print_latex_text(cont, fout);
23962554
break;
2555+
case PRINT_LATEX_LONGTABLE:
2556+
if (cont->opt->expanded == 1)
2557+
print_latex_vertical(cont, fout);
2558+
else
2559+
print_latex_text_longtable(cont, fout);
2560+
break;
23972561
case PRINT_TROFF_MS:
23982562
if (cont->opt->expanded == 1)
23992563
print_troff_ms_vertical(cont, fout);

src/bin/psql/print.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ enum printFormat
1919
PRINT_WRAPPED,
2020
PRINT_HTML,
2121
PRINT_LATEX,
22+
PRINT_LATEX_LONGTABLE,
2223
PRINT_TROFF_MS
2324
/* add your favourite output format here ... */
2425
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy