X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fpivot-table.c;h=55559773c87217cbdec3dbb2060e732f10175e4b;hb=dd45af75d87c680c7de07d591095751a0d75e49a;hp=671544ef06906a513e8c5099827fccc2b1b7f3a4;hpb=2b29f671e938c39ab6c4f198e685951552b9cae8;p=pspp diff --git a/src/output/pivot-table.c b/src/output/pivot-table.c index 671544ef06..55559773c8 100644 --- a/src/output/pivot-table.c +++ b/src/output/pivot-table.c @@ -18,6 +18,8 @@ #include "output/pivot-table.h" +#include +#include #include #include @@ -870,7 +872,7 @@ pivot_table_create__ (struct pivot_value *title, const char *subtype) table->weight_format = (struct fmt_spec) { FMT_F, 40, 0 }; table->title = title; table->subtype = subtype ? pivot_value_new_text (subtype) : NULL; - table->command_c = output_get_command_name (); + table->command_c = xstrdup_if_nonempty (output_get_command_name ()); table->look = pivot_table_look_ref (pivot_table_look_get_default ()); table->settings = fmt_settings_copy (settings_get_fmt_settings ()); table->small = settings_get_small (); @@ -911,12 +913,6 @@ pivot_table_ref (const struct pivot_table *table_) return table; } -static char * -xstrdup_if_nonnull (const char *s) -{ - return s ? xstrdup (s) : NULL; -} - static struct pivot_table_sizing clone_sizing (const struct pivot_table_sizing *s) { @@ -1505,15 +1501,30 @@ pivot_table_create_footnote (struct pivot_table *table, NULL, content); } -static struct pivot_value * -pivot_make_default_footnote_marker (int idx, bool show_numeric_markers) -{ - char text[INT_BUFSIZE_BOUND (size_t)]; - if (show_numeric_markers) - snprintf (text, sizeof text, "%d", idx + 1); +void +pivot_footnote_format_marker (const struct pivot_footnote *f, + const struct pivot_table *pt, + struct string *s) +{ + if (f->marker) + pivot_value_format_body (f->marker, pt, s); + else if (pt->look->show_numeric_markers) + ds_put_format (s, "%zu", f->idx + 1); else - str_format_26adic (idx + 1, false, text, sizeof text); - return pivot_value_new_user_text (text, -1); + { + char text[INT_BUFSIZE_BOUND (size_t)]; + str_format_26adic (f->idx + 1, false, text, sizeof text); + ds_put_cstr (s, text); + } +} + +char * +pivot_footnote_marker_string (const struct pivot_footnote *f, + const struct pivot_table *pt) +{ + struct string s = DS_EMPTY_INITIALIZER; + pivot_footnote_format_marker (f, pt, &s); + return ds_steal_cstr (&s); } /* Creates or modifies a footnote in TABLE with 0-based number IDX (and creates @@ -1533,12 +1544,10 @@ pivot_table_create_footnote__ (struct pivot_table *table, size_t idx, while (idx >= table->n_footnotes) { struct pivot_footnote *f = xmalloc (sizeof *f); - f->idx = table->n_footnotes; - f->marker = pivot_make_default_footnote_marker ( - f->idx, table->look->show_numeric_markers); - f->content = NULL; - f->show = true; - + *f = (struct pivot_footnote) { + .idx = table->n_footnotes, + .show = true, + }; table->footnotes[table->n_footnotes++] = f; } } @@ -2288,6 +2297,33 @@ interpret_show (enum settings_value_show global_show, : global_show); } +/* Appends to OUT the actual text content from the given Pango MARKUP. */ +static void +get_text_from_markup (const char *markup, struct string *out) +{ + xmlParserCtxt *parser = xmlCreatePushParserCtxt (NULL, NULL, NULL, 0, NULL); + if (!parser) + { + ds_put_cstr (out, markup); + return; + } + + xmlParseChunk (parser, "", strlen (""), false); + xmlParseChunk (parser, markup, strlen (markup), false); + xmlParseChunk (parser, "", strlen (""), true); + + if (parser->wellFormed) + { + xmlChar *s = xmlNodeGetContent (xmlDocGetRootElement (parser->myDoc)); + ds_put_cstr (out, CHAR_CAST (char *, s)); + xmlFree (s); + } + else + ds_put_cstr (out, markup); + xmlFreeDoc (parser->myDoc); + xmlFreeParserCtxt (parser); +} + /* Appends a text representation of the body of VALUE to OUT. Settings on PT control whether variable and value labels are included. @@ -2375,7 +2411,10 @@ pivot_value_format_body (const struct pivot_value *value, break; case PIVOT_VALUE_TEXT: - ds_put_cstr (out, value->text.local); + if (value->font_style && value->font_style->markup) + get_text_from_markup (value->text.local, out); + else + ds_put_cstr (out, value->text.local); break; case PIVOT_VALUE_TEMPLATE: @@ -2390,13 +2429,16 @@ pivot_value_format_body (const struct pivot_value *value, /* Appends a text representation of VALUE to OUT. Settings on PT control whether variable and value labels are included. - Subscripts and footnotes are included. */ -void + Subscripts and footnotes are included. + + Returns true if OUT is a number (or a number plus a value label), false + otherwise. */ +bool pivot_value_format (const struct pivot_value *value, const struct pivot_table *pt, struct string *out) { - pivot_value_format_body (value, pt, out); + bool numeric = pivot_value_format_body (value, pt, out); if (value->n_subscripts) { @@ -2410,10 +2452,12 @@ pivot_value_format (const struct pivot_value *value, size_t idx = value->footnote_indexes[i]; const struct pivot_footnote *f = pt->footnotes[idx]; - pivot_value_format (f->marker, pt, out); + pivot_footnote_format_marker (f, pt, out); ds_put_byte (out, ']'); } + + return numeric; } /* Returns a text representation of VALUE. The caller must free the string, @@ -2433,6 +2477,7 @@ pivot_value_to_string_defaults (const struct pivot_value *value) static const struct pivot_table pt = { .show_values = SETTINGS_VALUE_SHOW_DEFAULT, .show_variables = SETTINGS_VALUE_SHOW_DEFAULT, + .settings = FMT_SETTINGS_INIT, }; return pivot_value_to_string (value, &pt); } @@ -2841,6 +2886,29 @@ pivot_value_add_footnote (struct pivot_value *v, v->footnote_indexes = xrealloc ( v->footnote_indexes, (v->n_footnotes + 1) * sizeof *v->footnote_indexes); v->footnote_indexes[v->n_footnotes++] = footnote->idx; + pivot_value_sort_footnotes (v); +} + +static int +compare_footnote_indexes (const void *a_, const void *b_) +{ + const size_t *ap = a_; + const size_t *bp = b_; + size_t a = *ap; + size_t b = *bp; + return a < b ? -1 : a > b; +} + +/* Sorts the footnote references in V in the standard ascending order. + + This is only necessary if code adds (plural) footnotes to a pivot_value by + itself, because pivot_value_add_footnote() does it automatically. */ +void +pivot_value_sort_footnotes (struct pivot_value *v) +{ + if (v->n_footnotes > 1) + qsort (v->footnote_indexes, v->n_footnotes, sizeof *v->footnote_indexes, + compare_footnote_indexes); } /* If VALUE is a numeric value, and RC is a result class such as