Valid HTML/XHTML output for psql

From: "Greg Sabino Mullane" <greg(at)turnstep(dot)com>
To: pgsql-patches(at)postgresql(dot)org
Subject: Valid HTML/XHTML output for psql
Date: 2003-06-01 20:45:03
Message-ID: e6b44dcb50a892be66f4d82b9c0e8abd@biglumber.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message

Attached is a patch that enhances the output of psql's HTML mode.
The output now validates as HTML 4.01 Strict, XHTML 1.0 strict,
and XHTML 1.1 (assuming you wrap it in a valid html/body document).

It also wraps the output of PGRES_COMMAND_OK if the HTML tag is on,
for full compliance: this is why html_escaped_print has to be externalized.

--
Greg Sabino Mullane greg(at)turnstep(dot)com
PGP Key: 0x14964AC8 200306011737

Index: common.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/common.c,v
retrieving revision 1.62
diff -c -r1.62 common.c
*** common.c 25 Mar 2003 02:44:36 -0000 1.62
--- common.c 1 Jun 2003 20:34:41 -0000
***************
*** 525,531 ****
success = true;
sprintf(buf, "%u", (unsigned int) PQoidValue(results));
if (!QUIET())
! fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
SetVariable(pset.vars, "LASTOID", buf);
break;
}
--- 525,542 ----
success = true;
sprintf(buf, "%u", (unsigned int) PQoidValue(results));
if (!QUIET())
! {
! if (pset.popt.topt.format == PRINT_HTML)
! {
! fputs("<p>", pset.queryFout);
! html_escaped_print(PQcmdStatus(results), pset.queryFout);
! fputs("</p>\n", pset.queryFout);
! }
! else
! {
! fprintf(pset.queryFout, "%s\n", PQcmdStatus(results));
! }
! }
SetVariable(pset.vars, "LASTOID", buf);
break;
}
Index: print.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
retrieving revision 1.37
diff -c -r1.37 print.c
*** print.c 4 Apr 2003 15:48:38 -0000 1.37
--- print.c 1 Jun 2003 20:34:42 -0000
***************
*** 577,583 ****
/**********************/


