class Calendario::Renderers::MonthRenderer

Renders a month line by line

@api private

Constants

EMPTY_DAY_SPACES

The space of an empty day @return [String]

MONTH_WIDTH

Width of a rendered month @return [Integer]

WEEKDAY_INITIALS

Initials of each week day @return [String]

Attributes

filter[RW]

A proc to be executed on each date to define what is displayed on each day

@api private @return [Proc]

Public Class Methods

new() click to toggle source

Initializes a month renderer

@api private

# File lib/calendario/renderers/month_renderer.rb, line 34
def initialize
  @filter = proc { |date| date.day.to_s.rjust(2) }
end

Public Instance Methods

render(month) click to toggle source

Renders a month

@api private @param [Month] month The month to be rendered @return [RenderedMonth]

# File lib/calendario/renderers/month_renderer.rb, line 44
def render(month)
  weeks = build_weeks(month).map { |week| week.join(' ') }

  lines = [
    center_name(month),
    WEEKDAY_INITIALS,
    *weeks
  ]

  RenderedMonth.new(lines)
end

Private Instance Methods

add_leading_spaces(week) click to toggle source

Prepends leading spaces in a week until the first day of the week is found

@api private @param [Array<Date>] week A list of days in a week @return [void]

# File lib/calendario/renderers/month_renderer.rb, line 92
def add_leading_spaces(week)
  first_day_is_sunday = week.first.wday.zero?
  return if first_day_is_sunday

  week.first.wday.times { week.unshift(EMPTY_DAY_SPACES) }
end
add_trailing_spaces(week) click to toggle source

Appends trailing spaces in a week until it has 7 items

@api private @param [Array<Date>] week A list of days in a week @return [void]

# File lib/calendario/renderers/month_renderer.rb, line 105
def add_trailing_spaces(week)
  (6 - week.last.wday).abs.times { week.push(EMPTY_DAY_SPACES) }
end
apply_filter(date_or_string) click to toggle source

Applies a filter on a date or a blank space

@api private @param [Date|String] date_or_string A date or a string to be parsed by a filter @return [Date|String]

# File lib/calendario/renderers/month_renderer.rb, line 82
def apply_filter(date_or_string)
  date_or_string.is_a?(Date) ? filter.call(date_or_string) : date_or_string
end
build_weeks(month) click to toggle source

Builds all weeks in a month, applying a filter on every date

@api private @param [Month] month The month containing the weeks @return [Array<Date|String>]

# File lib/calendario/renderers/month_renderer.rb, line 64
def build_weeks(month)
  weeks = month.weeks

  add_leading_spaces(month.weeks.first)
  add_trailing_spaces(month.weeks.last)

  weeks << [EMPTY_DAY_SPACES] * 7 if month.weeks.size == 5
  weeks.map do |week|
    week.map(&method(:apply_filter))
  end
end
center_name(month) click to toggle source

Centers the month's name horizontally

@api private @param [Month] month The month to be centered @return [String]

# File lib/calendario/renderers/month_renderer.rb, line 115
def center_name(month)
  month.name.center(MONTH_WIDTH)
end