Hi, I've been working a little bit on a patch for printing tables in asciidoc with psql.
It's not finished yet, I'm not sure it there is any sense in supporting border types etc. The code is not cleared so far, but any remarks on the style not playing well with the normal postgres style of code are welcomed. The code just works. With extended and normal modes. With table columns made of funny characters, with alignment of data in table cells. I was trying to implement it similar to the html export function, however escaping of the strings was much easier, as the normal html-way substitution is not easy to implement in asciidoc. I'd like to ask you for any advices for this code. thanks, Szymon
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 2227db4..ae6b106 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -2247,6 +2247,9 @@ _align2string(enum printFormat in) case PRINT_TROFF_MS: return "troff-ms"; break; + case PRINT_ASCIIDOC: + return "asciidoc"; + break; } return "unknown"; } @@ -2316,9 +2319,11 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.format = PRINT_LATEX_LONGTABLE; else if (pg_strncasecmp("troff-ms", value, vallen) == 0) popt->topt.format = PRINT_TROFF_MS; + else if (pg_strncasecmp("asciidoc", value, vallen) == 0) + popt->topt.format = PRINT_ASCIIDOC; else { - psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms\n"); + psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms, asciidoc\n"); return false; } diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 3b3c3b7..236c8f3 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -2475,6 +2475,180 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout) } } +/*********************/ +/* ASCIIDOC **********/ +/*********************/ + +static void +print_asciidoc_text(const printTableContent *cont, FILE *fout) +{ + bool opt_tuples_only = cont->opt->tuples_only; + unsigned int i; + const char *const * ptr; + + if (cancel_pressed) + return; + + if (cont->opt->start_table) + { + /* print title */ + if (!opt_tuples_only && cont->title) + { + fputs(".", fout); + fputs(cont->title, fout); + fputs("\n", fout); + } + + /* print table [] header definition */ + fprintf(fout, "[options=\"header\",cols=\""); + for(i = 0; i < cont->ncolumns; i++) { + if (i != 0) fputs(",", fout); + fprintf(fout, "%s", cont->aligns[(i) % cont->ncolumns] == 'r' ? ">literal" : "<literal"); + } + fprintf(fout, "\"]\n"); + fprintf(fout, "|====\n"); + + /* print headers */ + if (!opt_tuples_only) + { + for (ptr = cont->headers; *ptr; ptr++) + { + fputs("^| +++", fout); + fputs(*ptr, fout); + fputs("+++ ", fout); + } + fputs("\n", fout); + } + } + + /* print cells */ + for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) + { + if (i % cont->ncolumns == 0) + { + if (cancel_pressed) + break; + } + + fprintf(fout, "| "); + + if ((*ptr)[strspn(*ptr, " \t")] == '\0') + fputs(" ", fout); + else + fputs(*ptr, fout); + + fputs(" ", fout); + + if ((i + 1) % cont->ncolumns == 0) + fputs("\n", fout); + + + } + + fprintf(fout, "|====\n"); + + if (cont->opt->stop_table) + { + printTableFooter *footers = footers_with_default(cont); + + /* print footers */ + if (!opt_tuples_only && footers != NULL && !cancel_pressed) + { + printTableFooter *f; + + fputs("\n....\n", fout); + for (f = footers; f; f = f->next) + { + fputs(f->data, fout); + fputs("\n", fout); + } + fputs("....\n", fout); + } + + } +} + +// TODO add support for cont->opt->border +// TODO add support for additional options + +static void +print_asciidoc_vertical(const printTableContent *cont, FILE *fout) +{ + bool opt_tuples_only = cont->opt->tuples_only; + unsigned short opt_border = cont->opt->border; + const char *opt_table_attr = cont->opt->tableAttr; + unsigned long record = cont->opt->prior_records + 1; + unsigned int i; + const char *const * ptr; + + if (cancel_pressed) + return; + + if (cont->opt->start_table) + { + /* print title */ + if (!opt_tuples_only && cont->title) + { + fputs(".", fout); + fputs(cont->title, fout); + fputs("\n", fout); + } + + /* print table [] header definition */ + fprintf(fout, "[cols=\"h,literal\"]\n"); + fprintf(fout, "|====\n"); + + } + + /* print records */ + for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) + { + if (i % cont->ncolumns == 0) + { + if (cancel_pressed) + break; + if (!opt_tuples_only) + fprintf(fout, + "2+^| Record %lu\n", + record++); + else + fputs("2| \n", fout); + } + + fputs("|+++", fout); + fputs(cont->headers[i % cont->ncolumns], fout); + fputs("+++", fout); + + fprintf(fout, " %s|", cont->aligns[i % cont->ncolumns] == 'r' ? ">" : "<"); + /* is string only whitespace? */ + if ((*ptr)[strspn(*ptr, " \t")] == '\0') + fputs(" ", fout); + else + fputs(*ptr, fout); + + fputs("\n", fout); + } + + fprintf(fout, "|====\n"); + + if (cont->opt->stop_table) + { + /* print footers */ + if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed) + { + printTableFooter *f; + + fputs("\n....\n", fout); + for (f = cont->footers; f; f = f->next) + { + fputs(f->data, fout); + fputs("\n", fout); + } + fputs("....\n", fout); + } + + } +} /********************************/ /* Public functions */ @@ -2872,6 +3046,12 @@ printTable(const printTableContent *cont, FILE *fout, FILE *flog) else print_troff_ms_text(cont, fout); break; + case PRINT_ASCIIDOC: + if (cont->opt->expanded == 1) + print_asciidoc_vertical(cont, fout); + else + print_asciidoc_text(cont, fout); + break; default: fprintf(stderr, _("invalid output format (internal error): %d"), cont->opt->format); @@ -3100,3 +3280,5 @@ strlen_max_width(unsigned char *str, int *target_width, int encoding) return str - start; } + + diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index f668b23..cf885ad 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -20,7 +20,8 @@ enum printFormat PRINT_HTML, PRINT_LATEX, PRINT_LATEX_LONGTABLE, - PRINT_TROFF_MS + PRINT_TROFF_MS, + PRINT_ASCIIDOC /* add your favourite output format here ... */ }; diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index b80fe13..a0c5230 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3633,7 +3633,7 @@ psql_completion(const char *text, int start, int end) { static const char *const my_list[] = {"unaligned", "aligned", "wrapped", "html", "latex", - "troff-ms", NULL}; + "troff-ms", "asciidoc", NULL}; COMPLETE_WITH_LIST_CS(my_list); }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers