Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a2dabf0

Browse files
committed
Add unicode_{column|header|border}_style to psql
With the unicode linestyle, this adds support to control if the column, header, or border style should be single or double line unicode characters. The default remains 'single'. In passing, clean up the border documentation and address some minor formatting/spelling issues. Pavel Stehule, with some additional changes by me.
1 parent 8296283 commit a2dabf0

File tree

8 files changed

+307
-34
lines changed

8 files changed

+307
-34
lines changed

doc/src/sgml/ref/psql-ref.sgml

+35-5
Original file line numberDiff line numberDiff line change
@@ -1996,12 +1996,12 @@ lo_import 152801
19961996
the number the more borders and lines the tables will have,
19971997
but this depends on the particular format. In
19981998
<acronym>HTML</acronym> format, this will translate directly
1999-
into the <literal>border=...</literal> attribute; in the
2000-
other formats only values 0 (no border), 1 (internal dividing lines),
2001-
and 2 (table frame) make sense.
1999+
into the <literal>border=...</literal> attribute; in
20022000
<literal>latex</literal> and <literal>latex-longtable</literal>
2003-
also support a <literal>border</literal> value of 3 which adds
2004-
a dividing line between each row.
2001+
formats, a value of 3 will add a dividing line between each row; in
2002+
the other formats only values 0 (no border), 1 (internal dividing
2003+
lines), and 2 (table frame) make sense and values above 2 will be
2004+
treated the same as <literal>border = 2</literal>.
20052005
</para>
20062006
</listitem>
20072007
</varlistentry>
@@ -2306,6 +2306,36 @@ lo_import 152801
23062306
</para>
23072307
</listitem>
23082308
</varlistentry>
2309+
2310+
<varlistentry>
2311+
<term><literal>unicode_border_style</literal></term>
2312+
<listitem>
2313+
<para>
2314+
Sets the border drawing style for the unicode linestyle to one
2315+
of <literal>single</literal> or <literal>double</literal>.
2316+
</para>
2317+
</listitem>
2318+
</varlistentry>
2319+
2320+
<varlistentry>
2321+
<term><literal>unicode_column_style</literal></term>
2322+
<listitem>
2323+
<para>
2324+
Sets the column drawing style for the unicode linestyle to one
2325+
of <literal>single</literal> or <literal>double</literal>.
2326+
</para>
2327+
</listitem>
2328+
</varlistentry>
2329+
2330+
<varlistentry>
2331+
<term><literal>unicode_header_style</literal></term>
2332+
<listitem>
2333+
<para>
2334+
Sets the header drawing style for the unicode linestyle to one
2335+
of <literal>single</literal> or <literal>double</literal>.
2336+
</para>
2337+
</listitem>
2338+
</varlistentry>
23092339
</variablelist>
23102340
</para>
23112341

src/bin/psql/command.c

+96
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,9 @@ exec_command(const char *cmd,
10541054
"footer", "format", "linestyle", "null",
10551055
"numericlocale", "pager", "recordsep",
10561056
"tableattr", "title", "tuples_only",
1057+
"unicode_border_linestyle",
1058+
"unicode_column_linestyle",
1059+
"unicode_header_linestyle",
10571060
NULL
10581061
};
10591062

@@ -2248,6 +2251,41 @@ _align2string(enum printFormat in)
22482251
return "unknown";
22492252
}
22502253

2254+
/*
2255+
* Parse entered unicode linestyle. Returns true, when entered string is
2256+
* known linestyle: single, double else returns false.
2257+
*/
2258+
static bool
2259+
set_unicode_line_style(printQueryOpt *popt, const char *value, size_t vallen,
2260+
unicode_linestyle *linestyle)
2261+
{
2262+
if (pg_strncasecmp("single", value, vallen) == 0)
2263+
*linestyle = UNICODE_LINESTYLE_SINGLE;
2264+
else if (pg_strncasecmp("double", value, vallen) == 0)
2265+
*linestyle = UNICODE_LINESTYLE_DOUBLE;
2266+
else
2267+
return false;
2268+
2269+
/* input is ok, generate new unicode style */
2270+
refresh_utf8format(&(popt->topt));
2271+
2272+
return true;
2273+
}
2274+
2275+
static const char *
2276+
_unicode_linestyle2string(int linestyle)
2277+
{
2278+
switch (linestyle)
2279+
{
2280+
case UNICODE_LINESTYLE_SINGLE:
2281+
return "single";
2282+
break;
2283+
case UNICODE_LINESTYLE_DOUBLE:
2284+
return "double";
2285+
break;
2286+
}
2287+
return "unknown";
2288+
}
22512289

