pivot-table: Implement hiding footnotes.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 10 Jan 2021 02:27:36 +0000 (18:27 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 10 Jan 2021 02:27:36 +0000 (18:27 -0800)
doc/dev/spv-file-format.texi
src/output/cairo-fsm.c
src/output/html.c
src/output/odt.c
src/output/pivot-output.c
src/output/spv/spv-writer.c
src/output/tex.c
tests/output/pivot-table-test.c
tests/output/pivot-table.at

index 723550a3723ed8487e14b0d9c8f783b4480deed7..54decbcf52bfa7034c6b34bc4465115c7aa3451b 100644 (file)
@@ -1101,6 +1101,7 @@ reference other footnotes, but in practice this doesn't work.
 @code{show} is a 32-bit signed integer.  It is positive to show the
 footnote or negative to hide it.  Its magnitude is often 1, and in
 other cases tends to be the number of references to the footnote.
+It is safe to write 1 to show a footnote and -1 to hide it.
 
 @node SPV Light Member Areas
 @subsection Areas
index e427a4a5ed8ba9d4c816d9a6f849d116c6bbfdbd..2df39754343b966b3305c6a7393b17a3c9989625 100644 (file)
@@ -761,13 +761,17 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell,
         }
 
       size_t footnote_ofs = ds_length (&body);
+      size_t n_footnotes = 0;
       for (size_t i = 0; i < value->n_footnotes; i++)
         {
-          if (i)
-            ds_put_byte (&body, ',');
-
-          size_t idx = value->footnote_indexes[i];
-          pivot_footnote_format_marker (pt->footnotes[idx], pt, &body);
+          const struct pivot_footnote *f
+            = pt->footnotes[value->footnote_indexes[i]];
+          if (f->show)
+            {
+              if (n_footnotes++)
+                ds_put_byte (&body, ',');
+              pivot_footnote_format_marker (f, pt, &body);
+            }
         }
 
       /* Allow footnote markers to occupy the right margin.  That way, numbers
index 3f07adcfeebd1dd634d19ba55c296054a21f0e5b..644ef49eba9e84082141fc1d5ef1cbb917eb9231 100644 (file)
@@ -586,17 +586,20 @@ html_put_table_cell (struct html_driver *html, const struct pivot_table *pt,
   if (cell->value->n_footnotes > 0)
     {
       fputs ("<sup>", html->file);
+      size_t n_footnotes = 0;
       for (size_t i = 0; i < cell->value->n_footnotes; i++)
         {
-          if (i > 0)
-            putc (',', html->file);
-
-          size_t idx = cell->value->footnote_indexes[i];
-          const struct pivot_footnote *f = pt->footnotes[idx];
+          const struct pivot_footnote *f
+            = pt->footnotes[cell->value->footnote_indexes[i]];
+          if (f->show)
+            {
+              if (n_footnotes++ > 0)
+                putc (',', html->file);
 
-          char *marker = pivot_footnote_marker_string (f, pt);
-          escape_string (html->file, marker, " ", "<br>");
-          free (marker);
+              char *marker = pivot_footnote_marker_string (f, pt);
+              escape_string (html->file, marker, " ", "<br>");
+              free (marker);
+            }
         }
       fputs ("</sup>", html->file);
     }
index 406ef14069c32b31f2d1661f24343f2b540223e7..4a87815548d43b2473e58f977e233870470e2663 100644 (file)
@@ -423,14 +423,18 @@ write_footnotes (struct odt_driver *odt,
 {
   for (size_t i = 0; i < n_footnotes; i++)
     {
-      xmlTextWriterStartElement (odt->content_wtr, _xml("text:span"));
-      xmlTextWriterWriteAttribute (odt->content_wtr, _xml("text:style-name"),
-                                   _xml("superscript"));
       const struct pivot_footnote *f = pt->footnotes[footnote_indexes[i]];
-      char *s = pivot_footnote_marker_string (f, pt);
-      write_xml_with_line_breaks (odt, s);
-      free (s);
-      xmlTextWriterEndElement (odt->content_wtr);
+      if (f->show)
+        {
+          xmlTextWriterStartElement (odt->content_wtr, _xml("text:span"));
+          xmlTextWriterWriteAttribute (odt->content_wtr,
+                                       _xml("text:style-name"),
+                                       _xml("superscript"));
+          char *s = pivot_footnote_marker_string (f, pt);
+          write_xml_with_line_breaks (odt, s);
+          free (s);
+          xmlTextWriterEndElement (odt->content_wtr);
+        }
     }
 }
 
index b49805f91612da94f2a6941828799a676a2ca80d..0efba3e34b0e0a6922644e18338cf219c3fad5db 100644 (file)
@@ -401,7 +401,7 @@ add_references (const struct pivot_table *pt, const struct table *table,
                 size_t idx = cell.value->footnote_indexes[i];
                 assert (idx < pt->n_footnotes);
 
-                if (!refs[idx])
+                if (!refs[idx] && pt->footnotes[idx]->show)
                   {
                     refs[idx] = true;
                     (*n_refs)++;
index c8cb28e3750bb12b45556f67d21b37b2e3a20609..58cb308fadbaa1e563d3cc995dcc08a2e002692f 100644 (file)
@@ -857,9 +857,10 @@ put_light_table (struct buf *buf, uint64_t table_id,
   put_u32 (buf, table->n_footnotes);
   for (size_t i = 0; i < table->n_footnotes; i++)
     {
-      put_value (buf, table->footnotes[i]->content);
-      put_optional_value (buf, table->footnotes[i]->marker);
-      put_u32 (buf, 0);
+      const struct pivot_footnote *f = table->footnotes[i];
+      put_value (buf, f->content);
+      put_optional_value (buf, f->marker);
+      put_u32 (buf, f->show ? 1 : -1);
     }
 
   /* Areas. */