! static void
html_escaped_print(const char *in, FILE *fout)
{
const char *p;
--- 577,583 ----
/**********************/


! void
html_escaped_print(const char *in, FILE *fout)
{
const char *p;
***************
*** 595,601 ****
fputs("&gt;", fout);
break;
case '\n':
! fputs("<br>", fout);
break;
default:
fputc(*p, fout);
--- 595,607 ----
fputs("&gt;", fout);
break;
case '\n':
! fputs("<br />\n", fout);
! break;
! case '"':
! fputs("&quot;", fout);
! break;
! case '\'':
! fputs("&apos;", fout);
break;
default:
fputc(*p, fout);
***************
*** 615,621 ****
unsigned int i;
const char *const * ptr;

! fprintf(fout, "<table border=%d", opt_border);
if (opt_table_attr)
fprintf(fout, " %s", opt_table_attr);
fputs(">\n", fout);
--- 621,627 ----
unsigned int i;
const char *const * ptr;

! fprintf(fout, "<table border=\"%d\"", opt_border);
if (opt_table_attr)
fprintf(fout, " %s", opt_table_attr);
fputs(">\n", fout);
***************
*** 636,642 ****
col_count++;
if (!opt_barebones)
{
! fputs(" <th align=center>", fout);
html_escaped_print(*ptr, fout);
fputs("</th>\n", fout);
}
--- 642,648 ----
col_count++;
if (!opt_barebones)
{
! fputs(" <th align=\"center\">", fout);
html_escaped_print(*ptr, fout);
fputs("</th>\n", fout);
}
***************
*** 648,659 ****
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
! fputs(" <tr valign=top>\n", fout);

! fprintf(fout, " <td align=%s>", opt_align[(i) % col_count] == 'r' ? "right" : "left");
! if ((*ptr)[strspn(*ptr, " \t")] == '\0') /* is string only
! * whitespace? */
! fputs("&nbsp;", fout);
else
html_escaped_print(*ptr, fout);
fputs("</td>\n", fout);
--- 654,664 ----
for (i = 0, ptr = cells; *ptr; i++, ptr++)
{
if (i % col_count == 0)
! fputs(" <tr valign=\"top\">\n", fout);

! fprintf(fout, " <td align=\"%s\">", opt_align[(i) % col_count] == 'r' ? "right" : "left");
! if ((*ptr)[strspn(*ptr, " \t")] == '\0') /* is string only whitespace? */
! fputs("&nbsp; ", fout);
else
html_escaped_print(*ptr, fout);
fputs("</td>\n", fout);
***************
*** 666,678 ****

/* print footers */

! if (footers && !opt_barebones)
for (ptr = footers; *ptr; ptr++)
{
html_escaped_print(*ptr, fout);
! fputs("<br>\n", fout);
}
!
fputc('\n', fout);
}

--- 671,686 ----

/* print footers */

! if (!opt_barebones && footers && *footers)
! {
! fputs("<p>", fout);
for (ptr = footers; *ptr; ptr++)
{
html_escaped_print(*ptr, fout);
! fputs("<br />\n", fout);
}
! fputs("</p>", fout);
! }
fputc('\n', fout);
}

***************
*** 690,696 ****
unsigned int record = 1;
const char *const * ptr;

! fprintf(fout, "<table border=%d", opt_border);
if (opt_table_attr)
fprintf(fout, " %s", opt_table_attr);
fputs(">\n", fout);
--- 698,704 ----
unsigned int record = 1;
const char *const * ptr;

! fprintf(fout, "<table border=\"%d\"", opt_border);
if (opt_table_attr)
fprintf(fout, " %s", opt_table_attr);
fputs(">\n", fout);
***************
*** 713,731 ****
if (i % col_count == 0)
{
if (!opt_barebones)
! fprintf(fout, "\n <tr><td colspan=2 align=center>Record %d</td></tr>\n", record++);
else
! fputs("\n <tr><td colspan=2>&nbsp;</td></tr>\n", fout);
}
! fputs(" <tr valign=top>\n"
" <th>", fout);
html_escaped_print(headers[i % col_count], fout);
fputs("</th>\n", fout);

! fprintf(fout, " <td align=%s>", opt_align[i % col_count] == 'r' ? "right" : "left");
! if ((*ptr)[strspn(*ptr, " \t")] == '\0') /* is string only
! * whitespace? */
! fputs("&nbsp;", fout);
else
html_escaped_print(*ptr, fout);
fputs("</td>\n </tr>\n", fout);
--- 721,738 ----
if (i % col_count == 0)
{
if (!opt_barebones)
! fprintf(fout, "\n <tr><td colspan=\"2\" align=\"center\">Record %d</td></tr>\n", record++);
else
! fputs("\n <tr><td colspan=\"2\">&nbsp;</td></tr>\n", fout);
}
! fputs(" <tr valign=\"top\">\n"
" <th>", fout);
html_escaped_print(headers[i % col_count], fout);
fputs("</th>\n", fout);

! fprintf(fout, " <td align=\"%s\">", opt_align[i % col_count] == 'r' ? "right" : "left");
! if ((*ptr)[strspn(*ptr, " \t")] == '\0') /* is string only whitespace? */
! fputs("&nbsp; ", fout);
else
html_escaped_print(*ptr, fout);
fputs("</td>\n </tr>\n", fout);
***************
*** 734,746 ****
fputs("</table>\n", fout);

/* print footers */
! if (footers && !opt_barebones)
for (ptr = footers; *ptr; ptr++)
{
html_escaped_print(*ptr, fout);
! fputs("<br>\n", fout);
}
!
fputc('\n', fout);
}

--- 741,756 ----
fputs("</table>\n", fout);

/* print footers */
! if (!opt_barebones && footers && *footers)
! {
! fputs("<p>", fout);
for (ptr = footers; *ptr; ptr++)
{
html_escaped_print(*ptr, fout);
! fputs("<br />\n", fout);
}
! fputs("</p>", fout);
! }
fputc('\n', fout);
}

***************
*** 1114,1119 ****
--- 1124,1130 ----
char **footers;
char *align;
int i;
+

/* extract headers */

Index: print.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.h,v
retrieving revision 1.16
diff -c -r1.16 print.h
*** print.h 18 Mar 2003 22:15:44 -0000 1.16
--- print.h 1 Jun 2003 20:34:43 -0000
***************
*** 13,18 ****
--- 13,19 ----

extern FILE *PageOutput(int lines, unsigned short int pager);

+ extern void html_escaped_print(const char *in, FILE *fout);

enum printFormat
{

-----BEGIN PGP SIGNATURE-----
Comment: http://www.turnstep.com/pgp.html

iD8DBQE+2nNjvJuQZxSWSsgRAiuWAKCnpa1SzCe6A8i55EXBAIlS0KnspQCdGiWK
H3bbC9FnvDMWQxYOi+vMRGY=
=sLzN
-----END PGP SIGNATURE-----

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Greg Sabino Mullane 2003-06-01 21:17:57 Broken link correction for register.txt
Previous Message Kurt Roeckx 2003-06-01 17:40:52 Ipv6 network cleanup patch #2.