From: Ben Pfaff Date: Thu, 31 Dec 2020 00:09:27 +0000 (-0800) Subject: work X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0625520a58e3cb811d699808e9df95593f7373a9;p=pspp work --- diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index 698141e080..179d7a812c 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -1066,6 +1066,7 @@ xr_fsm_create (const struct output_item *item_, .min_break = { [H] = style->min_break[H], [V] = style->min_break[V] }, .supports_margins = true, .rtl = render_direction_rtl (), + .printing = print, } }; diff --git a/src/output/csv.c b/src/output/csv.c index e4b1000769..3940ebe197 100644 --- a/src/output/csv.c +++ b/src/output/csv.c @@ -251,7 +251,7 @@ csv_output_table_layer (struct csv_driver *csv, const struct pivot_table *pt, const size_t *layer_indexes) { struct table *title, *layers, *body, *caption, *footnotes; - pivot_output (pt, layer_indexes, &title, &layers, &body, + pivot_output (pt, layer_indexes, true, &title, &layers, &body, &caption, &footnotes, NULL, NULL); csv_put_separator (csv); diff --git a/src/output/html.c b/src/output/html.c index 2dcdf52f06..740d04257d 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -623,7 +623,7 @@ html_output_table_layer (struct html_driver *html, const struct pivot_table *pt, const size_t *layer_indexes) { struct table *title, *layers, *body, *caption, *footnotes; - pivot_output (pt, layer_indexes, &title, &layers, &body, + pivot_output (pt, layer_indexes, true, &title, &layers, &body, &caption, &footnotes, NULL, NULL); fputs ("file); diff --git a/src/output/odt.c b/src/output/odt.c index 8d890e87e0..1d8127b96a 100644 --- a/src/output/odt.c +++ b/src/output/odt.c @@ -468,7 +468,7 @@ write_table_layer (struct odt_driver *odt, const struct pivot_table *pt, const size_t *layer_indexes) { struct table *title, *layers, *body, *caption, *footnotes; - pivot_output (pt, layer_indexes, &title, &layers, &body, + pivot_output (pt, layer_indexes, true, &title, &layers, &body, &caption, &footnotes, NULL, NULL); /* Write a heading for the table */ diff --git a/src/output/pivot-output.c b/src/output/pivot-output.c index a1fba1a3ba..6e31a7aab7 100644 --- a/src/output/pivot-output.c +++ b/src/output/pivot-output.c @@ -382,6 +382,7 @@ collect_footnotes (const struct pivot_table *pt, void pivot_output (const struct pivot_table *pt, const size_t *layer_indexes, + bool printing UNUSED, struct table **titlep, struct table **layersp, struct table **bodyp, @@ -409,6 +410,13 @@ pivot_output (const struct pivot_table *pt, body->styles[i] = table_area_style_override ( body->container, &pt->look->areas[i], NULL, NULL, false); + struct table_border_style borders[PIVOT_N_BORDERS]; + memcpy (borders, pt->look->borders, sizeof borders); + if (!printing && pt->show_grid_lines) + for (int b = 0; b < PIVOT_N_BORDERS; b++) + if (borders[b].stroke == TABLE_STROKE_NONE) + borders[b].stroke = TABLE_STROKE_DASHED; + for (size_t i = 0; i < PIVOT_N_BORDERS; i++) { const struct table_border_style *in = &pt->look->borders[i]; @@ -419,7 +427,7 @@ pivot_output (const struct pivot_table *pt, compose_headings (body, &pt->axes[PIVOT_AXIS_COLUMN], H, &pt->axes[PIVOT_AXIS_ROW], - pt->look->borders, + borders, PIVOT_BORDER_DIM_COL_HORZ, PIVOT_BORDER_DIM_COL_VERT, PIVOT_BORDER_CAT_COL_HORZ, @@ -433,7 +441,7 @@ pivot_output (const struct pivot_table *pt, compose_headings (body, &pt->axes[PIVOT_AXIS_ROW], V, &pt->axes[PIVOT_AXIS_COLUMN], - pt->look->borders, + borders, PIVOT_BORDER_DIM_ROW_VERT, PIVOT_BORDER_DIM_ROW_HORZ, PIVOT_BORDER_CAT_ROW_VERT, @@ -479,25 +487,25 @@ pivot_output (const struct pivot_table *pt, if (body->n[H] && body->n[V]) { table_hline ( - body, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_TOP), + body, get_table_rule (borders, PIVOT_BORDER_INNER_TOP), 0, body->n[H] - 1, 0); table_hline ( - body, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_BOTTOM), + body, get_table_rule (borders, PIVOT_BORDER_INNER_BOTTOM), 0, body->n[H] - 1, body->n[V]); table_vline ( - body, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_LEFT), + body, get_table_rule (borders, PIVOT_BORDER_INNER_LEFT), 0, 0, body->n[V] - 1); table_vline ( - body, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_RIGHT), + body, get_table_rule (borders, PIVOT_BORDER_INNER_RIGHT), body->n[H], 0, body->n[V] - 1); if (stub[V]) table_hline ( - body, get_table_rule (pt->look->borders, PIVOT_BORDER_DATA_TOP), + body, get_table_rule (borders, PIVOT_BORDER_DATA_TOP), 0, body->n[H] - 1, stub[V]); if (stub[H]) table_vline ( - body, get_table_rule (pt->look->borders, PIVOT_BORDER_DATA_LEFT), + body, get_table_rule (borders, PIVOT_BORDER_DATA_LEFT), stub[H], 0, body->n[V] - 1); } @@ -506,7 +514,7 @@ pivot_output (const struct pivot_table *pt, /* Title. */ struct table *title; - if (pt->title && titlep) + if (pt->title && pt->show_title && titlep) { title = create_aux_table (pt, 1, 1, PIVOT_AREA_TITLE); fill_cell (title, 0, 0, 0, 0, @@ -552,7 +560,7 @@ pivot_output (const struct pivot_table *pt, /* Caption. */ struct table *caption; - if (pt->caption && captionp) + if (pt->caption && pt->show_caption && captionp) { caption = create_aux_table (pt, 1, 1, PIVOT_AREA_CAPTION); fill_cell (caption, 0, 0, 0, 0, diff --git a/src/output/pivot-output.h b/src/output/pivot-output.h index 17118dfb21..f2feeb9599 100644 --- a/src/output/pivot-output.h +++ b/src/output/pivot-output.h @@ -32,6 +32,7 @@ size_t *pivot_output_next_layer (const struct pivot_table *, void pivot_output (const struct pivot_table *, const size_t *layer_indexes, + bool printing, struct table **titlep, struct table **layersp, struct table **bodyp, diff --git a/src/output/render.c b/src/output/render.c index b4c22b5163..23b43f2182 100644 --- a/src/output/render.c +++ b/src/output/render.c @@ -1523,8 +1523,8 @@ render_pager_create (const struct render_params *params, layer_indexes = pt->current_layer; struct table *title, *layers, *body, *caption, *footnotes; - pivot_output (pt, layer_indexes, &title, &layers, &body, &caption, - &footnotes, NULL, NULL); + pivot_output (pt, layer_indexes, params->printing, + &title, &layers, &body, &caption, &footnotes, NULL, NULL); /* Figure out the width of the body of the table. Use this to determine the base scale. */ diff --git a/src/output/render.h b/src/output/render.h index ff73c4e35a..bc8db241f8 100644 --- a/src/output/render.h +++ b/src/output/render.h @@ -79,6 +79,10 @@ struct render_params /* True if the local language has a right-to-left direction, otherwise false. (Use render_direction_rtl() to find out.) */ bool rtl; + + /* True if the table is being rendered for printing (as opposed to + on-screen display). */ + bool printing; }; struct render_ops diff --git a/src/output/tex.c b/src/output/tex.c index bf5eb7115e..684c5db468 100644 --- a/src/output/tex.c +++ b/src/output/tex.c @@ -413,7 +413,7 @@ tex_output_table_layer (struct tex_driver *tex, const struct pivot_table *pt, struct table *title, *layers, *body, *caption; struct pivot_footnote **footnotes; size_t n_footnotes; - pivot_output (pt, layer_indexes, &title, &layers, &body, + pivot_output (pt, layer_indexes, true, &title, &layers, &body, &caption, NULL, &footnotes, &n_footnotes); shipout (&tex->token_list, "\n{\\parindent=0pt\n"); diff --git a/tests/output/pivot-table-test.c b/tests/output/pivot-table-test.c index 8200c18737..44347fb4f2 100644 --- a/tests/output/pivot-table-test.c +++ b/tests/output/pivot-table-test.c @@ -30,6 +30,8 @@ #include "libpspp/i18n.h" #include "libpspp/string-map.h" #include "output/driver.h" +#include "output/message-item.h" +#include "output/options.h" #include "output/pivot-table.h" #include "output/table-item.h" @@ -50,6 +52,7 @@ static const char *output_base = "render"; static const char *parse_options (int argc, char **argv); static void usage (void) NO_RETURN; static struct pivot_table *read_table (struct lexer *); +static void output_msg (const struct msg *, void *); int main (int argc, char **argv) @@ -70,6 +73,7 @@ main (int argc, char **argv) exit (1); struct lexer *lexer = lex_create (); + msg_set_handler (output_msg, lexer); lex_include (lexer, reader); lex_get (lexer); @@ -169,6 +173,7 @@ parse_options (int argc, char **argv) OPT_MIN_BREAK, OPT_EMPHASIS, OPT_BOX, + OPT_TABLE_LOOK, OPT_HELP }; static const struct option options[] = @@ -179,6 +184,7 @@ parse_options (int argc, char **argv) {"emphasis", no_argument, NULL, OPT_EMPHASIS}, {"box", required_argument, NULL, OPT_BOX}, {"output", required_argument, NULL, 'o'}, + {"table-look", required_argument, NULL, OPT_TABLE_LOOK}, {"help", no_argument, NULL, OPT_HELP}, {NULL, 0, NULL, 0}, }; @@ -213,6 +219,17 @@ parse_options (int argc, char **argv) output_base = optarg; break; + case OPT_TABLE_LOOK: + { + struct pivot_table_look *look; + char *err = pivot_table_look_read (optarg, &look); + if (err) + error (1, 0, "%s", err); + pivot_table_look_set_default (look); + pivot_table_look_unref (look); + } + break; + case OPT_HELP: usage (); @@ -333,6 +350,32 @@ read_dimension (struct lexer *lexer, struct pivot_table *pt, read_group (lexer, pt, dim->root); } +static bool +parse_bool_setting (struct lexer *lexer, const char *name, + const char *true_kw, const char *false_kw, + bool *out) +{ + if (lex_match_id (lexer, name)) + { + if (!lex_force_match (lexer, T_EQUALS)) + exit (1); + + if (lex_match_id (lexer, true_kw)) + *out = true; + else if (lex_match_id (lexer, false_kw)) + *out = false; + else + { + lex_error_expecting (lexer, true_kw, false_kw); + exit (1); + } + + return true; + } + else + return false; +} + static void read_look (struct lexer *lexer, struct pivot_table *pt) { @@ -347,10 +390,121 @@ read_look (struct lexer *lexer, struct pivot_table *pt) msg (SE, "%s", error); exit (1); } + lex_get (lexer); pivot_table_set_look (pt, look); pivot_table_look_unref (look); } + + struct pivot_table_look *look = pivot_table_look_unshare ( + pivot_table_look_ref (pt->look)); + for (;;) + { + if (!parse_bool_setting (lexer, "EMPTY", "HIDE", "SHOW", + &look->omit_empty) + && !parse_bool_setting (lexer, "ROWLABELS", "CORNER", "NESTED", + &look->row_labels_in_corner) + && !parse_bool_setting (lexer, "MARKERS", "NUMERIC", "ALPHA", + &look->show_numeric_markers) + && !parse_bool_setting (lexer, "LEVEL", "SUPER", "SUB", + &look->footnote_marker_superscripts) + && !parse_bool_setting (lexer, "LAYERS", "CURRENT", "ALL", + &look->print_all_layers) + && !parse_bool_setting (lexer, "PAGINATELAYERS", "YES", "NO", + &look->paginate_layers) + && !parse_bool_setting (lexer, "HSHRINK", "YES", "NO", + &look->shrink_to_fit[TABLE_HORZ]) + && !parse_bool_setting (lexer, "VSHRINK", "YES", "NO", + &look->shrink_to_fit[TABLE_VERT]) + && !parse_bool_setting (lexer, "TOPCONTINUATION", "YES", "NO", + &look->top_continuation) + && !parse_bool_setting (lexer, "BOTTOMCONTINUATION", "YES", "NO", + &look->bottom_continuation)) + break; + } + pivot_table_set_look (pt, look); + pivot_table_look_unref (look); +} + +static enum table_stroke +read_stroke (struct lexer *lexer) +{ + for (int stroke = 0; stroke < TABLE_N_STROKES; stroke++) + if (lex_match_id (lexer, table_stroke_to_string (stroke))) + return stroke; + + lex_error (lexer, "expecting stroke"); + exit (1); +} + +static void +read_border (struct lexer *lexer, struct pivot_table *pt) +{ + static const char *const pivot_border_ids[PIVOT_N_BORDERS] = { + [PIVOT_BORDER_TITLE] = "title", + [PIVOT_BORDER_OUTER_LEFT] = "outer-left", + [PIVOT_BORDER_OUTER_TOP] = "outer-top", + [PIVOT_BORDER_OUTER_RIGHT] = "outer-right", + [PIVOT_BORDER_OUTER_BOTTOM] = "outer-bottom", + [PIVOT_BORDER_INNER_LEFT] = "inner-left", + [PIVOT_BORDER_INNER_TOP] = "inner-top", + [PIVOT_BORDER_INNER_RIGHT] = "inner-right", + [PIVOT_BORDER_INNER_BOTTOM] = "inner-bottom", + [PIVOT_BORDER_DATA_LEFT] = "data-left", + [PIVOT_BORDER_DATA_TOP] = "data-top", + [PIVOT_BORDER_DIM_ROW_HORZ] = "dim-row-horz", + [PIVOT_BORDER_DIM_ROW_VERT] = "dim-row-vert", + [PIVOT_BORDER_DIM_COL_HORZ] = "dim-col-horz", + [PIVOT_BORDER_DIM_COL_VERT] = "dim-col-vert", + [PIVOT_BORDER_CAT_ROW_HORZ] = "cat-row-horz", + [PIVOT_BORDER_CAT_ROW_VERT] = "cat-row-vert", + [PIVOT_BORDER_CAT_COL_HORZ] = "cat-col-horz", + [PIVOT_BORDER_CAT_COL_VERT] = "cat-col-vert", + }; + + lex_match (lexer, T_EQUALS); + + struct pivot_table_look *look = pivot_table_look_unshare ( + pivot_table_look_ref (pt->look)); + while (lex_token (lexer) == T_STRING) + { + char *s = xstrdup (lex_tokcstr (lexer)); + lex_get (lexer); + if (!lex_force_match (lexer, T_LPAREN)) + exit (1); + + struct table_border_style style = TABLE_BORDER_STYLE_INITIALIZER; + style.stroke = read_stroke (lexer); + if (lex_is_string (lexer)) + { + if (!parse_color__ (lex_tokcstr (lexer), &style.color)) + { + msg (SE, "%s: unknown color", lex_tokcstr (lexer)); + exit (1); + } + lex_get (lexer); + } + if (!lex_force_match (lexer, T_RPAREN)) + exit (1); + + int n = 0; + for (int b = 0; b < PIVOT_N_BORDERS; b++) + { + if (!strncmp (s, pivot_border_ids[b], strlen (s))) + { + look->borders[b] = style; + n++; + } + } + if (!n) + { + msg (SE, "%s: no matching borders", s); + exit (1); + } + free (s); + } + pivot_table_set_look (pt, look); + pivot_table_look_unref (look); } static struct pivot_table * @@ -359,6 +513,8 @@ read_table (struct lexer *lexer) struct pivot_table *pt = pivot_table_create__ (NULL, NULL); while (lex_match (lexer, T_SLASH)) { + assert (!pivot_table_is_shared (pt)); + if (lex_match_id (lexer, "ROW")) read_dimension (lexer, pt, PIVOT_AXIS_ROW); else if (lex_match_id (lexer, "COLUMN")) @@ -367,6 +523,30 @@ read_table (struct lexer *lexer) read_dimension (lexer, pt, PIVOT_AXIS_LAYER); else if (lex_match_id (lexer, "LOOK")) read_look (lexer, pt); + else if (lex_match_id (lexer, "ROTATE")) + { + lex_match (lexer, T_EQUALS); + while (lex_token (lexer) == T_ID) + if (!parse_bool_setting (lexer, "INNERCOLUMNS", "YES", "NO", + &pt->rotate_inner_column_labels) + && !parse_bool_setting (lexer, "OUTERROWS", "YES", "NO", + &pt->rotate_outer_row_labels)) + break; + } + else if (lex_match_id (lexer, "DISPLAY")) + { + lex_match (lexer, T_EQUALS); + while (lex_token (lexer) == T_ID) + if (!parse_bool_setting (lexer, "GRID", "YES", "NO", + &pt->show_grid_lines) + && !parse_bool_setting (lexer, "CAPTION", "YES", "NO", + &pt->show_caption) + && !parse_bool_setting (lexer, "TITLE", "YES", "NO", + &pt->show_caption)) + break; + } + else if (lex_match_id (lexer, "BORDER")) + read_border (lexer, pt); else { msg (SE, "Expecting keyword"); @@ -378,3 +558,23 @@ read_table (struct lexer *lexer) exit (1); return pt; } + +static void +output_msg (const struct msg *m_, void *lexer_) +{ + struct lexer *lexer = lexer_; + struct msg m = *m_; + + if (m.file_name == NULL) + { + m.file_name = CONST_CAST (char *, lex_get_file_name (lexer)); + m.first_line = lex_get_first_line_number (lexer, 0); + m.last_line = lex_get_last_line_number (lexer, 0); + } + + m.command_name = output_get_command_name (); + + message_item_submit (message_item_create (&m)); + + free (m.command_name); +}