lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 1aa42aa 1/3: Move page_count() to tabular-rep


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 1aa42aa 1/3: Move page_count() to tabular-reports TU
Date: Mon, 3 Sep 2018 17:39:19 -0400 (EDT)

branch: master
commit 1aa42aa2f13c87d5158f5b4773be1c3652844d23
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Move page_count() to tabular-reports TU
---
 ledger_pdf_generator_wx.cpp |   3 +-
 miscellany.cpp              |  75 -----------------------------
 miscellany.hpp              |   6 ---
 miscellany_test.cpp         |  96 ------------------------------------
 report_table.cpp            |  75 +++++++++++++++++++++++++++++
 report_table.hpp            |   8 +++
 report_table_test.cpp       | 115 ++++++++++++++++++++++++++++++++++++++++----
 7 files changed, 191 insertions(+), 187 deletions(-)

diff --git a/ledger_pdf_generator_wx.cpp b/ledger_pdf_generator_wx.cpp
index b616837..659054a 100644
--- a/ledger_pdf_generator_wx.cpp
+++ b/ledger_pdf_generator_wx.cpp
@@ -36,9 +36,10 @@
 #include "ledger_evaluator.hpp"
 #include "ledger_invariant.hpp"
 #include "ledger_variant.hpp"
-#include "miscellany.hpp"               // lmi_tolower(), page_count()
+#include "miscellany.hpp"               // lmi_tolower()
 #include "oecumenic_enumerations.hpp"
 #include "pdf_writer_wx.hpp"
+#include "report_table.hpp"             // page_count()
 #include "ssize_lmi.hpp"
 #include "wx_table_generator.hpp"
 
diff --git a/miscellany.cpp b/miscellany.cpp
index 83e9450..4be7039 100644
--- a/miscellany.cpp
+++ b/miscellany.cpp
@@ -25,7 +25,6 @@
 
 #include "alert.hpp"
 #include "assert_lmi.hpp"
-#include "math_functions.hpp"           // outward_quotient()
 #include "ssize_lmi.hpp"
 
 #include <algorithm>                    // equal(), max()
@@ -291,77 +290,3 @@ std::string iso_8601_datestamp_terse()
     LMI_ASSERT(0 != rc);
     return s;
 }
-
-/// Number of pages needed to display the given number of data
-/// rows in groups of the given size separated by blank lines.
-///
-/// Nomenclature:
-///  - a 'line' is a printable zone of unit height;
-///  - a 'row' is a series of data to be shown side by side.
-/// With quinquennial spacing, the Morse alphabet is printed thus:
-///
-///   A   .-     line  0   row  0
-///   B   -...   line  1   row  1
-///   C   -.-.   line  2   row  2
-///   D   -..    line  3   row  3
-///   E   .      line  4   row  4
-///   [blank]    line  5
-///   F   ..-.   line  6   row  5
-///   G   --.    line  7   row  6
-///   ...
-///   Z   --..   line 30   row 25
-///
-/// with a page length of 50 lines. With a page length of 25 lines,
-/// the first page would end with
-///   T   -      line 22   row 19
-/// and the second page would be printed thus:
-///
-///   U   ..-    line  0   row 20
-///   V   ...-   line  1   row 21
-///   W   .--    line  2   row 22
-///   X   -..-   line  3   row 23
-///   Y   -.--   line  4   row 24
-///   [blank]    line  5
-///   Z   --..   line  6   row 25
-///
-/// Preconditions: 0 <= total_rows && 0 < rows_per_group <= lines_per_page
-
-int page_count
-    (int total_rows
-    ,int rows_per_group
-    ,int lines_per_page
-    )
-{
-    LMI_ASSERT(0 <= total_rows);
-    LMI_ASSERT(0 <  rows_per_group                  );
-    LMI_ASSERT(     rows_per_group <= lines_per_page);
-
-    // If there are zero rows of data, then one empty page is wanted.
-    if(0 == total_rows)
-        return 1;
-
-    // "+ 1": blank-line separator after each group.
-    int const lines_per_group = rows_per_group + 1;
-
-    // "+ 1": no blank-line separator after the last group.
-    int const groups_per_page = (lines_per_page + 1) / lines_per_group;
-
-    int const rows_per_page = rows_per_group * groups_per_page;
-
-    int number_of_pages = outward_quotient(total_rows, rows_per_page);
-
-    // Avoid widowing a partial group on the last page, by moving it
-    // to the preceding page if there's room.
-    if(1 < number_of_pages)
-        {
-        auto const rows_on_last_page = total_rows - (number_of_pages - 1) * 
rows_per_page;
-        auto const free_lines = lines_per_page - lines_per_group * 
groups_per_page;
-        LMI_ASSERT(free_lines < rows_per_group);
-        if(rows_on_last_page <= free_lines)
-            {
-            --number_of_pages;
-            }
-        }
-
-    return number_of_pages;
-}
diff --git a/miscellany.hpp b/miscellany.hpp
index 69dc12b..95d23b0 100644
--- a/miscellany.hpp
+++ b/miscellany.hpp
@@ -199,12 +199,6 @@ inline unsigned char lmi_toupper(unsigned char c)
     return static_cast<unsigned char>(std::toupper(c));
 }
 