22522290
bool
22532291
do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
@@ -2305,6 +2343,45 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
23052343

23062344
}
23072345

2346+
/* set unicode border line style */
2347+
else if (strcmp(param, "unicode_border_linestyle") == 0)
2348+
{
2349+
if (!value)
2350+
;
2351+
else if (!set_unicode_line_style(popt, value, vallen,
2352+
&popt->topt.unicode_border_linestyle))
2353+
{
2354+
psql_error("\\pset: allowed unicode border linestyle are single, double\n");
2355+
return false;
2356+
}
2357+
}
2358+
2359+
/* set unicode column line style */
2360+
else if (strcmp(param, "unicode_column_linestyle") == 0)
2361+
{
2362+
if (!value)
2363+
;
2364+
else if (!set_unicode_line_style(popt, value, vallen,
2365+
&popt->topt.unicode_column_linestyle))
2366+
{
2367+
psql_error("\\pset: allowed unicode column linestyle are single, double\n");
2368+
return false;
2369+
}
2370+
}
2371+
2372+
/* set unicode header line style */
2373+
else if (strcmp(param, "unicode_header_linestyle") == 0)
2374+
{
2375+
if (!value)
2376+
;
2377+
else if (!set_unicode_line_style(popt, value, vallen,
2378+
&popt->topt.unicode_header_linestyle))
2379+
{
2380+
psql_error("\\pset: allowed unicode header linestyle are single, double\n");
2381+
return false;
2382+
}
2383+
}
2384+
23082385
/* set border style/width */
23092386
else if (strcmp(param, "border") == 0)
23102387
{
@@ -2601,6 +2678,25 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
26012678
printf(_("Tuples only (%s) is off.\n"), param);
26022679
}
26032680

2681+
/* unicode style formatting */
2682+
else if (strcmp(param, "unicode_border_linestyle") == 0)
2683+
{
2684+
printf(_("Unicode border linestyle is \"%s\".\n"),
2685+
_unicode_linestyle2string(popt->topt.unicode_border_linestyle));
2686+
}
2687+
2688+
else if (strcmp(param, "unicode_column_linestyle") == 0)
2689+
{
2690+
printf(_("Unicode column linestyle is \"%s\".\n"),
2691+
_unicode_linestyle2string(popt->topt.unicode_column_linestyle));
2692+
}
2693+
2694+
else if (strcmp(param, "unicode_header_linestyle") == 0)
2695+
{
2696+
printf(_("Unicode border linestyle is \"%s\".\n"),
2697+
_unicode_linestyle2string(popt->topt.unicode_header_linestyle));
2698+
}
2699+
26042700
else
26052701
{
26062702
psql_error("\\pset: unknown option: %s\n", param);

src/bin/psql/help.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ slashUsage(unsigned short int pager)
249249
ON(pset.popt.topt.format == PRINT_HTML));
250250
fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n"
251251
" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n"
252-
" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n"));
252+
" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n"
253+
" unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n"));
253254
fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"),
254255
ON(pset.popt.topt.tuples_only));
255256
fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n"));

src/bin/psql/print.c

+141-27
Original file line numberDiff line numberDiff line change
@@ -89,35 +89,97 @@ const printTextFormat pg_asciiformat_old =
8989
false
9090
};
9191

