libsmartcols: use ASCII art for trees rather than padding
Based on patch from Roman Odaisky. References: https://launchpad.net/bugs/1406133 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
2fa60c5ec2
commit
8501d9befe
|
@ -151,12 +151,103 @@ static size_t buffer_get_safe_art_size(struct libscols_buffer *buf)
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns pointer to the end of used data */
|
||||||
|
static int line_ascii_art_to_buffer(struct libscols_table *tb,
|
||||||
|
struct libscols_line *ln,
|
||||||
|
struct libscols_buffer *buf)
|
||||||
|
{
|
||||||
|
const char *art;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
assert(ln);
|
||||||
|
assert(buf);
|
||||||
|
|
||||||
|
if (!ln->parent)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = line_ascii_art_to_buffer(tb, ln->parent, buf);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch))
|
||||||
|
art = " ";
|
||||||
|
else
|
||||||
|
art = tb->symbols->vert;
|
||||||
|
|
||||||
|
return buffer_append_data(buf, art);
|
||||||
|
}
|
||||||
|
|
||||||
#define is_last_column(_tb, _cl) \
|
#define is_last_column(_tb, _cl) \
|
||||||
list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns)
|
list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns)
|
||||||
|
|
||||||
#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
|
#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
|
||||||
#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
|
#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
|
||||||
|
|
||||||
|
/* print padding or asci-art instead of data of @cl */
|
||||||
|
static void print_empty_cell(struct libscols_table *tb,
|
||||||
|
struct libscols_column *cl,
|
||||||
|
struct libscols_line *ln, /* optional */
|
||||||
|
size_t bufsz)
|
||||||
|
{
|
||||||
|
size_t len_pad = 0; /* in screen cells as opposed to bytes */
|
||||||
|
|
||||||
|
/* generate tree asci-art rather than padding */
|
||||||
|
if (ln && scols_column_is_tree(cl)) {
|
||||||
|
if (!ln->parent) {
|
||||||
|
/* only print symbols->vert if followed by something */
|
||||||
|
if (!list_empty(&ln->ln_branch)) {
|
||||||
|
fputs(tb->symbols->vert, tb->out);
|
||||||
|
len_pad = mbs_safe_width(tb->symbols->vert);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* use the same draw function as though we were intending to draw an L-shape */
|
||||||
|
struct libscols_buffer *art = new_buffer(bufsz);
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
if (art) {
|
||||||
|
/* whatever the rc, len_pad will be sensible */
|
||||||
|
line_ascii_art_to_buffer(tb, ln, art);
|
||||||
|
data = buffer_get_safe_data(art, &len_pad);
|
||||||
|
if (data && len_pad)
|
||||||
|
fputs(data, tb->out);
|
||||||
|
free_buffer(art);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* fill rest of cell with space */
|
||||||
|
for(; len_pad <= cl->width; ++len_pad)
|
||||||
|
fputc(' ', tb->out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill-in all line with padding (or tree asci-art)
|
||||||
|
*
|
||||||
|
* This is necessary after long non-truncated colum where next column
|
||||||
|
* is printed in next line. For example (see 'DDD'):
|
||||||
|
*
|
||||||
|
* aaa bbb ccc ddd eee
|
||||||
|
* AAA BBB CCCCCCC
|
||||||
|
* DDD EEE
|
||||||
|
* ^^^^^^^^^^^^
|
||||||
|
* new line padding
|
||||||
|
*/
|
||||||
|
static void print_newline_padding(struct libscols_table *tb,
|
||||||
|
struct libscols_column *cl,
|
||||||
|
struct libscols_line *ln, /* optional */
|
||||||
|
size_t bufsz,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
assert(tb);
|
||||||
|
assert(cl);
|
||||||
|
|
||||||
|
fputs(linesep(tb), tb->out); /* line break */
|
||||||
|
|
||||||
|
/* fill cells after line break */
|
||||||
|
for (i = 0; i <= (size_t) cl->seqnum; i++)
|
||||||
|
print_empty_cell(tb, scols_table_get_column(tb, i), ln, bufsz);
|
||||||
|
}
|
||||||
|
|
||||||
static int print_data(struct libscols_table *tb,
|
static int print_data(struct libscols_table *tb,
|
||||||
struct libscols_column *cl,
|
struct libscols_column *cl,
|
||||||
struct libscols_line *ln, /* optional */
|
struct libscols_line *ln, /* optional */
|
||||||
|
@ -252,46 +343,17 @@ static int print_data(struct libscols_table *tb,
|
||||||
fputs(data, tb->out);
|
fputs(data, tb->out);
|
||||||
}
|
}
|
||||||
for (i = len; i < width; i++)
|
for (i = len; i < width; i++)
|
||||||
fputs(" ", tb->out); /* padding */
|
fputc(' ', tb->out); /* padding */
|
||||||
|
|
||||||
if (!is_last_column(tb, cl)) {
|
if (is_last_column(tb, cl))
|
||||||
if (len > width && !scols_column_is_trunc(cl)) {
|
|
||||||
fputs(linesep(tb), tb->out);
|
|
||||||
for (i = 0; i <= (size_t) cl->seqnum; i++) {
|
|
||||||
struct libscols_column *x = scols_table_get_column(tb, i);
|
|
||||||
fprintf(tb->out, "%*s ", -((int)x->width), " ");
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
fputs(colsep(tb), tb->out); /* columns separator */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns pointer to the end of used data */
|
|
||||||
static int line_ascii_art_to_buffer(struct libscols_table *tb,
|
|
||||||
struct libscols_line *ln,
|
|
||||||
struct libscols_buffer *buf)
|
|
||||||
{
|
|
||||||
const char *art;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
assert(ln);
|
|
||||||
assert(buf);
|
|
||||||
|
|
||||||
if (!ln->parent)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = line_ascii_art_to_buffer(tb, ln->parent, buf);
|
if (len > width && !scols_column_is_trunc(cl))
|
||||||
if (rc)
|
print_newline_padding(tb, cl, ln, buf->bufsz, len); /* next column starts on next line */
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch))
|
|
||||||
art = " ";
|
|
||||||
else
|
else
|
||||||
art = tb->symbols->vert;
|
fputs(colsep(tb), tb->out); /* columns separator */
|
||||||
|
|
||||||
return buffer_append_data(buf, art);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cell_to_buffer(struct libscols_table *tb,
|
static int cell_to_buffer(struct libscols_table *tb,
|
||||||
|
|
Loading…
Reference in New Issue