improve alignment of month headers

Fri, 31 Jan 2025 22:27:28 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 31 Jan 2025 22:27:28 +0100
changeset 6
1040ba37d4c9
parent 5
60c2588b4455
child 7
d0f77dd2da42

improve alignment of month headers

src/html.cpp file | annotate | diff | comparison | revisions
src/html.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
--- a/src/html.cpp	Fri Jan 31 22:11:04 2025 +0100
+++ b/src/html.cpp	Fri Jan 31 22:27:28 2025 +0100
@@ -26,6 +26,9 @@
 
 #include <cstdio>
 
+#include <chrono>
+namespace chrono = std::chrono;
+
 namespace html {
     static unsigned indentation;
     static const char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
@@ -106,15 +109,33 @@
     printf("<h2>%s</h2>\n", encode(heading).c_str());
 }
 
-void html::table_begin() {
+void html::table_begin(int year) {
+    static constexpr const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+    // compute the column spans, first
+    unsigned colspans[12] = {};
+    {
+        unsigned total_cols = 0;
+        chrono::sys_days day{chrono::year_month_day{chrono::year{year}, chrono::month{1}, chrono::day{1}}};
+        if (chrono::weekday{day}.iso_encoding() != 1) {
+            colspans[0] = 1;
+            total_cols = 1;
+        }
+        for (unsigned col = 0; col < 12; ++col) {
+            while (total_cols < html::columns && chrono::year_month_day{day}.month() <= chrono::month{col + 1}) {
+                ++total_cols;
+                ++colspans[col];
+                day += chrono::days{7};
+            }
+        }
+    }
+
+    // now render the table heading
     indent();
     puts("<table class=\"heatmap\">");
     indent(1);
     puts("<tr>");
     indent(1);
     puts("<th></th>");
-    static constexpr const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-    static constexpr int colspans[] = {5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 5};
     for (unsigned i = 0 ; i < 12 ; i++) {
         indent();
         printf("<th scope=\"col\" colspan=\"%d\">%s</th>\n", colspans[i], months[i]);
--- a/src/html.h	Fri Jan 31 22:11:04 2025 +0100
+++ b/src/html.h	Fri Jan 31 22:27:28 2025 +0100
@@ -36,7 +36,7 @@
 
     void h1(const std::string& heading);
     void h2(const std::string& heading);
-    void table_begin();
+    void table_begin(int year);
     void table_end();
     void row_begin(unsigned int weekday);
     void row_end();
--- a/src/main.cpp	Fri Jan 31 22:11:04 2025 +0100
+++ b/src/main.cpp	Fri Jan 31 22:27:28 2025 +0100
@@ -218,7 +218,7 @@
         html::h1(repo);
         for (const auto &[author, entries] : authors) {
             html::h2(author);
-            html::table_begin();
+            html::table_begin(year);
 
             // initialize counters
             unsigned column = 0, row = 0;

mercurial