2017-04-19 10:05 GMT+02:00 Jan Michálek <godzilalal...@gmail.com>: > 2017-04-19 9:18 GMT+02:00 Fabien COELHO <coe...@cri.ensmp.fr>: > >> >> I still do not understand "why" this variant vs CommonMark or whatever >>>> other version. >>>> >>> >>> Because of simply implementation and readability (looks similar to >>> aligned >>> format) and it is comfortable to edit generated table (changing values, >>> aligning columns etc.). >>> >> >> Hmmm. Why not. >> >> Sorry, maybe I`m not understanding, there is problems with characters like >>> pipe in cells, pipe should be escaped. What other special markdown >>> characters? Escaping html code in cells? >>> >> >> Markdown include characters/sequences which are interpreted as markers: >> _Italic_, **Bold**, *** => horizontal rules, > block quote... `inline >> code`... If they are interpreted within a table cell then probably they >> should be escaped somehow. >> > > I have treated "_*|<>"
jelen=# SELECT E'**1**</br>\nrrr'; | **RECORD 1** | | |--------------|------------------------------| | ?column? | \*\*1\*\*</br></br>rrr | jelen=# > I`m able to sanitize characters, but complex sequences will be problem. I > will look on this, but I don`t know, if I`m able to do this. > > My main interest on this was in rst. I`m using markdown only in github > issues and my knowldge about md is poor. > > >> >> Main of the functionality is used from aligned format. I tested returned >>>>> tables in retext and it works. If i have another character than >>>>> standart >>>>> pipe, it shouldn`t work. >>>>> >>>>> Sure. ISTM that you are currently using U+2502 instead of pipe, hence >>>> my >>>> point. >>>> >>> >>> Could you send me example where? >>> >> >> I already did in the first mail with the example output copy pasted from >> psql. Some characters are pipe and others are BOX DRAWINGS LIGHT VERTICAL >> characters. >> >> Maybe this is because I have in my ~/.psqlrc: >> >> \pset linestyle unicode >> \pset border 2 >> > >> in which case your reuse of the the aligned stuff should take care of the >> border setting to avoid using special UTF8 characters.. >> > I corrected it. jelen=# \pset linestyle unicode Line style is unicode. jelen=# SELECT 1,2,3,4; | **RECORD 1** | | |--------------|---| | ?column? | 1 | | ?column? | 2 | | ?column? | 3 | | ?column? | 4 | jelen=# Regards Jan > > Yes, it looks it is done by linestyle. > > > jelen=# SELECT 1; > > | ?column? | > |----------| > | 1 | > > > (1 row) > > jelen=# \pset linestyle unicode > Line style is unicode. > jelen=# SELECT 1; > > │ ?column? │ > |----------| > │ 1 │ > > > (1 row) > > jelen=# > > I have prepared linestyle for rst and md, but I can`t switch linestyle > outside, because if i did it > \pset linestyle > wrote "markdown" or "rst". > I see, problem is only in cells borders, I will correct this. > > Jan > > >> >> -- >> Fabien. >> > > > > -- > 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 3b86612862..97d8612359 100644 *** a/doc/src/sgml/ref/psql-ref.sgml --- b/doc/src/sgml/ref/psql-ref.sgml *************** *** 2536,2542 **** 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.) --- 2536,2543 ---- <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.) *************** *** 2564,2570 **** 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 --- 2565,2572 ---- <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 859ded71f6..5bca425d22 100644 *** a/src/bin/psql/command.c --- b/src/bin/psql/command.c *************** *** 3693,3698 **** _align2string(enum printFormat in) --- 3693,3704 ---- case PRINT_TROFF_MS: return "troff-ms"; break; + case PRINT_MARKDOWN: + return "markdown"; + break; + case PRINT_RST: + return "rst"; + break; } return "unknown"; } *************** *** 3764,3772 **** 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; } } --- 3770,3782 ---- 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 ac435220e6..13f2e44add 100644 *** a/src/bin/psql/help.c --- b/src/bin/psql/help.c *************** *** 382,388 **** 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" --- 382,388 ---- 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 e2a3351210..96b0067919 100644 *** a/src/bin/psql/tab-complete.c --- b/src/bin/psql/tab-complete.c *************** *** 3444,3450 **** 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); } --- 3444,3450 ---- { 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..6736839283 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,393 ---- } /* + * 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 (*pwcs == '|') + { + linewidth += 2; + format_size += 2; + } + else if (*pwcs == '<') + { + linewidth += 4; + format_size += 4; + } + else if (*pwcs == '>') + { + linewidth += 4; + format_size += 4; + } + else if (*pwcs == '*') + { + linewidth += 2; + format_size += 2; + } + else if (*pwcs == '_') + { + linewidth += 2; + format_size += 2; + } + 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, --- 485,610 ---- (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 (*pwcs == '|') + { + strcpy((char *) ptr, "\\|"); + linewidth += 2; + ptr += 2; + } + else if (*pwcs == '<') + { + strcpy((char *) ptr, "<"); + linewidth += 4; + ptr += 4; + } + else if (*pwcs == '>') + { + strcpy((char *) ptr, ">"); + linewidth += 4; + ptr += 4; + } + else if (*pwcs == '*') + { + strcpy((char *) ptr, "\\*"); + linewidth += 2; + ptr += 2; + } + else if (*pwcs == '_') + { + strcpy((char *) ptr, "\\_"); + linewidth += 2; + ptr += 2; + } + 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..20d1ce99b1 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,721 ---- if (opt_border > 2) opt_border = 2; + if (cont->opt->format == PRINT_MARKDOWN) + { + format = &pg_markdown; + dformat = &format->lrule[PRINT_RULE_DATA]; + } + + else if (cont->opt->format == PRINT_RST) + { + format = &pg_rst; + dformat = &format->lrule[PRINT_RULE_DATA]; + } + + 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]) --- 755,766 ---- 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; --- 783,794 ---- 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 --- 948,959 ---- 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); --- 991,1002 ---- 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; --- 1017,1030 ---- 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; *************** *** 963,968 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) --- 1078,1086 ---- _print_horizontal_line(col_count, width_wrap, opt_border, PRINT_RULE_MIDDLE, format, fout); } + else if (format == &pg_rst) + _print_horizontal_line(col_count, width_wrap, opt_border, + PRINT_RULE_TOP, format, fout); } /* print cells, one loop per row */ *************** *** 974,985 **** print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager) break; /* * Format each cell. */ 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; } --- 1092,1115 ---- break; /* + * line after first row for markdown with only tuples option + */ + if(opt_tuples_only && format == &pg_markdown && i == col_count) + _print_horizontal_line(col_count, width_wrap, opt_border, + PRINT_RULE_MIDDLE, format, fout); + + + /* * Format each cell. */ 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; --- 1182,1193 ---- 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); --- 1256,1289 ---- 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, --- 1339,1348 ---- { 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, --- 1408,1427 ---- if (opt_border > 2) opt_border = 2; + if (cont->opt->format == PRINT_MARKDOWN) + { + format = &pg_markdown; + dformat = &format->lrule[PRINT_RULE_DATA]; + } + else if (cont->opt->format == PRINT_RST) + { + format = &pg_rst; + dformat = &format->lrule[PRINT_RULE_DATA]; + } + + 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) --- 1458,1470 ---- 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, --- 1475,1487 ---- if (fs > hformatsize) hformatsize = fs; } + if (format == &pg_rst) + hwidth = hwidth + 4; + + /* if hwidth < reclen fromheader */ + if (format == &pg_markdown && !opt_tuples_only) + 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) --- 1490,1502 ---- 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; --- 1685,1691 ---- 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 --- 1700,1758 ---- (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) && format != &pg_markdown) print_aligned_vertical_line(format, opt_border, 0, lhwidth, dwidth, pos, fout); + else if (i != 0 && format == &pg_markdown) + print_aligned_vertical_line(format, opt_border, 0, lhwidth, + dwidth, PRINT_RULE_DATA, fout); } ! if (i == 1 && format == &pg_markdown && opt_tuples_only) ! print_aligned_vertical_line(format, opt_border, 0, hwidth, ! 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 *************** *** 1565,1577 **** print_aligned_vertical(const printTableContent *cont, * Header text */ strlen_max_width(hlineptr[hline].ptr, &target_width, ! encoding); ! fprintf(fout, "%-s", hlineptr[hline].ptr); /* * Spacer */ ! swidth -= target_width; if (swidth > 0) fprintf(fout, "%*s", swidth, " "); --- 1785,1804 ---- * Header text */ strlen_max_width(hlineptr[hline].ptr, &target_width, ! encoding); ! if (format != &pg_rst) ! fprintf(fout, "%-s", hlineptr[hline].ptr); ! else ! fprintf(fout, "**%-s**", hlineptr[hline].ptr); /*header bold*/ /* * Spacer */ ! if (format == &pg_rst) ! swidth -= target_width + 4; ! else ! swidth -= target_width; ! if (swidth > 0) fprintf(fout, "%*s", swidth, " "); *************** *** 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; --- 1867,1878 ---- */ 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); --- 1935,1948 ---- 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, --- 3496,3514 ---- 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); 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 d602aeef42..c242abc4a3 100644 *** a/src/test/regress/expected/psql.out --- b/src/test/regress/expected/psql.out *************** *** 2964,2966 **** SELECT 3 --- 2964,3080 ---- UNION SELECT 4 UNION SELECT 5 ORDER BY 1; + 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 b56a05f7f0..fa32a60a28 100644 *** a/src/test/regress/sql/psql.sql --- b/src/test/regress/sql/psql.sql *************** *** 560,562 **** UNION SELECT 5 --- 560,580 ---- ORDER BY 1; \r \p + 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