Re: Troff -ms output for psql

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Roger Leigh <rleigh(at)whinlatter(dot)ukfsn(dot)org>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: Troff -ms output for psql
Date: 2004-08-03 01:08:31
Message-ID: 200408030108.i7318Vw13543@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches


This has been saved for the 7.6 release:

http:/momjian.postgresql.org/cgi-bin/pgpatches2

---------------------------------------------------------------------------

Roger Leigh wrote:
> Hello,
>
> I've created a patch which adds support for troff "-ms" output to
> psql. i.e. "\pset format troff-ms". The patch also corrects some
> problems with the "latex" format, notably defining an extra column in
> the output table, and correcting some alignment issues; it also
> changes the output to match the border setting as documented in the
> manual page and as shown with the "aligned" format.
>
> The troff-ms output is mostly identical to the latex output allowing
> for the differences between the two typesetters.
>
> The output should be saved in a file and piped as follows:
>
> cat file | tbl | troff -T ps -ms > file.ps
> or
> tbl file | troff -T ps -ms > file.ps
>
> Because it contains tabs, you'll need to redirect psql output or use
> "script", rather than pasting from a terminal window, due to the tabs
> which can be replaced with spaces.
>
> I've attached the patch (against the current mainline), and example
> output of each for each of border=[123] and expanded mode on and off
> (both source and printable copy).
>
>
> Regards,
> Roger
>
>
> PS. I'm not subscribed, so I would appreciate a CC on any replies.
> Thanks!
>
>
> --
> Roger Leigh
>
> Printing on GNU/Linux? http://gimp-print.sourceforge.net/
> GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.

Content-Description: patch to add troff output to psql

[ text/x-patch is unsupported, treating like TEXT/PLAIN ]

