diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index c41593c5e36..504a5164de9 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1890,6 +1890,9 @@ lo_import 152801
into the border=... attribute; in the
other formats only values 0 (no border), 1 (internal dividing lines),
and 2 (table frame) make sense.
+ latex and latex-longtable
+ also support a border value of 3 which adds
+ a dividing line between each row.
@@ -1979,7 +1982,9 @@ lo_import 152801
Sets the output format to one of unaligned,
aligned, wrapped,
html,
- latex, or troff-ms.
+ latex (uses tabular),
+ latex-longtable, or
+ troff-ms.
Unique abbreviations are allowed. (That would mean one letter
is enough.)
@@ -2005,12 +2010,16 @@ lo_import 152801
- The html>, latex>, and troff-ms>
+ The html>, latex>,
+ latex-longtable, and troff-ms>
formats put out tables that are intended to
be included in documents using the respective mark-up
- language. They are not complete documents! (This might not be
- so dramatic in HTML, but in LaTeX you must
- have a complete document wrapper.)
+ language. They are not complete documents! This might not be
+ necessary in HTML, but in
+ LaTeX you must have a complete
+ document wrapper. latex-longtable
+ also requires the LaTeX
+ longtable and booktabs> packages.
@@ -2141,9 +2150,8 @@ lo_import 152801
tableattr (or T)
- Specifies attributes to be placed inside the
- HTML table tag in
- html> output format. This
+ In HTML format, this specifies attributes
+ to be placed inside the table tag. This
could for example be cellpadding or
bgcolor. Note that you probably don't want
to specify border here, as that is already
@@ -2152,6 +2160,13 @@ lo_import 152801
value is given,
the table attributes are unset.
+
+ In latex-longtable format, this controls
+ the proportional width of each column containing a left-aligned
+ data type. It is specified as a space-separated list of values,
+ e.g. '0.2 0.2 0.6'>. Unspecified output columns
+ use the last specified value.
+
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 59f8b035511..740884ff3d8 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2164,6 +2164,9 @@ _align2string(enum printFormat in)
case PRINT_LATEX:
return "latex";
break;
+ case PRINT_LATEX_LONGTABLE:
+ return "latex-longtable";
+ break;
case PRINT_TROFF_MS:
return "troff-ms";
break;
@@ -2197,6 +2200,8 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
popt->topt.format = PRINT_HTML;
else if (pg_strncasecmp("latex", value, vallen) == 0)
popt->topt.format = PRINT_LATEX;
+ else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
+ popt->topt.format = PRINT_LATEX_LONGTABLE;
else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
popt->topt.format = PRINT_TROFF_MS;
else
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 466c255978c..821058d4652 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -1612,8 +1612,8 @@ print_latex_text(const printTableContent *cont, FILE *fout)
if (cancel_pressed)
return;
- if (opt_border > 2)
- opt_border = 2;
+ if (opt_border > 3)
+ opt_border = 3;
if (cont->opt->start_table)
{
@@ -1628,7 +1628,7 @@ print_latex_text(const printTableContent *cont, FILE *fout)
/* begin environment and set alignments and borders */
fputs("\\begin{tabular}{", fout);
- if (opt_border == 2)
+ if (opt_border >= 2)
fputs("| ", fout);
for (i = 0; i < cont->ncolumns; i++)
{
@@ -1636,12 +1636,12 @@ print_latex_text(const printTableContent *cont, FILE *fout)
if (opt_border != 0 && i < cont->ncolumns - 1)
fputs(" | ", fout);
}
- if (opt_border == 2)
+ if (opt_border >= 2)
fputs(" |", fout);
fputs("}\n", fout);
- if (!opt_tuples_only && opt_border == 2)
+ if (!opt_tuples_only && opt_border >= 2)
fputs("\\hline\n", fout);
/* print headers */
@@ -1668,6 +1668,8 @@ print_latex_text(const printTableContent *cont, FILE *fout)
if ((i + 1) % cont->ncolumns == 0)
{
fputs(" \\\\\n", fout);
+ if (opt_border == 3)
+ fputs("\\hline\n", fout);
if (cancel_pressed)
break;
}
@@ -1679,7 +1681,7 @@ print_latex_text(const printTableContent *cont, FILE *fout)
{
printTableFooter *footers = footers_with_default(cont);
- if (opt_border == 2)
+ if (opt_border >= 2)
fputs("\\hline\n", fout);
fputs("\\end{tabular}\n\n\\noindent ", fout);
@@ -1701,6 +1703,162 @@ print_latex_text(const printTableContent *cont, FILE *fout)
}
+static void
+print_latex_text_longtable(const printTableContent *cont, FILE *fout)
+{
+ bool opt_tuples_only = cont->opt->tuples_only;
+ unsigned short opt_border = cont->opt->border;
+ unsigned int i;
+ const char *opt_table_attr = cont->opt->tableAttr;
+ const char *next_opt_table_attr_char = opt_table_attr;
+ const char *last_opt_table_attr_char = NULL;
+ const char *const * ptr;
+
+ if (cancel_pressed)
+ return;
+
+ if (opt_border > 3)
+ opt_border = 3;
+
+ if (cont->opt->start_table)
+ {
+ /* begin environment and set alignments and borders */
+ fputs("\\begin{longtable}{", fout);
+
+ if (opt_border >= 2)
+ fputs("| ", fout);
+
+ for (i = 0; i < cont->ncolumns; i++)
+ {
+ /* longtable supports either a width (p) or an alignment (l/r) */
+ /* Are we left-justified and was a proportional width specified? */
+ if (*(cont->aligns + i) == 'l' && opt_table_attr)
+ {
+#define LONGTABLE_WHITESPACE " \t\n"
+
+ /* advance over whitespace */
+ next_opt_table_attr_char += strspn(next_opt_table_attr_char,
+ LONGTABLE_WHITESPACE);
+ /* We have a value? */
+ if (next_opt_table_attr_char[0] != '\0')
+ {
+ fputs("p{", fout);
+ fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
+ LONGTABLE_WHITESPACE), 1, fout);
+ last_opt_table_attr_char = next_opt_table_attr_char;
+ next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
+ LONGTABLE_WHITESPACE);
+ fputs("\\textwidth}", fout);
+ }
+ /* use previous value */
+ else if (last_opt_table_attr_char != NULL)
+ {
+ fputs("p{", fout);
+ fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
+ LONGTABLE_WHITESPACE), 1, fout);
+ fputs("\\textwidth}", fout);
+ }
+ else
+ fputc('l', fout);
+ }
+ else
+ fputc(*(cont->aligns + i), fout);
+
+ if (opt_border != 0 && i < cont->ncolumns - 1)
+ fputs(" | ", fout);
+ }
+
+ if (opt_border >= 2)
+ fputs(" |", fout);
+
+ fputs("}\n", fout);
+
+ /* print headers */
+ if (!opt_tuples_only)
+ {
+ /* firsthead */
+ if (opt_border >= 2)
+ fputs("\\toprule\n", fout);
+ for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
+ {
+ if (i != 0)
+ fputs(" & ", fout);
+ fputs("\\small\\textbf{\\textit{", fout);
+ latex_escaped_print(*ptr, fout);
+ fputs("}}", fout);
+ }
+ fputs(" \\\\\n", fout);
+ fputs("\\midrule\n\\endfirsthead\n", fout);
+
+ /* secondary heads */
+ if (opt_border >= 2)
+ fputs("\\toprule\n", fout);
+ for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
+ {
+ if (i != 0)
+ fputs(" & ", fout);
+ fputs("\\small\\textbf{\\textit{", fout);
+ latex_escaped_print(*ptr, fout);
+ fputs("}}", fout);
+ }
+ fputs(" \\\\\n", fout);
+ /* If the line under the row already appeared, don't do another */
+ if (opt_border != 3)
+ fputs("\\midrule\n", fout);
+ fputs("\\endhead\n", fout);
+
+ /* table name, caption? */
+ if (!opt_tuples_only && cont->title)
+ {
+ /* Don't output if we are printing a line under each row */
+ if (opt_border == 2)
+ fputs("\\bottomrule\n", fout);
+ fputs("\\caption[", fout);
+ latex_escaped_print(cont->title, fout);
+ fputs(" (Continued)]{", fout);
+ latex_escaped_print(cont->title, fout);
+ fputs("}\n\\endfoot\n", fout);
+ if (opt_border == 2)
+ fputs("\\bottomrule\n", fout);
+ fputs("\\caption[", fout);
+ latex_escaped_print(cont->title, fout);
+ fputs("]{", fout);
+ latex_escaped_print(cont->title, fout);
+ fputs("}\n\\endlastfoot\n", fout);
+ }
+ /* output bottom table line? */
+ else if (opt_border >= 2)
+ {
+ fputs("\\bottomrule\n\\endfoot\n", fout);
+ fputs("\\bottomrule\n\\endlastfoot\n", fout);
+ }
+ }
+ }
+
+ /* print cells */
+ for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
+ {
+ /* Add a line under each row? */
+ if (i != 0 && i % cont->ncolumns != 0)
+ fputs("\n&\n", fout);
+ fputs("\\raggedright{", fout);
+ latex_escaped_print(*ptr, fout);
+ fputc('}', fout);
+ if ((i + 1) % cont->ncolumns == 0)
+ {
+ fputs(" \\tabularnewline\n", fout);
+ if (opt_border == 3)
+ fputs(" \\hline\n", fout);
+ }
+ if (cancel_pressed)
+ break;
+ }
+
+ if (cont->opt->stop_table)
+ fputs("\\end{longtable}\n", fout);
+}
+
+
static void
print_latex_vertical(const printTableContent *cont, FILE *fout)
{
@@ -2394,6 +2552,12 @@ printTable(const printTableContent *cont, FILE *fout, FILE *flog)
else
print_latex_text(cont, fout);
break;
+ case PRINT_LATEX_LONGTABLE:
+ if (cont->opt->expanded == 1)
+ print_latex_vertical(cont, fout);
+ else
+ print_latex_text_longtable(cont, fout);
+ break;
case PRINT_TROFF_MS:
if (cont->opt->expanded == 1)
print_troff_ms_vertical(cont, fout);
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 63ba4a5d08a..9cfa3b6a417 100644
--- a/src/bin/psql/print.h
+++ b/src/bin/psql/print.h
@@ -19,6 +19,7 @@ enum printFormat
PRINT_WRAPPED,
PRINT_HTML,
PRINT_LATEX,
+ PRINT_LATEX_LONGTABLE,
PRINT_TROFF_MS
/* add your favourite output format here ... */
};