%s %d | \n", + hdate_string( HDATE_STRING_GMONTH, header.g_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL), + header.g_year_1); + + h_year_1 = hdate_string(HDATE_STRING_INT, header.h_year_1, HDATE_STRING_LONG, HDATE_STRING_HEBREW); + /************************************************** + * Print Hebrew month and year + **************************************************/ + printf (""); + if (header.h_month_1 != header.h_month_2) + { + printf ("%s-", + hdate_string( HDATE_STRING_HMONTH , header.h_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL)); + } + printf ("%s ", hdate_string( HDATE_STRING_HMONTH , header.h_month_2, HDATE_STRING_LONG, HDATE_STRING_LOCAL)); + printf ("\n"); + printf ("%s |
%3s | ", + hdate_string( HDATE_STRING_DOW, j, TRUE, FALSE)); +} + + + +/************************************************** + * end HTML functions + *************************************************/ + + +/************************************************* +* Display data in a more pleasing visual manner +*************************************************/ +void colorize_element ( const int element ) +{ + switch (element) { + case ELEMENT_WEEKDAY_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_WEEKDAY_H: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_MONTH_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_MONTH_H: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_WEEKDAY_NAMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_SHABBAT_NAME: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_SHABBAT_DAY: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_HOLIDAY_DAY: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_SHABBAT_TIMES: printf(CODE_LIGHT_PURPLE); break; + case ELEMENT_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_SHABBAT_TIMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_HOLIDAY_NAME: printf(CODE_LIGHT_GREY); break; + case ELEMENT_TODAY_HOLIDAY_DAY: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_TODAY_HOLIDAY_NAME: printf(CODE_LIGHT_GREEN); break; + } +/* switch (element) { + case ELEMENT_WEEKDAY_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_WEEKDAY_H: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_MONTH_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_MONTH_H: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_WEEKDAY_NAMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_SHABBAT_NAME: printf(CODE_BOLD_BLUE); break; + case ELEMENT_SHABBAT_DAY: printf(CODE_BOLD_BLUE); break; + case ELEMENT_HOLIDAY_DAY: printf(CODE_BOLD_BLUE); break; + case ELEMENT_SHABBAT_TIMES: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_SHABBAT_TIMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_HOLIDAY_NAME: printf(CODE_LIGHT_GREY); break; + case ELEMENT_TODAY_HOLIDAY_DAY: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_TODAY_HOLIDAY_NAME: printf(CODE_LIGHT_GREEN); break; +*/ +} + + + +/************************************************** + * print header - month line to stdout + *************************************************/ +void print_header_month_line_stdout( const header_info header, const int colorize, const int force_hebrew, const int visual_bidi ) +{ + char *g_month, *h1_month, *h2_month; + char *h1_year = NULL; + char *h2_year = NULL; + size_t g_month_len, g_year_len, h1_month_len, h2_month_len, h1_year_len, h2_year_len; + + + char *hebrew_buffer, *hebrew_buffer_next; + size_t hebrew_buffer_len, literals_len; + + int j; + size_t padding = 0; + + + /************************************************** + * Print Gregorian month and year + *************************************************/ + g_month = hdate_string( HDATE_STRING_GMONTH, header.g_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL); + if (colorize) colorize_element(ELEMENT_MONTH_G); + printf ("%s %d", g_month, header.g_year_1); + if (colorize) printf(CODE_RESTORE_VIDEO); + + /************************************************** + * Print Hebrew month and year + * + * because we want this printed right-justified on + * the same line, we need to calculate how many + * spaces to pad. + * + * because of the possible user option --bidi, we + * need to buffer the entire Hebrew text in order + * reverse its sequence for 'visual' display. + * + * This all requires collecting the data first + * and determining each's length. + *************************************************/ + + #define CALENDAR_WIDTH 41 + #define DASH_WIDTH 3 // includes surrounding spaces + #define SPACE_WIDTH 1 + + + /************************************************* + * padding info for gregorian date + *************************************************/ + g_month_len = strlen(g_month); + g_year_len = 4; + switch (header.g_year_1) + { + case 1-9: g_year_len = 1; break; + case 10-99: g_year_len = 2; break; + case 100-999: g_year_len = 3; break; + } + + + /************************************************** + * collect padding info for Hebrew date + *************************************************/ + h1_month = hdate_string( HDATE_STRING_HMONTH , header.h_month_1, HDATE_STRING_LONG, force_hebrew); + h1_year = hdate_string( HDATE_STRING_INT, header.h_year_1, HDATE_STRING_SHORT, force_hebrew); +//printf("\nh1_month = %s; h1_year = %s, in-year = %d\n",h1_month,h1_year, header.h_year_1);exit(0); + + h1_month_len = strlen(h1_month); + h1_year_len = strlen(h1_year); +// DEBUG - printf("\nh1 year value = %d, h1 year string = %s, string length = %d\n",header.h_year_1, h1_year, h1_year_len); +// DEBUG - int ii; for (ii=0; ii"); + else if (h.hd_dw == SHABBAT) printf (" | "); + else if (holiday_type) printf (" | "); + else printf (" | ");
+
+ /* Print a day */
+ hd_day_str = hdate_string(HDATE_STRING_INT, h.hd_day, HDATE_STRING_LONG,opt.force_hebrew);
+ printf ("
| \n");
+
+ if (hd_day_str != NULL) free(hd_day_str);
+}
+
+
+/*************************************************
+* print stdout calendar entry (ie. a single day)
+*************************************************/
+void print_day ( const hdate_struct h, const int month, const option_list opt)
+{
+
+ // for forcing Hebrew printing of Hebrew data
+ //char *language;
+
+ // char *hd_day_buffer[HEBREW_NUMBER_BUFFER_SIZE + 1];
+ // hd_day_buffer = malloc(HEBREW_NUMBER_BUFFER_SIZE + 1);
+ char *hd_day_str = NULL;
+
+ size_t hd_day_buffer_str_len;
+
+ int holiday_type;
+ holiday_type = hdate_get_holyday_type(hdate_get_holyday(&h, opt.diaspora));
+
+ /**************************************************
+ * out of month - needs padding
+ *************************************************/
+ if (h.gd_mon != month) printf(" ");
+
+
+ /**************************************************
+ * in month - print the data
+ *************************************************/
+ else
+ {
+ /*************************************************
+ * Gregorian date entry - color prefix
+ *************************************************/
+ if (h.hd_jd == opt.jd_today_g)
+ printf (CODE_REVERSE_VIDEO);
+ else if (opt.colorize)
+ {
+ if (h.hd_dw==7) colorize_element(ELEMENT_SHABBAT_DAY);
+ else if (holiday_type) colorize_element(ELEMENT_HOLIDAY_DAY);
+ else colorize_element(ELEMENT_WEEKDAY_G);
+ }
+
+ /*************************************************
+ * Gregorian date entry - the day of the month
+ *************************************************/
+ // this next line is necessary to align numbers
+ // correctly with bidi (tested using mlterm)
+ if ( (h.gd_day < 10) && (hdate_is_hebrew_locale()) )
+ printf ("%d ", h.gd_day);
+ else printf ("%2d", h.gd_day);
+
+ /*************************************************
+ * Gregorian date entry - color cleanup
+ *************************************************/
+ if ((h.hd_jd == opt.jd_today_g) || (opt.colorize))
+ printf (CODE_RESTORE_VIDEO);
+
+
+ /*************************************************
+ * holiday flag
+ *************************************************/
+ printf ("%c", holiday_flag[holiday_type]);
+
+
+ /*************************************************
+ * Hebrew date entry - color prefix
+ *************************************************/
+ if (h.hd_jd == opt.jd_today_h)
+ printf (CODE_REVERSE_VIDEO);
+ else if (opt.colorize)
+ {
+ if (h.hd_dw==7) colorize_element(ELEMENT_SHABBAT_DAY);
+ else if (holiday_type) colorize_element(ELEMENT_HOLIDAY_DAY);
+ else colorize_element(ELEMENT_WEEKDAY_H);
+ }
+
+
+ /*************************************************
+ * Hebrew date entry - day of the month
+ *************************************************/
+ hd_day_str = hdate_string(HDATE_STRING_INT, h.hd_day,HDATE_STRING_SHORT,opt.force_hebrew);
+ if (opt.bidi)
+ {
+ hd_day_buffer_str_len = (size_t) strlen(hd_day_str);
+ if ( hd_day_buffer_str_len > HEBREW_NUMBER_BUFFER_SIZE)
+ hd_day_buffer_str_len = HEBREW_NUMBER_BUFFER_SIZE - 1;
+ revstr(hd_day_str, hd_day_buffer_str_len);
+ }
+ if ( ( (opt.force_hebrew) || (hdate_is_hebrew_locale()) ) &&
+ ( (h.hd_day < 11) || (h.hd_day == 20) || (h.hd_day == 30) ) )
+ { // need to pad Hebrew dates 1-10, 20, 30
+ printf ("%s%s"," ",hd_day_str);
+ }
+ else printf ("%2s", hd_day_str);
+
+ /*************************************************
+ * Hebrew date entry - color cleanup
+ *************************************************/
+ if ((h.hd_jd == opt.jd_today_h) || (opt.colorize))
+ printf (CODE_RESTORE_VIDEO);
+
+ }
+
+ if (hd_day_str != NULL) free(hd_day_str);
+}
+
+
+/*************************************************
+* print a calendar week's entry (ie. seven columns)
+*************************************************/
+void print_week( int jd, const int month, const option_list opt)
+{
+#define long_parasha_name 0
+
+ hdate_struct h;
+
+ int calendar_column;
+
+ // for opt.shabbat
+ int sun_hour, first_light, talit, sunrise;
+ int midday, sunset, first_stars, three_stars;
+ int this_week;
+ hdate_struct yom_shishi;
+
+ // for opt.parasha
+ int shabbat_name;
+ char *shabbat_name_str, *shabbat_name_buffer;
+ size_t shabbat_name_str_len;
+
+
+ // for forcing Hebrew printing of Hebrew data
+ //char *language;
+
+
+ /**************************************************
+ * for each column of calendar
+ *************************************************/
+ for (calendar_column = 0; calendar_column < 7; calendar_column++)
+ {
+
+ /**************************************************
+ * Get this day's information
+ *************************************************/
+ hdate_set_jd (&h, jd);
+ if ( ((opt.shabbat) || (opt.parasha)) && (calendar_column == 5) )
+ yom_shishi = h;
+
+
+ /**************************************************
+ * HTML calendar option
+ *************************************************/
+ if (opt.html) print_day_html ( h, month, opt );
+
+
+
+ /**************************************************
+ * non-HTML calendar option
+ *************************************************/
+ else print_day ( h, month, opt);
+
+
+ /**************************************************
+ * space between days of week
+ *************************************************/
+ if (calendar_column != 6) printf (" ");
+
+ /**************************************************
+ * advance to next day of week
+ *************************************************/
+ jd++;
+ }
+
+ /**************************************************
+ * print end of calendar line
+ *************************************************/
+ if ((!opt.html) && ( (h.gd_mon == month) || (h.gd_day < SHABBAT) ) )
+ {
+
+ /********************************************************
+ * determine whether this line gets special highlighting
+ ********************************************************/
+ if ((opt.colorize)
+ && ((opt.shabbat) || (opt.parasha))
+ && ((jd - 1) > opt.jd_today_h)
+ && (((jd - 1) - opt.jd_today_h) < 7) )
+ this_week = TRUE;
+ else this_week = FALSE;
+
+ /*************************************************
+ * print shabbat times
+ *************************************************/
+ if (opt.shabbat)
+ {
+ // candlelighting times
+ /// note: compiler incorrectly issued warnings:
+ /// "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ /// The initialization occurs above (~line 1005) "yom_shishi = h"
+ hdate_get_utc_sun_time (yom_shishi.gd_day, yom_shishi.gd_mon, yom_shishi.gd_year,
+ opt.lat, opt.lon, &sunrise, &sunset);
+
+ // FIXME - allow for further minhag variation
+ if (opt.candles != 1) sunset = sunset - opt.candles + opt.tz;
+ else sunset = sunset + opt.tz - DEFAULT_CANDLES_MINUTES;
+
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_SHABBAT_TIMES);
+ else colorize_element(ELEMENT_SHABBAT_TIMES);
+ }
+ printf (" %02d:%02d", sunset / 60, sunset % 60);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+
+ printf(" - ");
+
+ // motzay shabat time
+ hdate_get_utc_sun_time_full (h.gd_day, h.gd_mon, h.gd_year, opt.lat,
+ opt.lon, &sun_hour, &first_light, &talit,
+ &sunrise, &midday, &sunset,
+ &first_stars, &three_stars);
+
+ // FIXME - allow for further minhag variation
+ if (opt.havdalah != 1) three_stars = sunset + opt.havdalah + opt.tz;
+ else three_stars = three_stars + opt.tz;
+
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_SHABBAT_TIMES);
+ else colorize_element(ELEMENT_SHABBAT_TIMES);
+ }
+ printf ("%02d:%02d", three_stars / 60, three_stars % 60);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+ }
+
+
+ /*************************************************
+ * print shabbat name
+ *************************************************/
+ if (opt.parasha)
+ {
+
+ /*************************************************
+ * print shabbat name - force-hebrew setup
+ *************************************************/
+ // BUG - this isn't thread-safe
+ /*if (opt.force_hebrew)
+ {
+ language=getenv("LANGUAGE");
+ setenv("LANGUAGE", "he_IL.UTF-8", 1);
+ }*/
+
+
+ shabbat_name = hdate_get_parasha (&h, opt.diaspora);
+ if (shabbat_name) shabbat_name_str =
+ hdate_string( HDATE_STRING_PARASHA, shabbat_name,
+ HDATE_STRING_SHORT, opt.force_hebrew);
+ else
+ {
+ shabbat_name = hdate_get_holyday(&h, opt.diaspora);
+ if (shabbat_name) shabbat_name_str =
+ hdate_string( HDATE_STRING_HOLIDAY,
+ shabbat_name,
+ HDATE_STRING_SHORT, opt.force_hebrew);
+ }
+ if (shabbat_name)
+ {
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_PARASHA);
+ else colorize_element(ELEMENT_PARASHA);
+ }
+ if (opt.bidi)
+ {
+ shabbat_name_str_len = strlen(shabbat_name_str);
+ shabbat_name_buffer = malloc(shabbat_name_str_len+1);
+ memcpy(shabbat_name_buffer, shabbat_name_str, shabbat_name_str_len);
+ shabbat_name_buffer[shabbat_name_str_len] = '\0';
+ revstr(shabbat_name_buffer, shabbat_name_str_len);
+
+ // padding - FIXME - spaces are single-byte, while
+ // the Hebrew characters are two bytes
+ const int margin_max = 15;
+ printf("%*s%s", (int)(margin_max - shabbat_name_str_len/2)," ", shabbat_name_buffer);
+
+ free(shabbat_name_buffer);
+ }
+ else printf(" %s", shabbat_name_str);
+ //if (opt.force_hebrew) setenv("LANGUAGE", language, 1);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+ }
+ }
+ }
+}
+
+
+
+
+/**************************************************
+* print month table
+*************************************************/
+int print_calendar ( const int current_month, const int current_year, const option_list opt)
+{
+ hdate_struct h;
+ int calendar_line;
+ int max_calendar_lines = 4;
+ /// the initializations on next line aren't truly necessary, but they do
+ /// suppress warning "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ int previous_month = 1, next_month = 1;
+ int previous_year, next_year;
+ /// the initializations on next line aren't truly necessary, but they do
+ /// suppress warning "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ int jd_current_month, jd_previous_month = 1, jd_next_month = 1;
+
+ void how_many_calendar_lines( int month, int start_dow )
+ {
+ switch (month)
+ {
+ case 4:
+ case 6:
+ case 9:
+ case 11: if (start_dow == 7) max_calendar_lines = 6;
+ else if (max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ case 8:
+ case 10:
+ case 12: if (start_dow > 5) max_calendar_lines = 6;
+ else if (max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ case 2: if (start_dow > 1 && max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ }
+ }
+
+ /*********************************************************
+ * Preliminaries:
+ * - Find the first sunday(s) of each calendar
+ * - Find number of calendar lines
+ *********************************************************/
+ hdate_set_gdate (&h, 1, current_month, current_year);
+ jd_current_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+
+ /*********************************************************
+ * three months, side-by-side
+ *********************************************************/
+ if (opt.three_month)
+ {
+ /*********************************************************
+ * previous month
+ *********************************************************/
+ if (current_month == 1)
+ {
+ previous_month = 12;
+ previous_year = current_year - 1;
+ }
+ else
+ {
+ previous_month = current_month - 1;
+ previous_year = current_year;
+ }
+ hdate_set_gdate (&h, 1, previous_month, previous_year);
+ jd_previous_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+
+ /*********************************************************
+ * next month
+ *********************************************************/
+ if (current_month == 12)
+ {
+ next_month = 1;
+ next_year = current_year + 1;
+ }
+ else
+ {
+ next_month = current_month + 1;
+ next_year = current_year;
+ }
+ hdate_set_gdate (&h, 1, next_month, next_year);
+ jd_next_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+ }
+
+
+
+ /**************************************************
+ * maximum six lines of calendar
+ **************************************************/
+ for (calendar_line = 0; calendar_line < max_calendar_lines; calendar_line++)
+ {
+ if (opt.html) printf ("
---|---|
%s %d | \n", + hdate_string( HDATE_STRING_GMONTH, header.g_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL), + header.g_year_1); + + h_year_1 = hdate_string(HDATE_STRING_INT, header.h_year_1, HDATE_STRING_LONG, HDATE_STRING_HEBREW); + /************************************************** + * Print Hebrew month and year + **************************************************/ + printf (""); + if (header.h_month_1 != header.h_month_2) + { + printf ("%s-", + hdate_string( HDATE_STRING_HMONTH , header.h_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL)); + } + printf ("%s ", hdate_string( HDATE_STRING_HMONTH , header.h_month_2, HDATE_STRING_LONG, HDATE_STRING_LOCAL)); + printf ("\n"); + printf ("%s |
%3s | ", + hdate_string( HDATE_STRING_DOW, j, TRUE, FALSE)); +} + + + +/************************************************** + * end HTML functions + *************************************************/ + + +/************************************************* +* Display data in a more pleasing visual manner +*************************************************/ +void colorize_element ( const int element ) +{ + switch (element) { + case ELEMENT_WEEKDAY_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_WEEKDAY_H: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_MONTH_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_MONTH_H: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_WEEKDAY_NAMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_SHABBAT_NAME: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_SHABBAT_DAY: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_HOLIDAY_DAY: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_SHABBAT_TIMES: printf(CODE_LIGHT_PURPLE); break; + case ELEMENT_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_SHABBAT_TIMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_HOLIDAY_NAME: printf(CODE_LIGHT_GREY); break; + case ELEMENT_TODAY_HOLIDAY_DAY: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_TODAY_HOLIDAY_NAME: printf(CODE_LIGHT_GREEN); break; + } +/* switch (element) { + case ELEMENT_WEEKDAY_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_WEEKDAY_H: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_MONTH_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_MONTH_H: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_WEEKDAY_NAMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_SHABBAT_NAME: printf(CODE_BOLD_BLUE); break; + case ELEMENT_SHABBAT_DAY: printf(CODE_BOLD_BLUE); break; + case ELEMENT_HOLIDAY_DAY: printf(CODE_BOLD_BLUE); break; + case ELEMENT_SHABBAT_TIMES: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_SHABBAT_TIMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_HOLIDAY_NAME: printf(CODE_LIGHT_GREY); break; + case ELEMENT_TODAY_HOLIDAY_DAY: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_TODAY_HOLIDAY_NAME: printf(CODE_LIGHT_GREEN); break; +*/ +} + + + +/************************************************** + * print header - month line to stdout + *************************************************/ +void print_header_month_line_stdout( const header_info header, const int colorize, const int force_hebrew, const int visual_bidi ) +{ + char *g_month, *h1_month, *h2_month; + char *h1_year = NULL; + char *h2_year = NULL; + size_t g_month_len, g_year_len, h1_month_len, h2_month_len, h1_year_len, h2_year_len; + + + char *hebrew_buffer, *hebrew_buffer_next; + size_t hebrew_buffer_len, literals_len; + + int j; + size_t padding = 0; + + + /************************************************** + * Print Gregorian month and year + *************************************************/ + g_month = hdate_string( HDATE_STRING_GMONTH, header.g_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL); + if (colorize) colorize_element(ELEMENT_MONTH_G); + printf ("%s %d", g_month, header.g_year_1); + if (colorize) printf(CODE_RESTORE_VIDEO); + + /************************************************** + * Print Hebrew month and year + * + * because we want this printed right-justified on + * the same line, we need to calculate how many + * spaces to pad. + * + * because of the possible user option --bidi, we + * need to buffer the entire Hebrew text in order + * reverse its sequence for 'visual' display. + * + * This all requires collecting the data first + * and determining each's length. + *************************************************/ + + #define CALENDAR_WIDTH 41 + #define DASH_WIDTH 3 // includes surrounding spaces + #define SPACE_WIDTH 1 + + + /************************************************* + * padding info for gregorian date + *************************************************/ + g_month_len = strlen(g_month); + g_year_len = 4; + switch (header.g_year_1) + { + case 1-9: g_year_len = 1; break; + case 10-99: g_year_len = 2; break; + case 100-999: g_year_len = 3; break; + } + + + /************************************************** + * collect padding info for Hebrew date + *************************************************/ + h1_month = hdate_string( HDATE_STRING_HMONTH , header.h_month_1, HDATE_STRING_LONG, force_hebrew); + h1_year = hdate_string( HDATE_STRING_INT, header.h_year_1, HDATE_STRING_SHORT, force_hebrew); +//printf("\nh1_month = %s; h1_year = %s, in-year = %d\n",h1_month,h1_year, header.h_year_1);exit(0); + + h1_month_len = strlen(h1_month); + h1_year_len = strlen(h1_year); +// DEBUG - printf("\nh1 year value = %d, h1 year string = %s, string length = %d\n",header.h_year_1, h1_year, h1_year_len); +// DEBUG - int ii; for (ii=0; ii"); + else if (h.hd_dw == SHABBAT) printf (" | "); + else if (holiday_type) printf (" | "); + else printf (" | ");
+
+ /* Print a day */
+ hd_day_str = hdate_string(HDATE_STRING_INT, h.hd_day, HDATE_STRING_LONG,opt.force_hebrew);
+ printf ("
| \n");
+
+ if (hd_day_str != NULL) free(hd_day_str);
+}
+
+
+/*************************************************
+* print stdout calendar entry (ie. a single day)
+*************************************************/
+void print_day ( const hdate_struct h, const int month, const option_list opt)
+{
+
+ // for forcing Hebrew printing of Hebrew data
+ //char *language;
+
+ // char *hd_day_buffer[HEBREW_NUMBER_BUFFER_SIZE + 1];
+ // hd_day_buffer = malloc(HEBREW_NUMBER_BUFFER_SIZE + 1);
+ char *hd_day_str = NULL;
+
+ size_t hd_day_buffer_str_len;
+
+ int holiday_type;
+ holiday_type = hdate_get_holyday_type(hdate_get_holyday(&h, opt.diaspora));
+
+ /**************************************************
+ * out of month - needs padding
+ *************************************************/
+ if (h.gd_mon != month) printf(" ");
+
+
+ /**************************************************
+ * in month - print the data
+ *************************************************/
+ else
+ {
+ /*************************************************
+ * Gregorian date entry - color prefix
+ *************************************************/
+ if (h.hd_jd == opt.jd_today_g)
+ printf (CODE_REVERSE_VIDEO);
+ else if (opt.colorize)
+ {
+ if (h.hd_dw==7) colorize_element(ELEMENT_SHABBAT_DAY);
+ else if (holiday_type) colorize_element(ELEMENT_HOLIDAY_DAY);
+ else colorize_element(ELEMENT_WEEKDAY_G);
+ }
+
+ /*************************************************
+ * Gregorian date entry - the day of the month
+ *************************************************/
+ // this next line is necessary to align numbers
+ // correctly with bidi (tested using mlterm)
+ if ( (h.gd_day < 10) && (hdate_is_hebrew_locale()) )
+ printf ("%d ", h.gd_day);
+ else printf ("%2d", h.gd_day);
+
+ /*************************************************
+ * Gregorian date entry - color cleanup
+ *************************************************/
+ if ((h.hd_jd == opt.jd_today_g) || (opt.colorize))
+ printf (CODE_RESTORE_VIDEO);
+
+
+ /*************************************************
+ * holiday flag
+ *************************************************/
+ printf ("%c", holiday_flag[holiday_type]);
+
+
+ /*************************************************
+ * Hebrew date entry - color prefix
+ *************************************************/
+ if (h.hd_jd == opt.jd_today_h)
+ printf (CODE_REVERSE_VIDEO);
+ else if (opt.colorize)
+ {
+ if (h.hd_dw==7) colorize_element(ELEMENT_SHABBAT_DAY);
+ else if (holiday_type) colorize_element(ELEMENT_HOLIDAY_DAY);
+ else colorize_element(ELEMENT_WEEKDAY_H);
+ }
+
+
+ /*************************************************
+ * Hebrew date entry - day of the month
+ *************************************************/
+ hd_day_str = hdate_string(HDATE_STRING_INT, h.hd_day,HDATE_STRING_SHORT,opt.force_hebrew);
+ if (opt.bidi)
+ {
+ hd_day_buffer_str_len = (size_t) strlen(hd_day_str);
+ if ( hd_day_buffer_str_len > HEBREW_NUMBER_BUFFER_SIZE)
+ hd_day_buffer_str_len = HEBREW_NUMBER_BUFFER_SIZE - 1;
+ revstr(hd_day_str, hd_day_buffer_str_len);
+ }
+ if ( ( (opt.force_hebrew) || (hdate_is_hebrew_locale()) ) &&
+ ( (h.hd_day < 11) || (h.hd_day == 20) || (h.hd_day == 30) ) )
+ { // need to pad Hebrew dates 1-10, 20, 30
+ printf ("%s%s"," ",hd_day_str);
+ }
+ else printf ("%2s", hd_day_str);
+
+ /*************************************************
+ * Hebrew date entry - color cleanup
+ *************************************************/
+ if ((h.hd_jd == opt.jd_today_h) || (opt.colorize))
+ printf (CODE_RESTORE_VIDEO);
+
+ }
+
+ if (hd_day_str != NULL) free(hd_day_str);
+}
+
+
+/*************************************************
+* print a calendar week's entry (ie. seven columns)
+*************************************************/
+void print_week( int jd, const int month, const option_list opt)
+{
+#define long_parasha_name 0
+
+ hdate_struct h;
+
+ int calendar_column;
+
+ // for opt.shabbat
+ int sun_hour, first_light, talit, sunrise;
+ int midday, sunset, first_stars, three_stars;
+ int this_week;
+ hdate_struct yom_shishi;
+
+ // for opt.parasha
+ int shabbat_name;
+ char *shabbat_name_str, *shabbat_name_buffer;
+ size_t shabbat_name_str_len;
+
+
+ // for forcing Hebrew printing of Hebrew data
+ //char *language;
+
+
+ /**************************************************
+ * for each column of calendar
+ *************************************************/
+ for (calendar_column = 0; calendar_column < 7; calendar_column++)
+ {
+
+ /**************************************************
+ * Get this day's information
+ *************************************************/
+ hdate_set_jd (&h, jd);
+ if ( ((opt.shabbat) || (opt.parasha)) && (calendar_column == 5) )
+ yom_shishi = h;
+
+
+ /**************************************************
+ * HTML calendar option
+ *************************************************/
+ if (opt.html) print_day_html ( h, month, opt );
+
+
+
+ /**************************************************
+ * non-HTML calendar option
+ *************************************************/
+ else print_day ( h, month, opt);
+
+
+ /**************************************************
+ * space between days of week
+ *************************************************/
+ if (calendar_column != 6) printf (" ");
+
+ /**************************************************
+ * advance to next day of week
+ *************************************************/
+ jd++;
+ }
+
+ /**************************************************
+ * print end of calendar line
+ *************************************************/
+ if ((!opt.html) && ( (h.gd_mon == month) || (h.gd_day < SHABBAT) ) )
+ {
+
+ /********************************************************
+ * determine whether this line gets special highlighting
+ ********************************************************/
+ if ((opt.colorize)
+ && ((opt.shabbat) || (opt.parasha))
+ && ((jd - 1) > opt.jd_today_h)
+ && (((jd - 1) - opt.jd_today_h) < 7) )
+ this_week = TRUE;
+ else this_week = FALSE;
+
+ /*************************************************
+ * print shabbat times
+ *************************************************/
+ if (opt.shabbat)
+ {
+ // candlelighting times
+ /// note: compiler incorrectly issued warnings:
+ /// "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ /// The initialization occurs above (~line 1005) "yom_shishi = h"
+ hdate_get_utc_sun_time (yom_shishi.gd_day, yom_shishi.gd_mon, yom_shishi.gd_year,
+ opt.lat, opt.lon, &sunrise, &sunset);
+
+ // FIXME - allow for further minhag variation
+ if (opt.candles != 1) sunset = sunset - opt.candles + opt.tz;
+ else sunset = sunset + opt.tz - DEFAULT_CANDLES_MINUTES;
+
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_SHABBAT_TIMES);
+ else colorize_element(ELEMENT_SHABBAT_TIMES);
+ }
+ printf (" %02d:%02d", sunset / 60, sunset % 60);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+
+ printf(" - ");
+
+ // motzay shabat time
+ hdate_get_utc_sun_time_full (h.gd_day, h.gd_mon, h.gd_year, opt.lat,
+ opt.lon, &sun_hour, &first_light, &talit,
+ &sunrise, &midday, &sunset,
+ &first_stars, &three_stars);
+
+ // FIXME - allow for further minhag variation
+ if (opt.havdalah != 1) three_stars = sunset + opt.havdalah + opt.tz;
+ else three_stars = three_stars + opt.tz;
+
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_SHABBAT_TIMES);
+ else colorize_element(ELEMENT_SHABBAT_TIMES);
+ }
+ printf ("%02d:%02d", three_stars / 60, three_stars % 60);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+ }
+
+
+ /*************************************************
+ * print shabbat name
+ *************************************************/
+ if (opt.parasha)
+ {
+
+ /*************************************************
+ * print shabbat name - force-hebrew setup
+ *************************************************/
+ // BUG - this isn't thread-safe
+ /*if (opt.force_hebrew)
+ {
+ language=getenv("LANGUAGE");
+ setenv("LANGUAGE", "he_IL.UTF-8", 1);
+ }*/
+
+
+ shabbat_name = hdate_get_parasha (&h, opt.diaspora);
+ if (shabbat_name) shabbat_name_str =
+ hdate_string( HDATE_STRING_PARASHA, shabbat_name,
+ HDATE_STRING_SHORT, opt.force_hebrew);
+ else
+ {
+ shabbat_name = hdate_get_holyday(&h, opt.diaspora);
+ if (shabbat_name) shabbat_name_str =
+ hdate_string( HDATE_STRING_HOLIDAY,
+ shabbat_name,
+ HDATE_STRING_SHORT, opt.force_hebrew);
+ }
+ if (shabbat_name)
+ {
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_PARASHA);
+ else colorize_element(ELEMENT_PARASHA);
+ }
+ if (opt.bidi)
+ {
+ shabbat_name_str_len = strlen(shabbat_name_str);
+ shabbat_name_buffer = malloc(shabbat_name_str_len+1);
+ memcpy(shabbat_name_buffer, shabbat_name_str, shabbat_name_str_len);
+ shabbat_name_buffer[shabbat_name_str_len] = '\0';
+ revstr(shabbat_name_buffer, shabbat_name_str_len);
+
+ // padding - FIXME - spaces are single-byte, while
+ // the Hebrew characters are two bytes
+ const int margin_max = 15;
+ printf("%*s%s", (int)(margin_max - shabbat_name_str_len/2)," ", shabbat_name_buffer);
+
+ free(shabbat_name_buffer);
+ }
+ else printf(" %s", shabbat_name_str);
+ //if (opt.force_hebrew) setenv("LANGUAGE", language, 1);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+ }
+ }
+ }
+}
+
+
+
+
+/**************************************************
+* print month table
+*************************************************/
+int print_calendar ( const int current_month, const int current_year, const option_list opt)
+{
+ hdate_struct h;
+ int calendar_line;
+ int max_calendar_lines = 4;
+ /// the initializations on next line aren't truly necessary, but they do
+ /// suppress warning "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ int previous_month = 1, next_month = 1;
+ int previous_year, next_year;
+ /// the initializations on next line aren't truly necessary, but they do
+ /// suppress warning "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ int jd_current_month, jd_previous_month = 1, jd_next_month = 1;
+
+ void how_many_calendar_lines( int month, int start_dow )
+ {
+ switch (month)
+ {
+ case 4:
+ case 6:
+ case 9:
+ case 11: if (start_dow == 7) max_calendar_lines = 6;
+ else if (max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ case 8:
+ case 10:
+ case 12: if (start_dow > 5) max_calendar_lines = 6;
+ else if (max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ case 2: if (start_dow > 1 && max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ }
+ }
+
+ /*********************************************************
+ * Preliminaries:
+ * - Find the first sunday(s) of each calendar
+ * - Find number of calendar lines
+ *********************************************************/
+ hdate_set_gdate (&h, 1, current_month, current_year);
+ jd_current_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+
+ /*********************************************************
+ * three months, side-by-side
+ *********************************************************/
+ if (opt.three_month)
+ {
+ /*********************************************************
+ * previous month
+ *********************************************************/
+ if (current_month == 1)
+ {
+ previous_month = 12;
+ previous_year = current_year - 1;
+ }
+ else
+ {
+ previous_month = current_month - 1;
+ previous_year = current_year;
+ }
+ hdate_set_gdate (&h, 1, previous_month, previous_year);
+ jd_previous_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+
+ /*********************************************************
+ * next month
+ *********************************************************/
+ if (current_month == 12)
+ {
+ next_month = 1;
+ next_year = current_year + 1;
+ }
+ else
+ {
+ next_month = current_month + 1;
+ next_year = current_year;
+ }
+ hdate_set_gdate (&h, 1, next_month, next_year);
+ jd_next_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+ }
+
+
+
+ /**************************************************
+ * maximum six lines of calendar
+ **************************************************/
+ for (calendar_line = 0; calendar_line < max_calendar_lines; calendar_line++)
+ {
+ if (opt.html) printf ("
---|---|
%s %d | \n", + hdate_string( HDATE_STRING_GMONTH, header.g_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL), + header.g_year_1); + + h_year_1 = hdate_string(HDATE_STRING_INT, header.h_year_1, HDATE_STRING_LONG, HDATE_STRING_HEBREW); + /************************************************** + * Print Hebrew month and year + **************************************************/ + printf (""); + if (header.h_month_1 != header.h_month_2) + { + printf ("%s-", + hdate_string( HDATE_STRING_HMONTH , header.h_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL)); + } + printf ("%s ", hdate_string( HDATE_STRING_HMONTH , header.h_month_2, HDATE_STRING_LONG, HDATE_STRING_LOCAL)); + printf ("\n"); + printf ("%s |
%3s | ", + hdate_string( HDATE_STRING_DOW, j, TRUE, FALSE)); +} + + + +/************************************************** + * end HTML functions + *************************************************/ + + +/************************************************* +* Display data in a more pleasing visual manner +*************************************************/ +void colorize_element ( const int element ) +{ + switch (element) { + case ELEMENT_WEEKDAY_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_WEEKDAY_H: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_MONTH_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_MONTH_H: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_WEEKDAY_NAMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_SHABBAT_NAME: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_SHABBAT_DAY: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_HOLIDAY_DAY: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_SHABBAT_TIMES: printf(CODE_LIGHT_PURPLE); break; + case ELEMENT_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_SHABBAT_TIMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_HOLIDAY_NAME: printf(CODE_LIGHT_GREY); break; + case ELEMENT_TODAY_HOLIDAY_DAY: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_TODAY_HOLIDAY_NAME: printf(CODE_LIGHT_GREEN); break; + } +/* switch (element) { + case ELEMENT_WEEKDAY_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_WEEKDAY_H: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_MONTH_G: printf(CODE_LIGHT_GREY); break; + case ELEMENT_MONTH_H: printf(CODE_LIGHT_AQUA); break; + case ELEMENT_WEEKDAY_NAMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_SHABBAT_NAME: printf(CODE_BOLD_BLUE); break; + case ELEMENT_SHABBAT_DAY: printf(CODE_BOLD_BLUE); break; + case ELEMENT_HOLIDAY_DAY: printf(CODE_BOLD_BLUE); break; + case ELEMENT_SHABBAT_TIMES: printf(CODE_LIGHT_BROWN); break; + case ELEMENT_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_SHABBAT_TIMES: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_THIS_PARASHA: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_HOLIDAY_NAME: printf(CODE_LIGHT_GREY); break; + case ELEMENT_TODAY_HOLIDAY_DAY: printf(CODE_LIGHT_GREEN); break; + case ELEMENT_TODAY_HOLIDAY_NAME: printf(CODE_LIGHT_GREEN); break; +*/ +} + + + +/************************************************** + * print header - month line to stdout + *************************************************/ +void print_header_month_line_stdout( const header_info header, const int colorize, const int force_hebrew, const int visual_bidi ) +{ + char *g_month, *h1_month, *h2_month; + char *h1_year = NULL; + char *h2_year = NULL; + size_t g_month_len, g_year_len, h1_month_len, h2_month_len, h1_year_len, h2_year_len; + + + char *hebrew_buffer, *hebrew_buffer_next; + size_t hebrew_buffer_len, literals_len; + + int j; + size_t padding = 0; + + + /************************************************** + * Print Gregorian month and year + *************************************************/ + g_month = hdate_string( HDATE_STRING_GMONTH, header.g_month_1, HDATE_STRING_LONG, HDATE_STRING_LOCAL); + if (colorize) colorize_element(ELEMENT_MONTH_G); + printf ("%s %d", g_month, header.g_year_1); + if (colorize) printf(CODE_RESTORE_VIDEO); + + /************************************************** + * Print Hebrew month and year + * + * because we want this printed right-justified on + * the same line, we need to calculate how many + * spaces to pad. + * + * because of the possible user option --bidi, we + * need to buffer the entire Hebrew text in order + * reverse its sequence for 'visual' display. + * + * This all requires collecting the data first + * and determining each's length. + *************************************************/ + + #define CALENDAR_WIDTH 41 + #define DASH_WIDTH 3 // includes surrounding spaces + #define SPACE_WIDTH 1 + + + /************************************************* + * padding info for gregorian date + *************************************************/ + g_month_len = strlen(g_month); + g_year_len = 4; + switch (header.g_year_1) + { + case 1-9: g_year_len = 1; break; + case 10-99: g_year_len = 2; break; + case 100-999: g_year_len = 3; break; + } + + + /************************************************** + * collect padding info for Hebrew date + *************************************************/ + h1_month = hdate_string( HDATE_STRING_HMONTH , header.h_month_1, HDATE_STRING_LONG, force_hebrew); + h1_year = hdate_string( HDATE_STRING_INT, header.h_year_1, HDATE_STRING_SHORT, force_hebrew); +//printf("\nh1_month = %s; h1_year = %s, in-year = %d\n",h1_month,h1_year, header.h_year_1);exit(0); + + h1_month_len = strlen(h1_month); + h1_year_len = strlen(h1_year); +// DEBUG - printf("\nh1 year value = %d, h1 year string = %s, string length = %d\n",header.h_year_1, h1_year, h1_year_len); +// DEBUG - int ii; for (ii=0; ii"); + else if (h.hd_dw == SHABBAT) printf (" | "); + else if (holiday_type) printf (" | "); + else printf (" | ");
+
+ /* Print a day */
+ hd_day_str = hdate_string(HDATE_STRING_INT, h.hd_day, HDATE_STRING_LONG,opt.force_hebrew);
+ printf ("
| \n");
+
+ if (hd_day_str != NULL) free(hd_day_str);
+}
+
+
+/*************************************************
+* print stdout calendar entry (ie. a single day)
+*************************************************/
+void print_day ( const hdate_struct h, const int month, const option_list opt)
+{
+
+ // for forcing Hebrew printing of Hebrew data
+ //char *language;
+
+ // char *hd_day_buffer[HEBREW_NUMBER_BUFFER_SIZE + 1];
+ // hd_day_buffer = malloc(HEBREW_NUMBER_BUFFER_SIZE + 1);
+ char *hd_day_str = NULL;
+
+ size_t hd_day_buffer_str_len;
+
+ int holiday_type;
+ holiday_type = hdate_get_holyday_type(hdate_get_holyday(&h, opt.diaspora));
+
+ /**************************************************
+ * out of month - needs padding
+ *************************************************/
+ if (h.gd_mon != month) printf(" ");
+
+
+ /**************************************************
+ * in month - print the data
+ *************************************************/
+ else
+ {
+ /*************************************************
+ * Gregorian date entry - color prefix
+ *************************************************/
+ if (h.hd_jd == opt.jd_today_g)
+ printf (CODE_REVERSE_VIDEO);
+ else if (opt.colorize)
+ {
+ if (h.hd_dw==7) colorize_element(ELEMENT_SHABBAT_DAY);
+ else if (holiday_type) colorize_element(ELEMENT_HOLIDAY_DAY);
+ else colorize_element(ELEMENT_WEEKDAY_G);
+ }
+
+ /*************************************************
+ * Gregorian date entry - the day of the month
+ *************************************************/
+ // this next line is necessary to align numbers
+ // correctly with bidi (tested using mlterm)
+ if ( (h.gd_day < 10) && (hdate_is_hebrew_locale()) )
+ printf ("%d ", h.gd_day);
+ else printf ("%2d", h.gd_day);
+
+ /*************************************************
+ * Gregorian date entry - color cleanup
+ *************************************************/
+ if ((h.hd_jd == opt.jd_today_g) || (opt.colorize))
+ printf (CODE_RESTORE_VIDEO);
+
+
+ /*************************************************
+ * holiday flag
+ *************************************************/
+ printf ("%c", holiday_flag[holiday_type]);
+
+
+ /*************************************************
+ * Hebrew date entry - color prefix
+ *************************************************/
+ if (h.hd_jd == opt.jd_today_h)
+ printf (CODE_REVERSE_VIDEO);
+ else if (opt.colorize)
+ {
+ if (h.hd_dw==7) colorize_element(ELEMENT_SHABBAT_DAY);
+ else if (holiday_type) colorize_element(ELEMENT_HOLIDAY_DAY);
+ else colorize_element(ELEMENT_WEEKDAY_H);
+ }
+
+
+ /*************************************************
+ * Hebrew date entry - day of the month
+ *************************************************/
+ hd_day_str = hdate_string(HDATE_STRING_INT, h.hd_day,HDATE_STRING_SHORT,opt.force_hebrew);
+ if (opt.bidi)
+ {
+ hd_day_buffer_str_len = (size_t) strlen(hd_day_str);
+ if ( hd_day_buffer_str_len > HEBREW_NUMBER_BUFFER_SIZE)
+ hd_day_buffer_str_len = HEBREW_NUMBER_BUFFER_SIZE - 1;
+ revstr(hd_day_str, hd_day_buffer_str_len);
+ }
+ if ( ( (opt.force_hebrew) || (hdate_is_hebrew_locale()) ) &&
+ ( (h.hd_day < 11) || (h.hd_day == 20) || (h.hd_day == 30) ) )
+ { // need to pad Hebrew dates 1-10, 20, 30
+ printf ("%s%s"," ",hd_day_str);
+ }
+ else printf ("%2s", hd_day_str);
+
+ /*************************************************
+ * Hebrew date entry - color cleanup
+ *************************************************/
+ if ((h.hd_jd == opt.jd_today_h) || (opt.colorize))
+ printf (CODE_RESTORE_VIDEO);
+
+ }
+
+ if (hd_day_str != NULL) free(hd_day_str);
+}
+
+
+/*************************************************
+* print a calendar week's entry (ie. seven columns)
+*************************************************/
+void print_week( int jd, const int month, const option_list opt)
+{
+#define long_parasha_name 0
+
+ hdate_struct h;
+
+ int calendar_column;
+
+ // for opt.shabbat
+ int sun_hour, first_light, talit, sunrise;
+ int midday, sunset, first_stars, three_stars;
+ int this_week;
+ hdate_struct yom_shishi;
+
+ // for opt.parasha
+ int shabbat_name;
+ char *shabbat_name_str, *shabbat_name_buffer;
+ size_t shabbat_name_str_len;
+
+
+ // for forcing Hebrew printing of Hebrew data
+ //char *language;
+
+
+ /**************************************************
+ * for each column of calendar
+ *************************************************/
+ for (calendar_column = 0; calendar_column < 7; calendar_column++)
+ {
+
+ /**************************************************
+ * Get this day's information
+ *************************************************/
+ hdate_set_jd (&h, jd);
+ if ( ((opt.shabbat) || (opt.parasha)) && (calendar_column == 5) )
+ yom_shishi = h;
+
+
+ /**************************************************
+ * HTML calendar option
+ *************************************************/
+ if (opt.html) print_day_html ( h, month, opt );
+
+
+
+ /**************************************************
+ * non-HTML calendar option
+ *************************************************/
+ else print_day ( h, month, opt);
+
+
+ /**************************************************
+ * space between days of week
+ *************************************************/
+ if (calendar_column != 6) printf (" ");
+
+ /**************************************************
+ * advance to next day of week
+ *************************************************/
+ jd++;
+ }
+
+ /**************************************************
+ * print end of calendar line
+ *************************************************/
+ if ((!opt.html) && ( (h.gd_mon == month) || (h.gd_day < SHABBAT) ) )
+ {
+
+ /********************************************************
+ * determine whether this line gets special highlighting
+ ********************************************************/
+ if ((opt.colorize)
+ && ((opt.shabbat) || (opt.parasha))
+ && ((jd - 1) > opt.jd_today_h)
+ && (((jd - 1) - opt.jd_today_h) < 7) )
+ this_week = TRUE;
+ else this_week = FALSE;
+
+ /*************************************************
+ * print shabbat times
+ *************************************************/
+ if (opt.shabbat)
+ {
+ // candlelighting times
+ /// note: compiler incorrectly issued warnings:
+ /// "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ /// The initialization occurs above (~line 1005) "yom_shishi = h"
+ hdate_get_utc_sun_time (yom_shishi.gd_day, yom_shishi.gd_mon, yom_shishi.gd_year,
+ opt.lat, opt.lon, &sunrise, &sunset);
+
+ // FIXME - allow for further minhag variation
+ if (opt.candles != 1) sunset = sunset - opt.candles + opt.tz;
+ else sunset = sunset + opt.tz - DEFAULT_CANDLES_MINUTES;
+
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_SHABBAT_TIMES);
+ else colorize_element(ELEMENT_SHABBAT_TIMES);
+ }
+ printf (" %02d:%02d", sunset / 60, sunset % 60);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+
+ printf(" - ");
+
+ // motzay shabat time
+ hdate_get_utc_sun_time_full (h.gd_day, h.gd_mon, h.gd_year, opt.lat,
+ opt.lon, &sun_hour, &first_light, &talit,
+ &sunrise, &midday, &sunset,
+ &first_stars, &three_stars);
+
+ // FIXME - allow for further minhag variation
+ if (opt.havdalah != 1) three_stars = sunset + opt.havdalah + opt.tz;
+ else three_stars = three_stars + opt.tz;
+
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_SHABBAT_TIMES);
+ else colorize_element(ELEMENT_SHABBAT_TIMES);
+ }
+ printf ("%02d:%02d", three_stars / 60, three_stars % 60);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+ }
+
+
+ /*************************************************
+ * print shabbat name
+ *************************************************/
+ if (opt.parasha)
+ {
+
+ /*************************************************
+ * print shabbat name - force-hebrew setup
+ *************************************************/
+ // BUG - this isn't thread-safe
+ /*if (opt.force_hebrew)
+ {
+ language=getenv("LANGUAGE");
+ setenv("LANGUAGE", "he_IL.UTF-8", 1);
+ }*/
+
+
+ shabbat_name = hdate_get_parasha (&h, opt.diaspora);
+ if (shabbat_name) shabbat_name_str =
+ hdate_string( HDATE_STRING_PARASHA, shabbat_name,
+ HDATE_STRING_SHORT, opt.force_hebrew);
+ else
+ {
+ shabbat_name = hdate_get_holyday(&h, opt.diaspora);
+ if (shabbat_name) shabbat_name_str =
+ hdate_string( HDATE_STRING_HOLIDAY,
+ shabbat_name,
+ HDATE_STRING_SHORT, opt.force_hebrew);
+ }
+ if (shabbat_name)
+ {
+ if (opt.colorize)
+ {
+ if (this_week) colorize_element(ELEMENT_THIS_PARASHA);
+ else colorize_element(ELEMENT_PARASHA);
+ }
+ if (opt.bidi)
+ {
+ shabbat_name_str_len = strlen(shabbat_name_str);
+ shabbat_name_buffer = malloc(shabbat_name_str_len+1);
+ memcpy(shabbat_name_buffer, shabbat_name_str, shabbat_name_str_len);
+ shabbat_name_buffer[shabbat_name_str_len] = '\0';
+ revstr(shabbat_name_buffer, shabbat_name_str_len);
+
+ // padding - FIXME - spaces are single-byte, while
+ // the Hebrew characters are two bytes
+ const int margin_max = 15;
+ printf("%*s%s", (int)(margin_max - shabbat_name_str_len/2)," ", shabbat_name_buffer);
+
+ free(shabbat_name_buffer);
+ }
+ else printf(" %s", shabbat_name_str);
+ //if (opt.force_hebrew) setenv("LANGUAGE", language, 1);
+ if (opt.colorize) printf (CODE_RESTORE_VIDEO);
+ }
+ }
+ }
+}
+
+
+
+
+/**************************************************
+* print month table
+*************************************************/
+int print_calendar ( const int current_month, const int current_year, const option_list opt)
+{
+ hdate_struct h;
+ int calendar_line;
+ int max_calendar_lines = 4;
+ /// the initializations on next line aren't truly necessary, but they do
+ /// suppress warning "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ int previous_month = 1, next_month = 1;
+ int previous_year, next_year;
+ /// the initializations on next line aren't truly necessary, but they do
+ /// suppress warning "may be used uninitialized in this function [-Wmaybe-uninitialized]"
+ int jd_current_month, jd_previous_month = 1, jd_next_month = 1;
+
+ void how_many_calendar_lines( int month, int start_dow )
+ {
+ switch (month)
+ {
+ case 4:
+ case 6:
+ case 9:
+ case 11: if (start_dow == 7) max_calendar_lines = 6;
+ else if (max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ case 8:
+ case 10:
+ case 12: if (start_dow > 5) max_calendar_lines = 6;
+ else if (max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ case 2: if (start_dow > 1 && max_calendar_lines == 4) max_calendar_lines = 5;
+ break;
+ }
+ }
+
+ /*********************************************************
+ * Preliminaries:
+ * - Find the first sunday(s) of each calendar
+ * - Find number of calendar lines
+ *********************************************************/
+ hdate_set_gdate (&h, 1, current_month, current_year);
+ jd_current_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+
+ /*********************************************************
+ * three months, side-by-side
+ *********************************************************/
+ if (opt.three_month)
+ {
+ /*********************************************************
+ * previous month
+ *********************************************************/
+ if (current_month == 1)
+ {
+ previous_month = 12;
+ previous_year = current_year - 1;
+ }
+ else
+ {
+ previous_month = current_month - 1;
+ previous_year = current_year;
+ }
+ hdate_set_gdate (&h, 1, previous_month, previous_year);
+ jd_previous_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+
+ /*********************************************************
+ * next month
+ *********************************************************/
+ if (current_month == 12)
+ {
+ next_month = 1;
+ next_year = current_year + 1;
+ }
+ else
+ {
+ next_month = current_month + 1;
+ next_year = current_year;
+ }
+ hdate_set_gdate (&h, 1, next_month, next_year);
+ jd_next_month = h.hd_jd - h.hd_dw + 1;
+ how_many_calendar_lines( h.gd_mon, h.hd_dw );
+ }
+
+
+
+ /**************************************************
+ * maximum six lines of calendar
+ **************************************************/
+ for (calendar_line = 0; calendar_line < max_calendar_lines; calendar_line++)
+ {
+ if (opt.html) printf ("
---|---|