-int LMI_SO page_count
-    (int total_rows
-    ,int rows_per_group
-    ,int lines_per_page
-    );
-
 /// DWISOTT
 ///
 /// Perhaps this function template's only legitimate use is within a
diff --git a/miscellany_test.cpp b/miscellany_test.cpp
index eaafa73..e4c1a16 100644
--- a/miscellany_test.cpp
+++ b/miscellany_test.cpp
@@ -152,101 +152,6 @@ void test_minmax()
     BOOST_TEST(!(zero <  m || m <  one));
 }
 
-void test_page_count()
-{
-    // Original tests: vary only the number of data rows.
-
-    // Edge cases.
-    BOOST_TEST_EQUAL(1, page_count( 0, 5, 28));
-    BOOST_TEST_EQUAL(1, page_count( 1, 5, 28));
-    // Just a trivial sanity test.
-    BOOST_TEST_EQUAL(1, page_count(17, 5, 28));
-    // 4 full groups + incomplete last group.
-    BOOST_TEST_EQUAL(1, page_count(24, 5, 28));
-    // 5 full groups don't fit on one page.
-    BOOST_TEST_EQUAL(2, page_count(25, 5, 28));
-    // 4 + 4 groups + incomplete last one.
-    BOOST_TEST_EQUAL(2, page_count(44, 5, 28));
-    // 9 full groups don't fit on two pages.
-    BOOST_TEST_EQUAL(3, page_count(45, 5, 28));
-
-    // Test preconditions.
-
-    // Negative number of data rows.
-    BOOST_TEST_THROW
-        (page_count(-1, 1, 1)
-        ,std::runtime_error
-        ,lmi_test::what_regex("^Assertion.*failed")
-        );
-
-    // Zero rows per group.
-    BOOST_TEST_THROW
-        (page_count(1, 0, 1)
-        ,std::runtime_error
-        ,lmi_test::what_regex("^Assertion.*failed")
-        );
-
-    // Insufficient room to print even one group.
-    BOOST_TEST_THROW
-        (page_count(1, 7, 3)
-        ,std::runtime_error
-        ,lmi_test::what_regex("^Assertion.*failed")
-        );
-
-    // A single row of data.
-    BOOST_TEST_EQUAL(1, page_count(1, 1, 1));
-    BOOST_TEST_EQUAL(1, page_count(1, 1, 3));
-    BOOST_TEST_EQUAL(1, page_count(1, 3, 3));
-    BOOST_TEST_EQUAL(1, page_count(1, 3, 7));
-
-    // One-row groups:
-
-    // Page length an odd number.
-    BOOST_TEST_EQUAL(1, page_count(1, 1, 5));
-    BOOST_TEST_EQUAL(1, page_count(3, 1, 5));
-    BOOST_TEST_EQUAL(2, page_count(4, 1, 5));
-    BOOST_TEST_EQUAL(2, page_count(6, 1, 5));
-    BOOST_TEST_EQUAL(3, page_count(7, 1, 5));
-
-    // Same, but next even length: same outcome.
-    BOOST_TEST_EQUAL(1, page_count(1, 1, 6));
-    BOOST_TEST_EQUAL(1, page_count(3, 1, 6));
-    BOOST_TEST_EQUAL(2, page_count(4, 1, 6));
-    BOOST_TEST_EQUAL(2, page_count(6, 1, 6));
-    BOOST_TEST_EQUAL(3, page_count(7, 1, 6));
-
-    // Two-row groups.
-
-    // Page length four.
-    BOOST_TEST_EQUAL(1, page_count(1, 2, 4));
-    BOOST_TEST_EQUAL(1, page_count(3, 2, 4));
-    BOOST_TEST_EQUAL(2, page_count(4, 2, 4));
-    BOOST_TEST_EQUAL(2, page_count(5, 2, 4));
-    BOOST_TEST_EQUAL(3, page_count(6, 2, 4));
-
-    // Page length five: no room for widow and orphan control.
-    BOOST_TEST_EQUAL(1, page_count(1, 2, 5));
-    BOOST_TEST_EQUAL(1, page_count(4, 2, 5));
-    BOOST_TEST_EQUAL(2, page_count(5, 2, 5));
-    BOOST_TEST_EQUAL(2, page_count(8, 2, 5));
-    BOOST_TEST_EQUAL(3, page_count(9, 2, 5));
-
-    // Same, but next even length: same outcome.
-    BOOST_TEST_EQUAL(1, page_count(1, 2, 6));
-    BOOST_TEST_EQUAL(1, page_count(4, 2, 6));
-    BOOST_TEST_EQUAL(2, page_count(5, 2, 6));
-    BOOST_TEST_EQUAL(2, page_count(8, 2, 6));
-    BOOST_TEST_EQUAL(3, page_count(9, 2, 6));
-
-    // Page length seven: one extra data row possible on last page.
-    BOOST_TEST_EQUAL(1, page_count(1, 2, 7));
-    BOOST_TEST_EQUAL(1, page_count(4, 2, 7));
-    BOOST_TEST_EQUAL(1, page_count(5, 2, 7));
-    BOOST_TEST_EQUAL(2, page_count(6, 2, 7));
-    BOOST_TEST_EQUAL(2, page_count(8, 2, 7));
-    BOOST_TEST_EQUAL(2, page_count(9, 2, 7));
-}
-
 void test_prefix_and_suffix()
 {
     std::string s = "";
@@ -496,7 +401,6 @@ int test_main(int, char*[])
     test_each_equal();
     test_files_are_identical();
     test_minmax();
-    test_page_count();
     test_prefix_and_suffix();
     test_scale_power();
     test_trimming();
diff --git a/report_table.cpp b/report_table.cpp
index 308cc19..8869ba7 100644
--- a/report_table.cpp
+++ b/report_table.cpp
@@ -25,6 +25,7 @@
 
 #include "alert.hpp"
 #include "assert_lmi.hpp"
+#include "math_functions.hpp"           // outward_quotient()
 #include "ssize_lmi.hpp"
 
 #include <algorithm>                    // min()
@@ -173,3 +174,77 @@ std::vector<int> set_column_widths
 
     return w;
 }