92-
const printTextFormat pg_utf8format =
93-
{
94-
"unicode",
95-
{
96-
/* ─, ┌, ┬, ┐ */
97-
{"\342\224\200", "\342\224\214", "\342\224\254", "\342\224\220"},
98-
/* ─, ├, ┼, ┤ */
99-
{"\342\224\200", "\342\224\234", "\342\224\274", "\342\224\244"},
100-
/* ─, └, ┴, ┘ */
101-
{"\342\224\200", "\342\224\224", "\342\224\264", "\342\224\230"},
102-
/* N/A, │, │, │ */
103-
{"", "\342\224\202", "\342\224\202", "\342\224\202"}
92+
/* Default unicode linestyle format */
93+
const printTextFormat pg_utf8format;
94+
95+
typedef struct unicodeStyleRowFormat {
96+
const char *horizontal;
97+
const char *vertical_and_right[2];
98+
const char *vertical_and_left[2];
99+
} unicodeStyleRowFormat;
100+
101+
typedef struct unicodeStyleColumnFormat {
102+
const char *vertical;
103+
const char *vertical_and_horizontal[2];
104+
const char *up_and_horizontal[2];
105+
const char *down_and_horizontal[2];
106+
} unicodeStyleColumnFormat;
107+
108+
typedef struct unicodeStyleBorderFormat {
109+
const char *up_and_right;
110+
const char *vertical;
111+
const char *down_and_right;
112+
const char *horizontal;
113+
const char *down_and_left;
114+
const char *left_and_right;
115+
} unicodeStyleBorderFormat;
116+
117+
typedef struct unicodeStyleFormat {
118+
unicodeStyleRowFormat row_style[2];
119+
unicodeStyleColumnFormat column_style[2];
120+
unicodeStyleBorderFormat border_style[2];
121+
const char *header_nl_left;
122+
const char *header_nl_right;
123+
const char *nl_left;
124+
const char *nl_right;
125+
const char *wrap_left;
126+
const char *wrap_right;
127+
bool wrap_right_border;
128+
} unicodeStyleFormat;
129+
130+
const unicodeStyleFormat unicode_style = {
131+
{
132+
{
133+
/* ─ */
134+
"\342\224\200",
135+
/* ├╟ */
136+
{"\342\224\234", "\342\225\237"},
137+
/* ┤╢ */
138+
{"\342\224\244", "\342\225\242"},
139+
},
140+
{
141+
/* ═ */
142+
"\342\225\220",
143+
/* ╞╠ */
144+
{"\342\225\236", "\342\225\240"},
145+
/* ╡╣ */
146+
{"\342\225\241", "\342\225\243"},
147+
},
148+
},
149+
{
150+
{
151+
/* │ */
152+
"\342\224\202",
153+
/* ┼╪ */
154+
{"\342\224\274", "\342\225\252"},
155+
/* ┴╧ */
156+
{"\342\224\264", "\342\225\247"},
157+
/* ┬╤ */
158+
{"\342\224\254", "\342\225\244"},
159+
},
160+
{
161+
/* ║ */
162+
"\342\225\221",
163+
/* ╫╬ */
164+
{"\342\225\253", "\342\225\254"},
165+
/* ╨╩ */
166+
{"\342\225\250", "\342\225\251"},
167+
/* ╥╦ */
168+
{"\342\225\245", "\342\225\246"},
169+
},
170+
},
171+
{
172+
/* └│┌─┐┘ */
173+
{"\342\224\224", "\342\224\202", "\342\224\214", "\342\224\200", "\342\224\220", "\342\224\230"},
174+
/* ╚║╔═╗╝ */
175+
{"\342\225\232", "\342\225\221", "\342\225\224", "\342\225\220", "\342\225\227", "\342\225\235"},
104176
},
105-
/* │ */
106-
"\342\224\202",
107-
/* │ */
108-
"\342\224\202",
109-
/* │ */
110-
"\342\224\202",
111177
" ",
112-
/* ↵ */
113-
"\342\206\265",
178+
"\342\206\265", /* ↵ */
114179
" ",
115-
/* ↵ */
116-
"\342\206\265",
117-
/* … */
118-
"\342\200\246",
119-
/* … */
120-
"\342\200\246",
180+
"\342\206\265", /* ↵ */
181+
"\342\200\246", /* … */
182+
"\342\200\246", /* … */
121183
true
122184
};
123185

@@ -1289,7 +1351,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
12891351
}
12901352
else
12911353
/*
1292-
* For border = 2, two more for the pipes (|) at the begging and
1354+
* For border = 2, two more for the pipes (|) at the beginning and
12931355
* at the end of the lines.
12941356
*/
12951357
swidth = 7;
@@ -2952,6 +3014,58 @@ get_line_style(const printTableOpt *opt)
29523014
return &pg_asciiformat;
29533015
}
29543016

