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 [EMAIL PROTECTED]) -- Bruce Momjian | http://candle.pha.pa.us [EMAIL PROTECTED] | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 ---------------------------(end of broadcast)--------------------------- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]