+
+/// Number of pages needed to display the given number of data
+/// rows in groups of the given size separated by blank lines.
+///
+/// Nomenclature:
+///  - a 'line' is a printable zone of unit height;
+///  - a 'row' is a series of data to be shown side by side.
+/// With quinquennial spacing, the Morse alphabet is printed thus:
+///
+///   A   .-     line  0   row  0
+///   B   -...   line  1   row  1
+///   C   -.-.   line  2   row  2
+///   D   -..    line  3   row  3
+///   E   .      line  4   row  4
+///   [blank]    line  5
+///   F   ..-.   line  6   row  5
+///   G   --.    line  7   row  6
+///   ...
+///   Z   --..   line 30   row 25
+///
+/// with a page length of 50 lines. With a page length of 25 lines,
+/// the first page would end with
+///   T   -      line 22   row 19
+/// and the second page would be printed thus:
+///
+///   U   ..-    line  0   row 20
+///   V   ...-   line  1   row 21
+///   W   .--    line  2   row 22
+///   X   -..-   line  3   row 23
+///   Y   -.--   line  4   row 24
+///   [blank]    line  5
+///   Z   --..   line  6   row 25
+///
+/// Preconditions: 0 <= total_rows && 0 < rows_per_group <= lines_per_page
+
+int page_count
+    (int total_rows
+    ,int rows_per_group
+    ,int lines_per_page
+    )
+{
+    LMI_ASSERT(0 <= total_rows);
+    LMI_ASSERT(0 <  rows_per_group                  );
+    LMI_ASSERT(     rows_per_group <= lines_per_page);
+
+    // If there are zero rows of data, then one empty page is wanted.
+    if(0 == total_rows)
+        return 1;
+
+    // "+ 1": blank-line separator after each group.
+    int const lines_per_group = rows_per_group + 1;
+
+    // "+ 1": no blank-line separator after the last group.
+    int const groups_per_page = (lines_per_page + 1) / lines_per_group;
+
+    int const rows_per_page = rows_per_group * groups_per_page;
+
+    int number_of_pages = outward_quotient(total_rows, rows_per_page);
+
+    // Avoid widowing a partial group on the last page, by moving it
+    // to the preceding page if there's room.
+    if(1 < number_of_pages)
+        {
+        auto const rows_on_last_page = total_rows - (number_of_pages - 1) * 
rows_per_page;
+        auto const free_lines = lines_per_page - lines_per_group * 
groups_per_page;
+        LMI_ASSERT(free_lines < rows_per_group);
+        if(rows_on_last_page <= free_lines)
+            {
+            --number_of_pages;
+            }
+        }
+
+    return number_of_pages;
+}
diff --git a/report_table.hpp b/report_table.hpp
index 0147223..1ff00c8 100644
--- a/report_table.hpp
+++ b/report_table.hpp
@@ -103,4 +103,12 @@ std::vector<int> LMI_SO set_column_widths
     ,int                                   minimum_margin
     );
 
