2017-03-27 19:41 GMT+02:00 Jan Michálek <godzilalal...@gmail.com>: > > > 2017-03-23 17:26 GMT+01:00 Pierre Ducroquet <p.p...@pinaraf.info>: > >> The following review has been posted through the commitfest application: >> make installcheck-world: tested, passed >> Implements feature: tested, passed >> Spec compliant: tested, passed >> Documentation: tested, passed >> >> Hi >> >> This is my first review (Magnus said in his presentation in PGDay Paris >> that volunteers should just come and help, so here I am), so please notify >> me for any mistake I do when using the review tools... >> >> The feature seems to work as expected, but I don't claim to be a markdown >> and rst expert. >> Some minor issues with the code itself : >> - some indentation issues (documentation and code itself with mix between >> space based and tab based indentation) and a few trailing spaces in code >> > > corrected > > >> - typographic issues in the documentation : >> - "The html, asciidoc, latex, latex-longtable, troff-ms, and markdown >> and rst formats" ==> duplicated and >> > > corrected > >> - "Sets the output format to one of unaligned, aligned, wrapped, html, >> asciidoc, latex (uses tabular), latex-longtable, rst, markdown, or >> troff-ms." ==> extra comma at the end of the list >> - the comment " dont add line after last row, because line is added after >> every row" is misleading, it should warn that it's only for rst >> - there is a block of commented out code left >> - in the print_aligned_vertical function, there is a mix between >> "cont->opt->format == PRINT_RST" and "format == &pg_rst" and I don't see >> any obvious reason for that >> > corrected > >> - the documentation doesn't mention (but ok, it's kind of obvious) that >> the linestyle option will not work with rst and markdown >> >> > In this patch are corrected (i hope, i had correct changes in vimrc) > indentation issues. Plese, look at this if it is OK (i men indentats) and > some minor errors. And it should work on current master (probably). >
Added \x option form markdown In markdown works multiline cels (newline replaced by </br>) regre tests passed Jan > > Have nice day > > Jan > > >> Thanks ! >> >> The new status of this patch is: Waiting on Author >> >> -- >> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) >> To make changes to your subscription: >> http://www.postgresql.org/mailpref/pgsql-hackers >> > > > > -- > Jelen > Starší čeledín datovýho chlíva > -- Jelen Starší čeledín datovýho chlíva
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 2a9c412020..ee0c8fbea6 100644 *** a/doc/src/sgml/ref/psql-ref.sgml --- b/doc/src/sgml/ref/psql-ref.sgml *************** *** 2366,2372 **** lo_import 152801 <literal>aligned</literal>, <literal>wrapped</literal>, <literal>html</literal>, <literal>asciidoc</literal>, <literal>latex</literal> (uses <literal>tabular</literal>), ! <literal>latex-longtable</literal>, or <literal>troff-ms</literal>. Unique abbreviations are allowed. (That would mean one letter is enough.) --- 2366,2373 ---- <literal>aligned</literal>, <literal>wrapped</literal>, <literal>html</literal>, <literal>asciidoc</literal>, <literal>latex</literal> (uses <literal>tabular</literal>), ! <literal>latex-longtable</literal>, ! <literal>rst</literal>, <literal>markdown</literal>, or <literal>troff-ms</literal>. Unique abbreviations are allowed. (That would mean one letter is enough.) *************** *** 2394,2400 **** lo_import 152801 <para> The <literal>html</>, <literal>asciidoc</>, <literal>latex</>, ! <literal>latex-longtable</literal>, and <literal>troff-ms</> formats put out tables that are intended to be included in documents using the respective mark-up language. They are not complete documents! This might not be --- 2395,2402 ---- <para> The <literal>html</>, <literal>asciidoc</>, <literal>latex</>, ! <literal>latex-longtable</literal>, <literal>troff-ms</>, ! <literal>markdown</> and <literal>rst</> formats put out tables that are intended to be included in documents using the respective mark-up language. They are not complete documents! This might not be diff --git a/src/bin/psql/command.c bindex 4f4a0aa9bd..97f4f37923 100644 *** a/src/bin/psql/command.c --- b/src/bin/psql/command.c *************** *** 2518,2523 **** _align2string(enum printFormat in) --- 2518,2529 ---- case PRINT_TROFF_MS: return "troff-ms"; break; + case PRINT_MARKDOWN: + return "markdown"; + break; + case PRINT_RST: + return "rst"; + break; } return "unknown"; } *************** *** 2589,2597 **** 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 { ! psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n"); return false; } } --- 2595,2607 ---- 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("markdown", value, vallen) == 0) + popt->topt.format = PRINT_MARKDOWN; + else if (pg_strncasecmp("rst", value, vallen) == 0) + popt->topt.format = PRINT_RST; else { ! psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms, markdown, rst\n"); return false; } } diff --git a/src/bin/psql/helindex ba14df0344..d9dc5e10d9 100644 *** a/src/bin/psql/help.c --- b/src/bin/psql/help.c *************** *** 375,381 **** helpVariables(unsigned short int pager) fprintf(output, _(" fieldsep field separator for unaligned output (default \"%s\")\n"), DEFAULT_FIELD_SEP); fprintf(output, _(" fieldsep_zero set field separator for unaligned output to zero byte\n")); fprintf(output, _(" footer enable or disable display of the table footer [on, off]\n")); ! fprintf(output, _(" format set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n")); fprintf(output, _(" linestyle set the border line drawing style [ascii, old-ascii, unicode]\n")); fprintf(output, _(" null set the string to be printed in place of a null value\n")); fprintf(output, _(" numericlocale enable or disable display of a locale-specific character to separate\n" --- 375,381 ---- fprintf(output, _(" fieldsep field separator for unaligned output (default \"%s\")\n"), DEFAULT_FIELD_SEP); fprintf(output, _(" fieldsep_zero set field separator for unaligned output to zero byte\n")); fprintf(output, _(" footer enable or disable display of the table footer [on, off]\n")); ! fprintf(output, _(" format set output format [unaligned, aligned, wrapped, html, asciidoc, rst, markdown ...]\n")); fprintf(output, _(" linestyle set the border line drawing style [ascii, old-ascii, unicode]\n")); fprintf(output, _(" null set the string to be printed in place of a null value\n")); fprintf(output, _(" numericlocale enable or disable display of a locale-specific character to separate\n" diff --git a/src/bin/psql/index f7494065de..ea14ec3d28 100644 *** a/src/bin/psql/tab-complete.c --- b/src/bin/psql/tab-complete.c *************** *** 3422,3428 **** psql_completion(const char *text, int start, int end) { static const char *const my_list[] = {"unaligned", "aligned", "wrapped", "html", "asciidoc", ! "latex", "latex-longtable", "troff-ms", NULL}; COMPLETE_WITH_LIST_CS(my_list); } --- 3422,3428 ---- { static const char *const my_list[] = {"unaligned", "aligned", "wrapped", "html", "asciidoc", ! "latex", "latex-longtable", "troff-ms", "markdown", "rst", NULL}; COMPLETE_WITH_LIST_CS(my_list); } diff --git a/src/fe_utils/mbprint.index d186fc4c91..a2b030e2f7 100644 *** a/src/fe_utils/mbprint.c --- b/src/fe_utils/mbprint.c *************** *** 285,290 **** pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, --- 285,368 ---- } /* + * version of pg_wcssize for markdown + * replace newline with </br> + */ + void + pg_wcssize_newline(const unsigned char *pwcs, size_t len, int encoding, + int *result_width, int *result_height, int *result_format_size) + { + int w, + chlen = 0, + linewidth = 0; + int width = 0; + int height = 1; + int format_size = 0; + + for (; *pwcs && len > 0; pwcs += chlen) + { + chlen = PQmblen((const char *) pwcs, encoding); + if (len < (size_t) chlen) + break; + w = PQdsplen((const char *) pwcs, encoding); + + if (chlen == 1) /* single-byte char */ + { + if (*pwcs == '\n') /* Newline */ + { + linewidth += 5; + format_size += 5; + } + else if (*pwcs == '\r') /* Linefeed */ + { + linewidth += 2; + format_size += 2; + } + else if (*pwcs == '\t') /* Tab */ + { + do + { + linewidth++; + format_size++; + } while (linewidth % 8 != 0); + } + else if (w < 0) /* Other control char */ + { + linewidth += 4; + format_size += 4; + } + else /* Output it as-is */ + { + linewidth += w; + format_size += 1; + } + } + else if (w < 0) /* Non-ascii control char */ + { + linewidth += 6; /* \u0000 */ + format_size += 6; + } + else /* All other chars */ + { + linewidth += w; + format_size += chlen; + } + len -= chlen; + } + if (linewidth > width) + width = linewidth; + format_size += 1; /* For NUL char */ + + /* Set results */ + if (result_width) + *result_width = width; + if (result_height) + *result_height = height; + if (result_format_size) + *result_format_size = format_size; + } + + /* * Format a string into one or more "struct lineptr" lines. * lines[i].ptr == NULL indicates the end of the array. * *************** *** 382,387 **** pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, --- 460,555 ---- (lines + 1)->ptr = NULL; /* terminate line array */ } + /* + * version of pg_wcsformat for markdown + * replace newline with </br> + */ + + void + pg_wcsformat_newline(const unsigned char *pwcs, size_t len, int encoding, + struct lineptr * lines, int count) + { + int w, + chlen = 0; + int linewidth = 0; + unsigned char *ptr = lines->ptr; /* Pointer to data area */ + + for (; *pwcs && len > 0; pwcs += chlen) + { + chlen = PQmblen((const char *) pwcs, encoding); + if (len < (size_t) chlen) + break; + w = PQdsplen((const char *) pwcs, encoding); + + if (chlen == 1) /* single-byte char */ + { + if (*pwcs == '\n') /* Newline */ + { + strcpy((char *) ptr, "</br>"); + linewidth += 5; + ptr += 5; + } + else if (*pwcs == '\r') /* Linefeed */ + { + strcpy((char *) ptr, "\\r"); + linewidth += 2; + ptr += 2; + } + else if (*pwcs == '\t') /* Tab */ + { + do + { + *ptr++ = ' '; + linewidth++; + } while (linewidth % 8 != 0); + } + else if (w < 0) /* Other control char */ + { + sprintf((char *) ptr, "\\x%02X", *pwcs); + linewidth += 4; + ptr += 4; + } + else /* Output it as-is */ + { + linewidth += w; + *ptr++ = *pwcs; + } + } + else if (w < 0) /* Non-ascii control char */ + { + if (encoding == PG_UTF8) + sprintf((char *) ptr, "\\u%04X", utf8_to_unicode(pwcs)); + else + { + /* + * This case cannot happen in the current code because only + * UTF-8 signals multibyte control characters. But we may need + * to support it at some stage + */ + sprintf((char *) ptr, "\\u????"); + } + ptr += 6; + linewidth += 6; + } + else /* All other chars */ + { + int i; + + for (i = 0; i < chlen; i++) + *ptr++ = pwcs[i]; + linewidth += w; + } + len -= chlen; + } + lines->width = linewidth; + *ptr++ = '\0'; /* Terminate formatted string */ + + if (count <= 0) + exit(1); /* Screwup */ + + (lines + 1)->ptr = NULL; /* terminate line array */ + } + /* * Encoding validation: delete any unvalidatable characters from the string diff --git a/src/fe_utils/priindex 9180b90004..735d3973ce 100644 *** a/src/fe_utils/print.c --- b/src/fe_utils/print.c *************** *** 56,61 **** static char default_footer[100]; --- 56,104 ---- static printTableFooter default_footer_cell = {default_footer, NULL}; /* Line style control structures */ + + const printTextFormat pg_markdown = + { + "markdown", + { + {"", "", "", ""}, + {"-", "|", "|", "|"}, + {"", "", "", ""}, + {" ", "|", "|", "|"} + }, + "|", + "|", + "|", + " ", + "+", + " ", + " ", + ".", + ".", + true + }; + + const printTextFormat pg_rst = + { + "rst", + { + {"-", "+", "+", "+"}, + {"=", "+", "+", "+"}, + {"-", "+", "+", "+"}, + {" ", "|", "|", "|"} + }, + "|", + "|", + "|", + " ", + "+", + " ", + " ", + ".", + ".", + true + }; + const printTextFormat pg_asciiformat = { "ascii", *************** *** 205,210 **** static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool e --- 248,255 ---- static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager); + static void skip_leading_spaces_print(const char *in, FILE *fout); + /* Count number of digits in integral part of number */ static int *************** *** 574,579 **** _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, --- 619,655 ---- fputc('\n', fout); } + /* + * skip leading spaces + */ + static void + skip_leading_spaces_print(const char *in, FILE *fout) + { + const char *p; + bool leading_space = true; + unsigned int spac; /**leading spaces*/ + spac = 0; + + for (p = in; *p; p++) + { + if (*p != ' ' && *p != '\n') + { + leading_space = false; + fputc(*p, fout); + } + else if (*p == '\n') + { + fputc(*p, fout); + leading_space = true; + } + else if (leading_space) + spac++; + else + fputc(*p, fout); + } + if (spac != 0) + fprintf(fout, "%*s", spac, " "); + } /* * Print pretty boxes around cells. *************** *** 622,627 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) --- 698,709 ---- if (opt_border > 2) opt_border = 2; + if (format == &pg_markdown) + opt_border = 2; + + if (format == &pg_rst) + opt_border = 2; + if (cont->ncolumns > 0) { col_count = cont->ncolumns; *************** *** 661,668 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) nl_lines, bytes_required; ! pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]), ! encoding, &width, &nl_lines, &bytes_required); if (width > max_width[i]) max_width[i] = width; if (nl_lines > max_nl_lines[i]) --- 743,754 ---- nl_lines, bytes_required; ! if (format != &pg_markdown) ! pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]), ! encoding, &width, &nl_lines, &bytes_required); ! else ! pg_wcssize_newline((const unsigned char *) cont->headers[i], strlen(cont->headers[i]), ! encoding, &width, &nl_lines, &bytes_required); if (width > max_width[i]) max_width[i] = width; if (nl_lines > max_nl_lines[i]) *************** *** 685,692 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) nl_lines, bytes_required; ! pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &nl_lines, &bytes_required); if (width > max_width[i % col_count]) max_width[i % col_count] = width; --- 771,782 ---- nl_lines, bytes_required; ! if (format != &pg_markdown) ! pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &nl_lines, &bytes_required); ! else ! pg_wcssize_newline((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &nl_lines, &bytes_required); if (width > max_width[i % col_count]) max_width[i % col_count] = width; *************** *** 846,853 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) nl_lines, bytes_required; ! pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &nl_lines, &bytes_required); /* * A row can have both wrapping and newlines that cause it to --- 936,947 ---- nl_lines, bytes_required; ! if (format != &pg_markdown) ! pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &nl_lines, &bytes_required); ! else ! pg_wcssize_newline((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &nl_lines, &bytes_required); /* * A row can have both wrapping and newlines that cause it to *************** *** 885,892 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) int width, height; ! pg_wcssize((const unsigned char *) cont->title, strlen(cont->title), ! encoding, &width, &height, NULL); if (width >= width_total) /* Aligned */ fprintf(fout, "%s\n", cont->title); --- 979,990 ---- int width, height; ! if (format != &pg_markdown) ! pg_wcssize((const unsigned char *) cont->title, strlen(cont->title), ! encoding, &width, &height, NULL); ! else ! pg_wcssize_newline((const unsigned char *) cont->title, strlen(cont->title), ! encoding, &width, &height, NULL); if (width >= width_total) /* Aligned */ fprintf(fout, "%s\n", cont->title); *************** *** 907,915 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) PRINT_RULE_TOP, format, fout); for (i = 0; i < col_count; i++) ! pg_wcsformat((const unsigned char *) cont->headers[i], ! strlen(cont->headers[i]), encoding, ! col_lineptrs[i], max_nl_lines[i]); more_col_wrapping = col_count; curr_nl_line = 0; --- 1005,1018 ---- PRINT_RULE_TOP, format, fout); for (i = 0; i < col_count; i++) ! if (format != &pg_markdown) ! pg_wcsformat((const unsigned char *) cont->headers[i], ! strlen(cont->headers[i]), encoding, ! col_lineptrs[i], max_nl_lines[i]); ! else ! pg_wcsformat_newline((const unsigned char *) cont->headers[i], ! strlen(cont->headers[i]), encoding, ! col_lineptrs[i], max_nl_lines[i]); more_col_wrapping = col_count; curr_nl_line = 0; *************** *** 978,985 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) */ for (j = 0; j < col_count; j++) { ! pg_wcsformat((const unsigned char *) ptr[j], strlen(ptr[j]), encoding, ! col_lineptrs[j], max_nl_lines[j]); curr_nl_line[j] = 0; } --- 1081,1092 ---- */ for (j = 0; j < col_count; j++) { ! if (format != &pg_markdown) ! pg_wcsformat((const unsigned char *) ptr[j], strlen(ptr[j]), encoding, ! col_lineptrs[j], max_nl_lines[j]); ! else ! pg_wcsformat_newline((const unsigned char *) ptr[j], strlen(ptr[j]), encoding, ! col_lineptrs[j], max_nl_lines[j]); curr_nl_line[j] = 0; } *************** *** 1052,1060 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) else /* Left aligned cell */ { /* spaces second */ ! fputnbytes(fout, ! (char *) (this_line->ptr + bytes_output[j]), ! bytes_to_output); } bytes_output[j] += bytes_to_output; --- 1159,1170 ---- else /* Left aligned cell */ { /* spaces second */ ! if (format != &pg_rst) ! fputnbytes(fout, ! (char *) (this_line->ptr + bytes_output[j]), ! bytes_to_output); ! else ! skip_leading_spaces_print((char *) (this_line->ptr + bytes_output[j]), fout); } bytes_output[j] += bytes_to_output; *************** *** 1123,1142 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) fputc('\n', fout); } while (more_lines); } if (cont->opt->stop_table) { printTableFooter *footers = footers_with_default(cont); ! if (opt_border == 2 && !cancel_pressed) _print_horizontal_line(col_count, width_wrap, opt_border, ! PRINT_RULE_BOTTOM, format, fout); /* print footers */ if (footers && !opt_tuples_only && !cancel_pressed) { printTableFooter *f; for (f = footers; f; f = f->next) fprintf(fout, "%s\n", f->data); --- 1233,1266 ---- fputc('\n', fout); } while (more_lines); + + if (format == &pg_rst) + _print_horizontal_line(col_count, width_wrap, opt_border, + PRINT_RULE_BOTTOM, format, fout); } if (cont->opt->stop_table) { printTableFooter *footers = footers_with_default(cont); ! if ((opt_border == 2 && format != &pg_rst) && !cancel_pressed) ! /* ! * dont add line after last row, because line is added after every row ! */ _print_horizontal_line(col_count, width_wrap, opt_border, ! PRINT_RULE_BOTTOM, format, fout); /* print footers */ if (footers && !opt_tuples_only && !cancel_pressed) { printTableFooter *f; + /* + * add newline after table because rst needs empty line after table + */ + if (format == &pg_rst || format == &pg_markdown) + { + fprintf(fout, "\n"); + } for (f = footers; f; f = f->next) fprintf(fout, "%s\n", f->data); *************** *** 1192,1197 **** print_aligned_vertical_line(const printTextFormat *format, --- 1316,1325 ---- { if (opt_border == 0) reclen = fprintf(fout, "* Record %lu", record); + else if (format == &pg_rst) + reclen = fprintf(fout, "**RECORD %lu**", record); + else if (format == &pg_markdown) + reclen = fprintf(fout, "**RECORD %lu**", record); else reclen = fprintf(fout, "[ RECORD %lu ]", record); } *************** *** 1257,1262 **** print_aligned_vertical(const printTableContent *cont, --- 1385,1393 ---- if (opt_border > 2) opt_border = 2; + if (format == &pg_rst || format == &pg_markdown) /*rst works only with border 2*/ + opt_border = 2; + if (cont->cells[0] == NULL && cont->opt->start_table && cont->opt->stop_table) { *************** *** 1293,1300 **** print_aligned_vertical(const printTableContent *cont, height, fs; ! pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]), ! encoding, &width, &height, &fs); if (width > hwidth) hwidth = width; if (height > hheight) --- 1424,1436 ---- height, fs; ! if (format != &pg_markdown) ! pg_wcssize((const unsigned char *) cont->headers[i], strlen(cont->headers[i]), ! encoding, &width, &height, &fs); ! else ! pg_wcssize_newline((const unsigned char *) cont->headers[i], strlen(cont->headers[i]), ! encoding, &width, &height, &fs); ! if (width > hwidth) hwidth = width; if (height > hheight) *************** *** 1305,1310 **** print_aligned_vertical(const printTableContent *cont, --- 1441,1453 ---- if (fs > hformatsize) hformatsize = fs; } + if (format == &pg_rst) + hwidth = hwidth + 4; + + /* if hwidth < reclen fromheader */ + if (format == &pg_markdown) + if (hwidth < floor (log10 (abs (cont->nrows))) + 12) + hwidth = floor (log10 (abs (cont->nrows))) + 12; /* find longest data cell */ for (i = 0, ptr = cont->cells; *ptr; ptr++, i++) *************** *** 1313,1320 **** print_aligned_vertical(const printTableContent *cont, height, fs; ! pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &height, &fs); if (width > dwidth) dwidth = width; if (height > dheight) --- 1456,1468 ---- height, fs; ! if (format != &pg_markdown) ! pg_wcssize((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &height, &fs); ! else ! pg_wcssize_newline((const unsigned char *) *ptr, strlen(*ptr), encoding, ! &width, &height, &fs); ! if (width > dwidth) dwidth = width; if (height > dheight) *************** *** 1503,1509 **** print_aligned_vertical(const printTableContent *cont, if (cancel_pressed) break; ! if (i == 0) pos = PRINT_RULE_TOP; else pos = PRINT_RULE_MIDDLE; --- 1651,1657 ---- if (cancel_pressed) break; ! if (i == 0 || format == &pg_rst) pos = PRINT_RULE_TOP; else pos = PRINT_RULE_MIDDLE; *************** *** 1518,1538 **** print_aligned_vertical(const printTableContent *cont, (format == &pg_asciiformat_old)) lhwidth++; /* for newline indicators */ ! if (!opt_tuples_only) print_aligned_vertical_line(format, opt_border, record++, lhwidth, dwidth, pos, fout); else if (i != 0 || !cont->opt->start_table || opt_border == 2) print_aligned_vertical_line(format, opt_border, 0, lhwidth, dwidth, pos, fout); } ! /* Format the header */ ! pg_wcsformat((const unsigned char *) cont->headers[i % cont->ncolumns], ! strlen(cont->headers[i % cont->ncolumns]), ! encoding, hlineptr, hheight); ! /* Format the data */ ! pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding, ! dlineptr, dheight); /* * Loop through header and data in parallel dealing with newlines and --- 1666,1717 ---- (format == &pg_asciiformat_old)) lhwidth++; /* for newline indicators */ ! if (!opt_tuples_only && (format != &pg_rst && format != &pg_markdown)) print_aligned_vertical_line(format, opt_border, record++, lhwidth, dwidth, pos, fout); + else if (!opt_tuples_only && format == &pg_rst) + { + if (i ==0) + print_aligned_vertical_line(format, opt_border, 0, lhwidth, + dwidth, pos, fout); + print_aligned_vertical_line(format, opt_border, record++, + 0, lhwidth + dwidth, PRINT_RULE_DATA, fout); /* because need of only one column*/ + print_aligned_vertical_line(format, opt_border, 0, lhwidth, + dwidth, pos, fout); + } + else if (!opt_tuples_only && format == &pg_markdown) + { + print_aligned_vertical_line(format, opt_border, record++, + lhwidth, dwidth, PRINT_RULE_DATA, fout); + if (i == 0) + print_aligned_vertical_line(format, opt_border, 0, lhwidth, + dwidth, PRINT_RULE_MIDDLE, fout); + } else if (i != 0 || !cont->opt->start_table || opt_border == 2) print_aligned_vertical_line(format, opt_border, 0, lhwidth, dwidth, pos, fout); } ! if (format != &pg_markdown) ! { ! /* Format the header */ ! pg_wcsformat((const unsigned char *) cont->headers[i % cont->ncolumns], ! strlen(cont->headers[i % cont->ncolumns]), ! encoding, hlineptr, hheight); ! /* Format the data */ ! pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding, ! dlineptr, dheight); ! } ! else ! { ! /* Format the header */ ! pg_wcsformat_newline((const unsigned char *) cont->headers[i % cont->ncolumns], ! strlen(cont->headers[i % cont->ncolumns]), ! encoding, hlineptr, hheight); ! /* Format the data */ ! pg_wcsformat_newline((const unsigned char *) *ptr, strlen(*ptr), encoding, ! dlineptr, dheight); ! } /* * Loop through header and data in parallel dealing with newlines and *************** *** 1564,1572 **** print_aligned_vertical(const printTableContent *cont, /* * Header text */ ! strlen_max_width(hlineptr[hline].ptr, &target_width, ! encoding); ! fprintf(fout, "%-s", hlineptr[hline].ptr); /* * Spacer --- 1743,1758 ---- /* * Header text */ ! if (format != &pg_rst) ! strlen_max_width(hlineptr[hline].ptr, &target_width, ! encoding); ! else ! strlen_max_width(hlineptr[hline].ptr, &target_width - 4, ! encoding); ! if (format != &pg_rst) ! fprintf(fout, "%-s", hlineptr[hline].ptr); ! else ! fprintf(fout, "**%-s**", hlineptr[hline].ptr); /*header bold*/ /* * Spacer *************** *** 1640,1647 **** print_aligned_vertical(const printTableContent *cont, */ bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset, &target_width, encoding); ! fputnbytes(fout, (char *) (dlineptr[dline].ptr + offset), ! bytes_to_output); chars_to_output -= target_width; offset += bytes_to_output; --- 1826,1837 ---- */ bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset, &target_width, encoding); ! ! if (format != &pg_rst) ! fputnbytes(fout, (char *) (dlineptr[dline].ptr + offset), ! bytes_to_output); ! else ! skip_leading_spaces_print((char *) (dlineptr[dline].ptr + offset), fout); chars_to_output -= target_width; offset += bytes_to_output; *************** *** 1704,1714 **** print_aligned_vertical(const printTableContent *cont, fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule); } } } if (cont->opt->stop_table) { ! if (opt_border == 2 && !cancel_pressed) print_aligned_vertical_line(format, opt_border, 0, hwidth, dwidth, PRINT_RULE_BOTTOM, fout); --- 1894,1907 ---- fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule); } } + if (opt_border == 2 && format == &pg_rst) + print_aligned_vertical_line(format, opt_border, 0, hwidth, dwidth, + PRINT_RULE_BOTTOM, fout); } if (cont->opt->stop_table) { ! if (opt_border == 2 && !cancel_pressed && format != &pg_rst) print_aligned_vertical_line(format, opt_border, 0, hwidth, dwidth, PRINT_RULE_BOTTOM, fout); *************** *** 3262,3267 **** printTable(const printTableContent *cont, --- 3455,3473 ---- else print_troff_ms_text(cont, fout); break; + case PRINT_RST: + if (cont->opt->expanded == 1) + print_aligned_vertical(cont, fout, false); + else + print_aligned_text(cont, fout, false); + break; + case PRINT_MARKDOWN: + if (cont->opt->expanded == 1) + print_aligned_vertical(cont, fout, false); + else + print_aligned_text(cont, fout, false); + break; + default: fprintf(stderr, _("invalid output format (internal error): %d"), cont->opt->format); *************** *** 3416,3422 **** get_line_style(const printTableOpt *opt) * printTableOpt struct can be initialized to zeroes to get default * behavior. */ ! if (opt->line_style != NULL) return opt->line_style; else return &pg_asciiformat; --- 3622,3632 ---- * printTableOpt struct can be initialized to zeroes to get default * behavior. */ ! if (opt->format == PRINT_RST) ! return &pg_rst; ! else if (opt->format == PRINT_MARKDOWN) ! return &pg_markdown; ! else if (opt->line_style != NULL) return opt->line_style; else return &pg_asciiformat; diff --git a/src/include/feindex 56626f631b..70684155b5 100644 *** a/src/include/fe_utils/mbprint.h --- b/src/include/fe_utils/mbprint.h *************** *** 25,29 **** extern void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, --- 25,33 ---- struct lineptr * lines, int count); extern void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, int *width, int *height, int *format_size); + extern void pg_wcsformat_newline(const unsigned char *pwcs, size_t len, int encoding, + struct lineptr * lines, int count); + extern void pg_wcssize_newline(const unsigned char *pwcs, size_t len, int encoding, + int *width, int *height, int *format_size); #endif /* MBPRINT_H */ diff --git a/src/include/fe_utils/priindex d89b6febcb..e8b7532bbf 100644 *** a/src/include/fe_utils/print.h --- b/src/include/fe_utils/print.h *************** *** 33,39 **** enum printFormat PRINT_ASCIIDOC, PRINT_LATEX, PRINT_LATEX_LONGTABLE, ! PRINT_TROFF_MS /* add your favourite output format here ... */ }; --- 33,41 ---- PRINT_ASCIIDOC, PRINT_LATEX, PRINT_LATEX_LONGTABLE, ! PRINT_TROFF_MS, ! PRINT_MARKDOWN, ! PRINT_RST /* add your favourite output format here ... */ }; *************** *** 176,181 **** typedef struct printQueryOpt --- 178,185 ---- extern volatile bool cancel_pressed; extern const printTextFormat pg_asciiformat; + extern const printTextFormat pg_markdown; /*linestyle markdown*/ + extern const printTextFormat pg_rst; /*linestyle rst*/ extern const printTextFormat pg_asciiformat_old; extern printTextFormat pg_utf8format; /* ideally would be const, but... */ diff --git a/src/test/regress/expecindex eb7f197b12..adaac27fc3 100644 *** a/src/test/regress/expected/psql.out --- b/src/test/regress/expected/psql.out *************** *** 2763,2765 **** NOTICE: foo --- 2763,2879 ---- CONTEXT: PL/pgSQL function inline_code_block line 3 at RAISE ERROR: bar CONTEXT: PL/pgSQL function inline_code_block line 4 at RAISE + prepare q AS VALUES(E'Elephant, kangaroo,\nsquirrel, gorilla', 121, + (279./278.)::text, 0.1111, repeat('Hello ', 10)) + , (E'goat, rhinoceros,\nmonkey, ape', 11121, (1279./1278.)::text, 5.1111, + repeat('xxxxxx ', 10)) + , (E'donkey, cow, horse, tit,\neagle, whale,\naligator, + pelican,\ngrasshoper\npig\n\tbat', 14351, (12345./245.)::text, 345.11, + repeat('yyyyyy ', 10)); + \pset format rst + execute q; + +--------------------------+---------+---------------------+---------+------------------------------------------------------------------------+ + | column1 | column2 | column3 | column4 | column5 | + +==========================+=========+=====================+=========+========================================================================+ + | Elephant, kangaroo, | 121 | 1.0035971223021583 | 0.1111 | Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello | + | squirrel, gorilla | | | | | + +--------------------------+---------+---------------------+---------+------------------------------------------------------------------------+ + | goat, rhinoceros, | 11121 | 1.0007824726134585 | 5.1111 | xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx | + | monkey, ape | | | | | + +--------------------------+---------+---------------------+---------+------------------------------------------------------------------------+ + | donkey, cow, horse, tit, | 14351 | 50.3877551020408163 | 345.11 | yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy | + | eagle, whale, | | | | | + | aligator, | | | | | + | pelican, | | | | | + | grasshoper | | | | | + | pig | | | | | + | bat | | | | | + +--------------------------+---------+---------------------+---------+------------------------------------------------------------------------+ + + (3 rows) + + \pset format markdown + execute q; + + | column1 | column2 | column3 | column4 | column5 | + |-------------------------------------------------------------------------------------------------------------|---------|---------------------|---------|------------------------------------------------------------------------| + | Elephant, kangaroo,</br>squirrel, gorilla | 121 | 1.0035971223021583 | 0.1111 | Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello | + | goat, rhinoceros,</br>monkey, ape | 11121 | 1.0007824726134585 | 5.1111 | xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx | + | donkey, cow, horse, tit,</br>eagle, whale,</br>aligator,</br> pelican,</br>grasshoper</br>pig</br> bat | 14351 | 50.3877551020408163 | 345.11 | yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy | + + + (3 rows) + + \x + \pset format rst + execute q; + +-------------+------------------------------------------------------------------------+ + | **RECORD 1** | + +-------------+------------------------------------------------------------------------+ + | **column1** | Elephant, kangaroo, | + | | squirrel, gorilla | + +-------------+------------------------------------------------------------------------+ + | **column2** | 121 | + +-------------+------------------------------------------------------------------------+ + | **column3** | 1.0035971223021583 | + +-------------+------------------------------------------------------------------------+ + | **column4** | 0.1111 | + +-------------+------------------------------------------------------------------------+ + | **column5** | Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello | + +-------------+------------------------------------------------------------------------+ + | **RECORD 2** | + +-------------+------------------------------------------------------------------------+ + | **column1** | goat, rhinoceros, | + | | monkey, ape | + +-------------+------------------------------------------------------------------------+ + | **column2** | 11121 | + +-------------+------------------------------------------------------------------------+ + | **column3** | 1.0007824726134585 | + +-------------+------------------------------------------------------------------------+ + | **column4** | 5.1111 | + +-------------+------------------------------------------------------------------------+ + | **column5** | xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx | + +-------------+------------------------------------------------------------------------+ + | **RECORD 3** | + +-------------+------------------------------------------------------------------------+ + | **column1** | donkey, cow, horse, tit, | + | | eagle, whale, | + | | aligator, | + | | pelican, | + | | grasshoper | + | | pig | + | | bat | + +-------------+------------------------------------------------------------------------+ + | **column2** | 14351 | + +-------------+------------------------------------------------------------------------+ + | **column3** | 50.3877551020408163 | + +-------------+------------------------------------------------------------------------+ + | **column4** | 345.11 | + +-------------+------------------------------------------------------------------------+ + | **column5** | yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy | + +-------------+------------------------------------------------------------------------+ + + \pset format markdown + execute q; + | **RECORD 1** | | + |--------------|-------------------------------------------------------------------------------------------------------------| + | column1 | Elephant, kangaroo,</br>squirrel, gorilla | + | column2 | 121 | + | column3 | 1.0035971223021583 | + | column4 | 0.1111 | + | column5 | Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello | + | **RECORD 2** | | + | column1 | goat, rhinoceros,</br>monkey, ape | + | column2 | 11121 | + | column3 | 1.0007824726134585 | + | column4 | 5.1111 | + | column5 | xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx xxxxxx | + | **RECORD 3** | | + | column1 | donkey, cow, horse, tit,</br>eagle, whale,</br>aligator,</br> pelican,</br>grasshoper</br>pig</br> bat | + | column2 | 14351 | + | column3 | 50.3877551020408163 | + | column4 | 345.11 | + | column5 | yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy yyyyyy | + + + deallocate q; diff --git a/src/test/regress/sql/psql.sqindex 8f8e17a87c..8e3aea7c6b 100644 *** a/src/test/regress/sql/psql.sql --- b/src/test/regress/sql/psql.sql *************** *** 404,406 **** begin --- 404,425 ---- raise notice 'foo'; raise exception 'bar'; end $$; + + prepare q AS VALUES(E'Elephant, kangaroo,\nsquirrel, gorilla', 121, + (279./278.)::text, 0.1111, repeat('Hello ', 10)) + , (E'goat, rhinoceros,\nmonkey, ape', 11121, (1279./1278.)::text, 5.1111, + repeat('xxxxxx ', 10)) + , (E'donkey, cow, horse, tit,\neagle, whale,\naligator, + pelican,\ngrasshoper\npig\n\tbat', 14351, (12345./245.)::text, 345.11, + repeat('yyyyyy ', 10)); + + \pset format rst + execute q; + \pset format markdown + execute q; + \x + \pset format rst + execute q; + \pset format markdown + execute q; + deallocate q;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers