2017-04-18 2:27 GMT+02:00 Fabien COELHO <coe...@cri.ensmp.fr>:

>
> Hello Jan,
>
> Corrected problem with \pset linestyle when format is set to markdown, or
>> rst.
>>
>> Corrected tuples only for markdown and rst (normal and expanded)
>>
>
> It seems that the patch does not apply anymore on head due to changes in
> psql non regression tests. Could you rebase?
>

This should work on current master (all test passed).

Je;


>
> --
> Fabien.
>



-- 
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..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..526a40a5d4 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,714 ----
  	if (opt_border > 2)
  		opt_border = 2;
  
+ 	if (cont->opt->format == PRINT_MARKDOWN)
+ 		format = &pg_markdown;
+ 	else if (cont->opt->format == PRINT_RST)
+ 		format = &pg_rst;
+ 
+ 	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])
--- 748,759 ----
  					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;
--- 776,787 ----
  					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
--- 941,952 ----
  						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);
--- 984,995 ----
  			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;
--- 1010,1023 ----
  									   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)
--- 1071,1079 ----
  			_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;
  		}
  
--- 1085,1108 ----
  			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;
--- 1175,1186 ----
  					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);
--- 1249,1282 ----
  			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,
--- 1332,1341 ----
  	{
  		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,
--- 1401,1414 ----
  	if (opt_border > 2)
  		opt_border = 2;
  
+ 	if (cont->opt->format == PRINT_MARKDOWN)
+ 		format = &pg_markdown;
+ 	else if (cont->opt->format == PRINT_RST)
+ 		format = &pg_rst;
+ 
+ 	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)
--- 1445,1457 ----
  					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,
--- 1462,1474 ----
  		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)
--- 1477,1489 ----
  					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;
--- 1672,1678 ----
  		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
--- 1687,1745 ----
  				(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, " ");
  
--- 1772,1791 ----
  				 * 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;
--- 1854,1865 ----
  				 */
  				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);
  
--- 1922,1935 ----
  					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,
--- 3483,3501 ----
  			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

Reply via email to