+class paginator; // Coming soon.
+
+int LMI_SO page_count
+    (int total_rows
+    ,int rows_per_group
+    ,int lines_per_page
+    );
+
 #endif // report_table_hpp
diff --git a/report_table_test.cpp b/report_table_test.cpp
index 4a5f1e9..149d7e3 100644
--- a/report_table_test.cpp
+++ b/report_table_test.cpp
@@ -80,17 +80,19 @@ class report_table_test
         {
         test_apportion();
         test_bloat();
-        test_generally();
-        test_group_quote();
-        test_illustration();
+        test_column_widths_generally();
+        test_column_widths_for_group_quotes();
+        test_column_widths_for_illustrations();
+        test_paginator();
         }
 
   private:
     static void test_apportion();
     static void test_bloat();
-    static void test_generally();
-    static void test_group_quote();
-    static void test_illustration();
+    static void test_column_widths_generally();
+    static void test_column_widths_for_group_quotes();
+    static void test_column_widths_for_illustrations();
+    static void test_paginator();
 };
 
 void report_table_test::test_apportion()
@@ -171,7 +173,7 @@ void report_table_test::test_bloat()
     BOOST_TEST(v == bloat({3, 1, 0, 0, 2}, {0, 1, 0, 1, 0}));
 }
 
-void report_table_test::test_generally()
+void report_table_test::test_column_widths_generally()
 {
     std::vector<table_column_info> v;
     std::vector<int> expected;
@@ -278,7 +280,7 @@ void report_table_test::test_generally()
 /// group quote. Therefore, they aren't written in a compact way
 /// or expanded by bloat().
 
-void report_table_test::test_group_quote()
+void report_table_test::test_column_widths_for_group_quotes()
 {
     static int const total_width    = 756;
     static int const default_margin = 14;
@@ -309,7 +311,7 @@ void report_table_test::test_group_quote()
 /// illustrations. Therefore, they aren't written in a compact way
 /// or expanded by bloat().
 
-void report_table_test::test_illustration()
+void report_table_test::test_column_widths_for_illustrations()
 {
     static int const total_width    = 576;
     static int const default_margin = 14;
@@ -402,3 +404,98 @@ int test_main(int, char*[])
     report_table_test::test();
     return EXIT_SUCCESS;
 }
+
+void report_table_test::test_paginator()
+{
+    // Original tests: vary only the number of data rows.
+
+    // Edge cases.
+    BOOST_TEST_EQUAL(1, page_count( 0, 5, 28));
+    BOOST_TEST_EQUAL(1, page_count( 1, 5, 28));
+    // Just a trivial sanity test.
+    BOOST_TEST_EQUAL(1, page_count(17, 5, 28));
+    // 4 full groups + incomplete last group.
+    BOOST_TEST_EQUAL(1, page_count(24, 5, 28));
+    // 5 full groups don't fit on one page.
+    BOOST_TEST_EQUAL(2, page_count(25, 5, 28));
+    // 4 + 4 groups + incomplete last one.
+    BOOST_TEST_EQUAL(2, page_count(44, 5, 28));
+    // 9 full groups don't fit on two pages.
+    BOOST_TEST_EQUAL(3, page_count(45, 5, 28));
+
+    // Test preconditions.
+
+    // Negative number of data rows.
+    BOOST_TEST_THROW
+        (page_count(-1, 1, 1)
+        ,std::runtime_error
+        ,lmi_test::what_regex("^Assertion.*failed")
+        );
+
+    // Zero rows per group.
+    BOOST_TEST_THROW
+        (page_count(1, 0, 1)
+        ,std::runtime_error
+        ,lmi_test::what_regex("^Assertion.*failed")
+        );
+
+    // Insufficient room to print even one group.
+    BOOST_TEST_THROW
+        (page_count(1, 7, 3)
+        ,std::runtime_error
+        ,lmi_test::what_regex("^Assertion.*failed")
+        );
+
+    // A single row of data.
+    BOOST_TEST_EQUAL(1, page_count(1, 1, 1));
+    BOOST_TEST_EQUAL(1, page_count(1, 1, 3));
+    BOOST_TEST_EQUAL(1, page_count(1, 3, 3));
+    BOOST_TEST_EQUAL(1, page_count(1, 3, 7));
+
+    // One-row groups:
+
+    // Page length an odd number.
+    BOOST_TEST_EQUAL(1, page_count(1, 1, 5));
+    BOOST_TEST_EQUAL(1, page_count(3, 1, 5));
+    BOOST_TEST_EQUAL(2, page_count(4, 1, 5));
+    BOOST_TEST_EQUAL(2, page_count(6, 1, 5));
+    BOOST_TEST_EQUAL(3, page_count(7, 1, 5));
+
+    // Same, but next even length: same outcome.
+    BOOST_TEST_EQUAL(1, page_count(1, 1, 6));
+    BOOST_TEST_EQUAL(1, page_count(3, 1, 6));
+    BOOST_TEST_EQUAL(2, page_count(4, 1, 6));
+    BOOST_TEST_EQUAL(2, page_count(6, 1, 6));
+    BOOST_TEST_EQUAL(3, page_count(7, 1, 6));
+
+    // Two-row groups.
+
+    // Page length four.
+    BOOST_TEST_EQUAL(1, page_count(1, 2, 4));
+    BOOST_TEST_EQUAL(1, page_count(3, 2, 4));
+    BOOST_TEST_EQUAL(2, page_count(4, 2, 4));
+    BOOST_TEST_EQUAL(2, page_count(5, 2, 4));
+    BOOST_TEST_EQUAL(3, page_count(6, 2, 4));
+
+    // Page length five: no room for widow and orphan control.
+    BOOST_TEST_EQUAL(1, page_count(1, 2, 5));
+    BOOST_TEST_EQUAL(1, page_count(4, 2, 5));
+    BOOST_TEST_EQUAL(2, page_count(5, 2, 5));
+    BOOST_TEST_EQUAL(2, page_count(8, 2, 5));
+    BOOST_TEST_EQUAL(3, page_count(9, 2, 5));
+
+    // Same, but next even length: same outcome.
+    BOOST_TEST_EQUAL(1, page_count(1, 2, 6));
+    BOOST_TEST_EQUAL(1, page_count(4, 2, 6));
+    BOOST_TEST_EQUAL(2, page_count(5, 2, 6));
+    BOOST_TEST_EQUAL(2, page_count(8, 2, 6));
+    BOOST_TEST_EQUAL(3, page_count(9, 2, 6));
+
+    // Page length seven: one extra data row possible on last page.
+    BOOST_TEST_EQUAL(1, page_count(1, 2, 7));
+    BOOST_TEST_EQUAL(1, page_count(4, 2, 7));
+    BOOST_TEST_EQUAL(1, page_count(5, 2, 7));
+    BOOST_TEST_EQUAL(2, page_count(6, 2, 7));
+    BOOST_TEST_EQUAL(2, page_count(8, 2, 7));
+    BOOST_TEST_EQUAL(2, page_count(9, 2, 7));
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]