[A] Extended table border settings
This commit is contained in:
parent
b9110741e7
commit
33da7186ff
@ -101,6 +101,51 @@ FORT_EXTERN char* ft_to_string(const FTABLE *FORT_RESTRICT table);
|
|||||||
//FORT_EXTERN ssize_t ft_n_row_to_string(const FTABLE *FORT_RESTRICT table, size_t row, char *FORT_RESTRICT dst, size_t dst_len);
|
//FORT_EXTERN ssize_t ft_n_row_to_string(const FTABLE *FORT_RESTRICT table, size_t row, char *FORT_RESTRICT dst, size_t dst_len);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* TABLE BORDER
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TL TT TT TT TV TT TT TT TV TB TB TB TR <----- TopSeparator
|
||||||
|
* LL IV IV RR
|
||||||
|
* LH IH IH IH II IH IH IH II IH IH IH RH <----- InsideSeparator
|
||||||
|
* LL IV IV RR
|
||||||
|
* BL BB BB BB BV BB BB BB BV BB BB BB BR <----- BottomSeparator
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum HorSeparatorPos
|
||||||
|
{
|
||||||
|
TopSeparator,
|
||||||
|
InsideSeparator,
|
||||||
|
BottomSeparator
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BorderItemPos
|
||||||
|
{
|
||||||
|
TL_bip = 0,
|
||||||
|
TT_bip = 1,
|
||||||
|
TV_bip = 2,
|
||||||
|
TR_bip = 3,
|
||||||
|
|
||||||
|
LL_bip = 4,
|
||||||
|
IV_bip = 5,
|
||||||
|
RR_bip = 6,
|
||||||
|
|
||||||
|
LH_bip = 7,
|
||||||
|
IH_bip = 8,
|
||||||
|
II_bip = 9,
|
||||||
|
RH_bip = 10,
|
||||||
|
|
||||||
|
BL_bip = 11,
|
||||||
|
BB_bip = 12,
|
||||||
|
BV_bip = 13,
|
||||||
|
BR_bip = 14,
|
||||||
|
|
||||||
|
BorderItemPosSize
|
||||||
|
};
|
||||||
|
|
||||||
struct fort_table_options
|
struct fort_table_options
|
||||||
{
|
{
|
||||||
int cell_padding_top;
|
int cell_padding_top;
|
||||||
@ -108,10 +153,9 @@ struct fort_table_options
|
|||||||
int cell_padding_left;
|
int cell_padding_left;
|
||||||
int cell_padding_right;
|
int cell_padding_right;
|
||||||
int cell_empty_string_height;
|
int cell_empty_string_height;
|
||||||
char hor_separator;
|
|
||||||
char ver_separator;
|
char border_chars[BorderItemPosSize];
|
||||||
char header_hor_separator;
|
char header_border_chars[BorderItemPosSize];
|
||||||
char header_ver_separator;
|
|
||||||
};
|
};
|
||||||
typedef struct fort_table_options fort_table_options_t;
|
typedef struct fort_table_options fort_table_options_t;
|
||||||
|
|
||||||
|
107
src/fort.c
107
src/fort.c
@ -185,10 +185,23 @@ static fort_table_options_t g_table_options = {
|
|||||||
1, /* cell_padding_left */
|
1, /* cell_padding_left */
|
||||||
1, /* cell_padding_right */
|
1, /* cell_padding_right */
|
||||||
1, /* cell_empty_string_height */
|
1, /* cell_empty_string_height */
|
||||||
'=', /* hor_separator */
|
|
||||||
'|', /* ver_separator */
|
/* border_chars */
|
||||||
'=', /* header_hor_separator */
|
{
|
||||||
'|' /* header_ver_separator */
|
'=', '=', '=', '=',
|
||||||
|
'|', '|', '|',
|
||||||
|
'=', '=', '=', '=',
|
||||||
|
'=', '=', '=', '='
|
||||||
|
},
|
||||||
|
|
||||||
|
/* header_border_chars */
|
||||||
|
{
|
||||||
|
'=', '=', '=', '=',
|
||||||
|
'|', '|', '|',
|
||||||
|
'=', '=', '=', '=',
|
||||||
|
'=', '=', '=', '='
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -369,9 +382,10 @@ static const fort_cell_t *get_cell_c(const fort_row_t *row, size_t col)
|
|||||||
return get_cell((fort_row_t *)row, col);
|
return get_cell((fort_row_t *)row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_row_separator(char *buffer, size_t buffer_sz, size_t table_width,
|
static int print_row_separator(char *buffer, size_t buffer_sz,
|
||||||
|
const size_t *col_width_arr, size_t cols,
|
||||||
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
||||||
const context_t *context)
|
enum HorSeparatorPos separatorPos, const context_t *context)
|
||||||
{
|
{
|
||||||
#define CHECK_RESULT_AND_MOVE_DEV(statement) \
|
#define CHECK_RESULT_AND_MOVE_DEV(statement) \
|
||||||
k = statement; \
|
k = statement; \
|
||||||
@ -385,7 +399,6 @@ static int print_row_separator(char *buffer, size_t buffer_sz, size_t table_widt
|
|||||||
|
|
||||||
int dev = 0;
|
int dev = 0;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
const char *hor_separator = NULL;
|
|
||||||
|
|
||||||
const fort_row_t *main_row = NULL;
|
const fort_row_t *main_row = NULL;
|
||||||
if (upper_row != NULL && lower_row != NULL) {
|
if (upper_row != NULL && lower_row != NULL) {
|
||||||
@ -398,11 +411,55 @@ static int print_row_separator(char *buffer, size_t buffer_sz, size_t table_widt
|
|||||||
main_row = NULL;
|
main_row = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hor_separator = (main_row && main_row->is_header == F_TRUE)
|
/* Row separator anatomy
|
||||||
? &(context->header_hor_separator)
|
*
|
||||||
: &(context->hor_separator);
|
* L I I I IV I I I R
|
||||||
|
*/
|
||||||
|
const char *L = NULL;
|
||||||
|
const char *I = NULL;
|
||||||
|
const char *IV = NULL;
|
||||||
|
const char *R = NULL;
|
||||||
|
|
||||||
|
const char (*border_chars)[BorderItemPosSize] = NULL;
|
||||||
|
if (main_row && main_row->is_header == F_TRUE) {
|
||||||
|
border_chars = &context->header_border_chars;
|
||||||
|
} else {
|
||||||
|
border_chars = &context->border_chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (separatorPos) {
|
||||||
|
case TopSeparator:
|
||||||
|
L = &(*border_chars)[TL_bip];
|
||||||
|
I = &(*border_chars)[TT_bip];
|
||||||
|
IV = &(*border_chars)[TV_bip];
|
||||||
|
R = &(*border_chars)[TR_bip];
|
||||||
|
break;
|
||||||
|
case InsideSeparator:
|
||||||
|
L = &(*border_chars)[LH_bip];
|
||||||
|
I = &(*border_chars)[IH_bip];
|
||||||
|
IV = &(*border_chars)[II_bip];
|
||||||
|
R = &(*border_chars)[RH_bip];
|
||||||
|
break;
|
||||||
|
case BottomSeparator:
|
||||||
|
L = &(*border_chars)[BL_bip];
|
||||||
|
I = &(*border_chars)[BB_bip];
|
||||||
|
IV = &(*border_chars)[BV_bip];
|
||||||
|
R = &(*border_chars)[BR_bip];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cols; ++i) {
|
||||||
|
if (i == 0) {
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, 1, *L));
|
||||||
|
} else {
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, 1, *IV));
|
||||||
|
}
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, col_width_arr[i], *I));
|
||||||
|
}
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, 1, *R));
|
||||||
|
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, table_width - 1, *hor_separator));
|
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, 1, '\n'));
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, 1, '\n'));
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
@ -955,13 +1012,22 @@ static int snprintf_row(const fort_row_t *row, char *buffer, size_t buf_sz, size
|
|||||||
if (cols_in_row > col_width_arr_sz)
|
if (cols_in_row > col_width_arr_sz)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
const char *ver_separator = (row->is_header == F_TRUE)
|
/* Row separator anatomy
|
||||||
? &(context->header_ver_separator)
|
*
|
||||||
: &(context->ver_separator);
|
* L data IV data IV data R
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char (*bord_chars)[BorderItemPosSize] = (row->is_header)
|
||||||
|
? (&context->header_border_chars)
|
||||||
|
: (&context->border_chars);
|
||||||
|
const char *L = &(*bord_chars)[LL_bip];
|
||||||
|
const char *IV = &(*bord_chars)[IV_bip];
|
||||||
|
const char *R = &(*bord_chars)[RR_bip];
|
||||||
|
|
||||||
|
|
||||||
int dev = 0;
|
int dev = 0;
|
||||||
for (size_t i = 0; i < row_height; ++i) {
|
for (size_t i = 0; i < row_height; ++i) {
|
||||||
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, *ver_separator);
|
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, *L);
|
||||||
for (size_t j = 0; j < col_width_arr_sz; ++j) {
|
for (size_t j = 0; j < col_width_arr_sz; ++j) {
|
||||||
if (j < cols_in_row) {
|
if (j < cols_in_row) {
|
||||||
fort_cell_t *cell = *(fort_cell_t**)vector_at(row->cells, j);
|
fort_cell_t *cell = *(fort_cell_t**)vector_at(row->cells, j);
|
||||||
@ -969,7 +1035,11 @@ static int snprintf_row(const fort_row_t *row, char *buffer, size_t buf_sz, size
|
|||||||
} else {
|
} else {
|
||||||
dev += snprint_n_chars(buffer + dev, buf_sz - dev, col_width_arr[j], ' ');
|
dev += snprint_n_chars(buffer + dev, buf_sz - dev, col_width_arr[j], ' ');
|
||||||
}
|
}
|
||||||
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, *ver_separator);
|
if (j == col_width_arr_sz - 1) {
|
||||||
|
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, *R);
|
||||||
|
} else {
|
||||||
|
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, *IV);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, '\n');
|
dev += snprint_n_chars(buffer + dev, buf_sz - dev, 1, '\n');
|
||||||
}
|
}
|
||||||
@ -1120,12 +1190,13 @@ char* ft_to_string(const FTABLE *FORT_RESTRICT table)
|
|||||||
fort_row_t *cur_row = NULL;
|
fort_row_t *cur_row = NULL;
|
||||||
for (size_t i = 0; i < rows; ++i) {
|
for (size_t i = 0; i < rows; ++i) {
|
||||||
cur_row = *(fort_row_t**)vector_at(table->rows, i);
|
cur_row = *(fort_row_t**)vector_at(table->rows, i);
|
||||||
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, width, prev_row, cur_row, context));
|
enum HorSeparatorPos separatorPos = (i == 0) ? TopSeparator : InsideSeparator;
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, col_width_arr, cols, prev_row, cur_row, separatorPos, context));
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprintf_row(cur_row, buffer + dev, sz - dev, col_width_arr, cols, row_height_arr[i], context));
|
CHECK_RESULT_AND_MOVE_DEV(snprintf_row(cur_row, buffer + dev, sz - dev, col_width_arr, cols, row_height_arr[i], context));
|
||||||
prev_row = cur_row;
|
prev_row = cur_row;
|
||||||
}
|
}
|
||||||
cur_row = NULL;
|
cur_row = NULL;
|
||||||
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, width, prev_row, cur_row, context));
|
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, col_width_arr, cols, prev_row, cur_row, BottomSeparator, context));
|
||||||
|
|
||||||
|
|
||||||
F_FREE(col_width_arr);
|
F_FREE(col_width_arr);
|
||||||
|
@ -434,10 +434,23 @@ void test_table_options(void **state)
|
|||||||
WHEN("Changing cell separators") {
|
WHEN("Changing cell separators") {
|
||||||
fort_table_options_t table_options;
|
fort_table_options_t table_options;
|
||||||
memcpy(&table_options, &def_options, sizeof(fort_table_options_t));
|
memcpy(&table_options, &def_options, sizeof(fort_table_options_t));
|
||||||
table_options.hor_separator = '|';
|
|
||||||
table_options.ver_separator = '=';
|
#define BOR_CHARS table_options.border_chars
|
||||||
table_options.header_hor_separator = '*';
|
#define H_BOR_CHARS table_options.header_border_chars
|
||||||
table_options.header_ver_separator = 'v';
|
|
||||||
|
BOR_CHARS[TL_bip] = BOR_CHARS[TT_bip] = BOR_CHARS[TV_bip] = BOR_CHARS[TR_bip] = '|';
|
||||||
|
BOR_CHARS[LH_bip] = BOR_CHARS[IH_bip] = BOR_CHARS[II_bip] = BOR_CHARS[RH_bip] = '|';
|
||||||
|
BOR_CHARS[BL_bip] = BOR_CHARS[BB_bip] = BOR_CHARS[BV_bip] = BOR_CHARS[BR_bip] = '|';
|
||||||
|
BOR_CHARS[LL_bip] = BOR_CHARS[IV_bip] = BOR_CHARS[RR_bip] = '=';
|
||||||
|
|
||||||
|
|
||||||
|
H_BOR_CHARS[TL_bip] = H_BOR_CHARS[TT_bip] = H_BOR_CHARS[TV_bip] = H_BOR_CHARS[TR_bip] = '*';
|
||||||
|
H_BOR_CHARS[LH_bip] = H_BOR_CHARS[IH_bip] = H_BOR_CHARS[II_bip] = H_BOR_CHARS[RH_bip] = '*';
|
||||||
|
H_BOR_CHARS[BL_bip] = H_BOR_CHARS[BB_bip] = H_BOR_CHARS[BV_bip] = H_BOR_CHARS[BR_bip] = '*';
|
||||||
|
H_BOR_CHARS[LL_bip] = H_BOR_CHARS[IV_bip] = H_BOR_CHARS[RR_bip] = 'v';
|
||||||
|
|
||||||
|
#undef BOR_CHARS
|
||||||
|
#undef H_BOR_CHARS
|
||||||
|
|
||||||
ft_set_default_options(&table_options);
|
ft_set_default_options(&table_options);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user