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" : "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); }