index e832db7d2acf34061af4a58db22bcd02b4fe5d0c..c5591011f8e81ea99b57d78897c0cf5f63fa8648 100644 (file)
@@ -389,16 +389,21 @@ tex_put_footnote_markers (struct tex_driver *tex,
                           const size_t *footnote_indexes,
                           size_t n_footnotes)
 {
-  if (n_footnotes > 0)
-    shipout (&tex->token_list, "$^{");
+  size_t n_visible = 0;
   for (size_t i = 0; i < n_footnotes; i++)
     {
       const struct pivot_footnote *f = pt->footnotes[footnote_indexes[i]];
-      char *marker = pivot_footnote_marker_string (f, pt);
-      tex_escape_string (tex, marker, true);
-      free (marker);
+      if (f->show)
+        {
+          if (!n_visible++)
+            shipout (&tex->token_list, "$^{");
+
+          char *marker = pivot_footnote_marker_string (f, pt);
+          tex_escape_string (tex, marker, true);
+          free (marker);
+        }
     }
-  if (n_footnotes > 0)
+  if (n_visible)
     shipout (&tex->token_list, "}$");
 }
 
index 04f3eb2401d4cdb9a30ead0a3971cf31c7f654a0..976abcd0d0007994124d58441dd2174369fdad5c 100644 (file)
@@ -934,7 +934,8 @@ read_footnote (struct lexer *lexer, struct pivot_table *pt)
   else
     marker = NULL;
 
-  pivot_table_create_footnote__ (pt, idx, marker, content);
+  bool show = !lex_match_id (lexer, "HIDE");
+  pivot_table_create_footnote__ (pt, idx, marker, content)->show = show;
 }
 
 static void
index 7f09330a15a80500e4e7e28fef2d256c9c3f466c..5e45563d666e7319fcf0c4e6ee6de23027686809 100644 (file)
@@ -471,6 +471,9 @@ AT_DATA([pivot.txt], [[
 /display
 /title "Pivot Table with Numeric Superscript Footnotes"[footnote 0]
 /look marker=numeric level=super
+/display
+/title "Hidden Footnote"[footnote 0]
+/footnote[0] "First footnote" marker="*" hide
 ]])
 AT_CHECK([pivot-table-test --table-look $srcdir/output/look.stt pivot.txt --box unicode], [0],
 [[Pivot Table with Alphabetic Subscript Footnotes[*]
@@ -524,6 +527,18 @@ Pivot Table with Numeric Superscript Footnotes[*]
 Caption[*]
 *. First footnote
 2. Second footnote
+
+Hidden Footnote[*]
+╭────────────┬──────────────────╮
+│            │       A[*]       │
+│            ├───────┬──────────┤
+│Corner[*][2]│  B[2] │  C[*][2] │
+├────────────┼───────┼──────────┤
+│D[2] E[*]   │    .00│   1.00[*]│
+│     F[*][2]│2.00[2]│3.00[*][2]│
+╰────────────┴───────┴──────────╯
+Caption[*]
+2. Second footnote
 ]])
 AT_CLEANUP