3017+
void
3018+
refresh_utf8format(const printTableOpt *opt)
3019+
{
3020+
printTextFormat *popt = (printTextFormat *) &pg_utf8format;
3021+
3022+
const unicodeStyleBorderFormat *border;
3023+
const unicodeStyleRowFormat *header;
3024+
const unicodeStyleColumnFormat *column;
3025+
3026+
popt->name = "unicode";
3027+
3028+
border = &unicode_style.border_style[opt->unicode_border_linestyle];
3029+
header = &unicode_style.row_style[opt->unicode_header_linestyle];
3030+
column = &unicode_style.column_style[opt->unicode_column_linestyle];
3031+
3032+
popt->lrule[PRINT_RULE_TOP].hrule = border->horizontal;
3033+
popt->lrule[PRINT_RULE_TOP].leftvrule = border->down_and_right;
3034+
popt->lrule[PRINT_RULE_TOP].midvrule = column->down_and_horizontal[opt->unicode_border_linestyle];
3035+
popt->lrule[PRINT_RULE_TOP].rightvrule = border->down_and_left;
3036+
3037+
popt->lrule[PRINT_RULE_MIDDLE].hrule = header->horizontal;
3038+
popt->lrule[PRINT_RULE_MIDDLE].leftvrule = header->vertical_and_right[opt->unicode_border_linestyle];
3039+
popt->lrule[PRINT_RULE_MIDDLE].midvrule = column->vertical_and_horizontal[opt->unicode_header_linestyle];
3040+
popt->lrule[PRINT_RULE_MIDDLE].rightvrule = header->vertical_and_left[opt->unicode_border_linestyle];
3041+
3042+
popt->lrule[PRINT_RULE_BOTTOM].hrule = border->horizontal;
3043+
popt->lrule[PRINT_RULE_BOTTOM].leftvrule = border->up_and_right;
3044+
popt->lrule[PRINT_RULE_BOTTOM].midvrule = column->up_and_horizontal[opt->unicode_border_linestyle];
3045+
popt->lrule[PRINT_RULE_BOTTOM].rightvrule = border->left_and_right;
3046+
3047+
/* N/A */
3048+
popt->lrule[PRINT_RULE_DATA].hrule = "";
3049+
popt->lrule[PRINT_RULE_DATA].leftvrule = border->vertical;
3050+
popt->lrule[PRINT_RULE_DATA].midvrule = column->vertical;
3051+
popt->lrule[PRINT_RULE_DATA].rightvrule = border->vertical;
3052+
3053+
popt->midvrule_nl = column->vertical;
3054+
popt->midvrule_wrap = column->vertical;
3055+
popt->midvrule_blank = column->vertical;
3056+
3057+
/* Same for all unicode today */
3058+
popt->header_nl_left = unicode_style.header_nl_left;
3059+
popt->header_nl_right = unicode_style.header_nl_right;
3060+
popt->nl_left = unicode_style.nl_left;
3061+
popt->nl_right = unicode_style.nl_right;
3062+
popt->wrap_left = unicode_style.wrap_left;
3063+
popt->wrap_right = unicode_style.wrap_right;
3064+
popt->wrap_right_border = unicode_style.wrap_right_border;
3065+
3066+
return;
3067+
}
3068+
29553069
/*
29563070
* Compute the byte distance to the end of the string or *target_width
29573071
* display character positions, whichever comes first. Update *target_width

0 commit comments

Comments
 (0)