# frozen_string_literal: true require 'date' # calendar methods ################################################### class HtmlSkeleton attr_reader :day_header protected def a_year(year) rows = @options[:rows] cols = 12 / rows raise 'html_skeleton_calendar: invalid option ' unless rows * cols == 12 body = (0..rows - 1).collect { |y| str = (1..cols).collect { |x| "#{a_month(year, y * cols + x)}" } "#{str.join}" } <<~THEAD #{@options[:title]} #{body.join} THEAD end def a_month(year, month) title = @options[:month_names][month] <<~TABLE #{@day_header} #{days_of_month(year, month)}
#{title}
TABLE end def days_of_month(year, month) first_weekday = @options[:first_day_of_week] last_weekday = first_weekday.positive? ? first_weekday - 1 : 6 cell_proc = @options[:cell_proc] bool = Time.respond_to?(:zone) && !(zone = Time.zone).nil? today = bool ? zone.now.to_date : Date.today first = Date.civil(year, month, 1) last = Date.civil(year, month, -1) cal = +'' cal << '' * days_between(first_weekday, first.wday) first.upto(last) { |cur| cal << a_day(cur, today, cell_proc) cal << ' ' if cur.wday == last_weekday } cal << '' * days_between((last + 1).wday, first_weekday + 7) cal << '' end def a_day(date, today, block) attrs = 'day' attrs += ' weekendDay' if weekend?(date) attrs += ' today' if date == today "#{block.call(date)}" end def weekend?(date) [0, 6].include?(date.wday) end def days_between(first, second) first > second ? second + (7 - first) : second - first end end