> Index: doc/src/sgml/ref/psql-ref.sgml
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ref/psql-ref.sgml,v
> retrieving revision 1.119
> diff -u -r1.119 psql-ref.sgml
> --- doc/src/sgml/ref/psql-ref.sgml 15 Jul 2004 03:56:04 -0000 1.119
> +++ doc/src/sgml/ref/psql-ref.sgml 1 Aug 2004 17:36:46 -0000
> @@ -1372,9 +1372,10 @@
> <listitem>
> <para>
> Sets the output format to one of <literal>unaligned</literal>,
> - <literal>aligned</literal>, <literal>html</literal>, or
> - <literal>latex</literal>. Unique abbreviations are allowed.
> - (That would mean one letter is enough.)
> + <literal>aligned</literal>, <literal>html</literal>,
> + <literal>latex</literal>, or <literal>troff-ms</literal>.
> + Unique abbreviations are allowed. (That would mean one letter
> + is enough.)
> </para>
>
> <para>
> Index: src/bin/psql/command.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/command.c,v
> retrieving revision 1.122
> diff -u -r1.122 command.c
> --- src/bin/psql/command.c 15 Jul 2004 03:56:06 -0000 1.122
> +++ src/bin/psql/command.c 1 Aug 2004 17:36:53 -0000
> @@ -1307,6 +1307,9 @@
> case PRINT_LATEX:
> return "latex";
> break;
> + case PRINT_TROFF_MS:
> + return "troff-ms";
> + break;
> }
> return "unknown";
> }
> @@ -1335,9 +1338,11 @@
> popt->topt.format = PRINT_HTML;
> else if (pg_strncasecmp("latex", value, vallen) == 0)
> popt->topt.format = PRINT_LATEX;
> + else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
> + popt->topt.format = PRINT_TROFF_MS;
> else
> {
> - psql_error("\\pset: allowed formats are unaligned, aligned, html, latex\n");
> + psql_error("\\pset: allowed formats are unaligned, aligned, html, latex, troff-ms\n");
> return false;
> }
>
> Index: src/bin/psql/print.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
> retrieving revision 1.48
> diff -u -r1.48 print.c
> --- src/bin/psql/print.c 23 May 2004 22:20:10 -0000 1.48
> +++ src/bin/psql/print.c 1 Aug 2004 17:36:56 -0000
> @@ -769,7 +769,7 @@
>
>
> /*************************/
> -/* LaTeX */
> +/* LaTeX */
> /*************************/
>
>
> @@ -790,6 +790,9 @@
> case '$':
> fputs("\\$", fout);
> break;
> + case '_':
> + fputs("\\_", fout);
> + break;
> case '{':
> fputs("\\{", fout);
> break;
> @@ -817,7 +820,6 @@
> {
> unsigned int col_count = 0;
> unsigned int i;
> - const char *cp;
> const char *const * ptr;
>
>
> @@ -829,42 +831,39 @@
> fputs("\n\\end{center}\n\n", fout);
> }
>
> + /* count columns */
> + for (ptr = headers; *ptr; ptr++)
> + col_count++;
> +
> /* begin environment and set alignments and borders */
> fputs("\\begin{tabular}{", fout);
> - if (opt_border == 0)
> - fputs(opt_align, fout);
> - else if (opt_border == 1)
> - {
> - for (cp = opt_align; *cp; cp++)
> - {
> - if (cp != opt_align)
> - fputc('|', fout);
> - fputc(*cp, fout);
> - }
> - }
> - else if (opt_border == 2)
> +
> + if (opt_border == 2)
> + fputs("| ", fout);
> + for (i = 0; i < col_count; i++)
> {
> - for (cp = opt_align; *cp; cp++)
> - {
> - fputc('|', fout);
> - fputc(*cp, fout);
> - }
> - fputc('|', fout);
> + fputc(*(opt_align + i), fout);
> + if (opt_border != 0 && i < col_count - 1)
> + fputs (" | ", fout);
> }
> + if (opt_border == 2)
> + fputs(" |", fout);
> +
> fputs("}\n", fout);
>
> if (!opt_barebones && opt_border == 2)
> fputs("\\hline\n", fout);
>
> /* print headers and count columns */
> - for (i = 0, ptr = headers; *ptr; i++, ptr++)
> + for (i = 0, ptr = headers; i < col_count; i++, ptr++)
> {
> - col_count++;
> if (!opt_barebones)
> {
> if (i != 0)
> fputs(" & ", fout);
> + fputs("\\textit{", fout);
> latex_escaped_print(*ptr, fout);
> + fputc('}', fout);
> }
> }
>
> @@ -888,7 +887,7 @@
> if (opt_border == 2)
> fputs("\\hline\n", fout);
>
> - fputs("\\end{tabular}\n\n", fout);
> + fputs("\\end{tabular}\n\n\\noindent ", fout);
>
>
> /* print footers */
> @@ -951,8 +950,12 @@
> if (!opt_barebones)
> {
> if (opt_border == 2)
> + {
> fputs("\\hline\n", fout);
> - fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
> + fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
> + }
> + else
> + fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
> }
> if (opt_border >= 1)
> fputs("\\hline\n", fout);
> @@ -967,7 +970,7 @@
> if (opt_border == 2)
> fputs("\\hline\n", fout);
>
> - fputs("\\end{tabular}\n\n", fout);
> + fputs("\\end{tabular}\n\n\\noindent ", fout);
>
>
> /* print footers */
> @@ -984,6 +987,213 @@
>
>
>
> +/*************************/
> +/* Troff -ms */
> +/*************************/
> +
> +
> +static void
> +troff_ms_escaped_print(const char *in, FILE *fout)
> +{
> + const char *p;
> +
> + for (p = in; *p; p++)
> + switch (*p)
> + {
> + case '\\':
> + fputs("\(rs", fout);
> + break;
> + default:
> + fputc(*p, fout);
> + }
> +}
> +
> +
> +
> +static void
> +print_troff_ms_text(const char *title, const char *const * headers,
> + const char *const * cells, const char *const * footers,
> +const char *opt_align, bool opt_barebones, unsigned short int opt_border,
> + FILE *fout)
> +{
> + unsigned int col_count = 0;
> + unsigned int i;
> + const char *const * ptr;
> +
> +
> + /* print title */
> + if (!opt_barebones && title)
> + {
> + fputs(".LP\n.DS C\n", fout);
> + troff_ms_escaped_print(title, fout);
> + fputs("\n.DE\n", fout);
> + }
> +
> + /* count columns */
> + for (ptr = headers; *ptr; ptr++)
> + col_count++;
> +
> + /* begin environment and set alignments and borders */
> + fputs(".LP\n.TS\n", fout);
> + if (opt_border == 2)
> + fputs("center box;\n", fout);
> + else
> + fputs("center;\n", fout);
> +
> + for (i = 0; i < col_count; i++)
> + {
> + fputc(*(opt_align + i), fout);
> + if (opt_border > 0 && i < col_count - 1)
> + fputs(" | ", fout);
> + }
> + fputs(".\n", fout);
> +
> + /* print headers and count columns */
> + for (i = 0, ptr = headers; i < col_count; i++, ptr++)
> + {
> + if (!opt_barebones)
> + {
> + if (i != 0)
> + fputc('\t', fout);
> + fputs("\\fI", fout);
> + troff_ms_escaped_print(*ptr, fout);
> + fputs("\\fP", fout);
> + }
> + }
> +
> + if (!opt_barebones)
> + {
> + fputs("\n_\n", fout);
> + }
> +
> + /* print cells */
> + for (i = 0, ptr = cells; *ptr; i++, ptr++)
> + {
> + troff_ms_escaped_print(*ptr, fout);
> +
> + if ((i + 1) % col_count == 0)
> + fputc('\n', fout);
> + else
> + fputc('\t', fout);
> + }
> +
> + fputs(".TE\n.DS L\n", fout);
> +
> +
> + /* print footers */
> +
> + if (footers && !opt_barebones)
> + for (ptr = footers; *ptr; ptr++)
> + {
> + troff_ms_escaped_print(*ptr, fout);
> + fputc('\n', fout);
> + }
> +
> + fputs(".DE\n", fout);
> +}
> +
> +
> +
> +static void
> +print_troff_ms_vertical(const char *title, const char *const * headers,
> + const char *const * cells, const char *const * footers,
> +const char *opt_align, bool opt_barebones, unsigned short int opt_border,
> + FILE *fout)
> +{
> + unsigned int col_count = 0;
> + unsigned int i;
> + const char *const * ptr;
> + unsigned int record = 1;
> + unsigned short current_format = 0; /* 0=none, 1=header, 2=body */
> +
> + (void) opt_align; /* currently unused parameter */
> +
> + /* print title */
> + if (!opt_barebones && title)
> + {
> + fputs(".LP\n.DS C\n", fout);
> + troff_ms_escaped_print(title, fout);
> + fputs("\n.DE\n", fout);
> + }
> +
> + /* begin environment and set alignments and borders */
> + fputs(".LP\n.TS\n", fout);
> + if (opt_border == 2)
> + fputs("center box;\n", fout);
> + else
> + fputs("center;\n", fout);
> +
> + /* basic format */
> + if (opt_barebones)
> + fputs("c l;\n", fout);
> +
> +
> + /* count columns */
> + for (ptr = headers; *ptr; ptr++)
> + col_count++;
> +
> +
> + /* print records */
> + for (i = 0, ptr = cells; *ptr; i++, ptr++)
> + {
> + /* new record */
> + if (i % col_count == 0)
> + {
> + if (!opt_barebones)
> + {
> +
> + if (current_format != 1)
> + {
> + if (opt_border == 2 && i > 0)
> + fputs("_\n", fout);
> + if (current_format != 0)
> + fputs(".T&\n", fout);
> + fputs("c s.\n", fout);
> + current_format = 1;
> + }
> + fprintf(fout, "\\fIRecord %d\\fP\n", record++);
> + }
> + if (opt_border >= 1)
> + fputs("_\n", fout);
> + }
> +
> + if (!opt_barebones)
> + {
> + if (current_format != 2)
> + {
> + if (current_format != 0)
> + fputs(".T&\n", fout);
> + if (opt_border != 1)
> + fputs("c l.\n", fout);
> + else
> + fputs("c | l.\n", fout);
> + current_format = 2;
> + }
> + }
> +
> + troff_ms_escaped_print(headers[i % col_count], fout);
> + fputc('\t', fout);
> + troff_ms_escaped_print(*ptr, fout);
> + fputc('\n', fout);
> + }
> +
> + fputs(".TE\n.DS L\n", fout);
> +
> +
> + /* print footers */
> +
> + if (footers && !opt_barebones)
> + for (ptr = footers; *ptr; ptr++)
> + {
> + troff_ms_escaped_print(*ptr, fout);
> + fputc('\n', fout);
> + }
> +
> + fputs(".DE\n", fout);
> +}
> +
> +
> +
> /********************************/
> /* Public functions */
> /********************************/
> @@ -1113,6 +1323,12 @@
> else
> print_latex_text(title, headers, cells, footers, align, opt->tuples_only, border, output);
> break;
> + case PRINT_TROFF_MS:
> + if (opt->expanded)
> + print_troff_ms_vertical(title, headers, cells, footers, align, opt->tuples_only, border, output);
> + else
> + print_troff_ms_text(title, headers, cells, footers, align, opt->tuples_only, border, output);
> + break;
> default:
> fprintf(stderr, "+ Oops, you shouldn't see this!\n");
> }
> Index: src/bin/psql/print.h
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.h,v
> retrieving revision 1.20
> diff -u -r1.20 print.h
> --- src/bin/psql/print.h 29 Nov 2003 19:52:07 -0000 1.20
> +++ src/bin/psql/print.h 1 Aug 2004 17:36:56 -0000
> @@ -21,7 +21,8 @@
> PRINT_UNALIGNED,
> PRINT_ALIGNED,
> PRINT_HTML,
> - PRINT_LATEX
> + PRINT_LATEX,
> + PRINT_TROFF_MS
> /* add your favourite output format here ... */
> };
>

Content-Description: Troff -ms generated source

[ Attachment, skipping... ]

Content-Description: Troff -ms postscript output

[ Attachment, skipping... ]

Content-Description: LaTeX generated source

[ Attachment, skipping... ]

Content-Description: LaTeX PDF output

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
> (send "unregister YourEmailAddressHere" to majordomo(at)postgresql(dot)org)

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2004-08-03 01:09:14 Re: psql latex bugfixes
Previous Message Tom Lane 2004-08-02 23:26:11 Re: autovauum integration patch: Attempt #4