module BomRainReport
BomRainReport — compact rain-summary line formatting for BOM forecasts.
Constants
- BAR_DIGIT_GUARD
- BAR_EMPTY_STYLE
-
Default fg/bg for unfilled bar tails (btop-style empty segment after \x03 reset). Zero-width space before digit-led tails avoids \x0399,9960 mIRC parse errors.
- DAY_SHORT_NAMES
- RAIN_STYLE_MAX_MM
-
Rainfall mm thresholds → [fg, bg] pairs from Ibis echocolors (reference/stuff/aliases1.ibis). 16 stops linearly across 0–100 mm using all mIRC colour indices 1–16.
- RAIN_STYLE_PAIRS
- RAIN_STYLE_STOPS
Public Instance Methods
Source
# File lib/bom_rain_report.rb, line 133 def apply_rain_chance_bar(plain, percent, style:) percent = [[percent.to_f, 0].max, 100].min bar_zone = rain_chance_bar_zone(plain) return plain if bar_zone.empty? zone_width = bar_zone.length filled = rain_chance_bar_fill_length(bar_zone, percent) return plain if filled <= 0 head = plain[0, filled] zone_tail = plain[filled, zone_width - filled] || "" after_zone = plain[zone_width..] || "" return IrcFormat.decorate(bar_zone, style) if after_zone.empty? && zone_tail.empty? empty_lead = "#{IrcFormat::RESET}#{BAR_EMPTY_STYLE}" empty_lead += BAR_DIGIT_GUARD if zone_tail.match?(/\A\d/) result = "#{style}#{head}#{empty_lead}#{zone_tail}" result += "#{IrcFormat::RESET}#{after_zone}" unless after_zone.empty? result end
Source
# File lib/bom_rain_report.rb, line 68 def compact_rainfall(amount) amount.to_s.strip.gsub(/\s+to\s+/, "-") end
Source
# File lib/bom_rain_report.rb, line 48 def compact_temp_celsius(value) text = value.to_s.strip return nil if text.empty? text.sub(/\s*°C\z/i, "") end
Source
# File lib/bom_rain_report.rb, line 40 def format_period_short(period) DAY_SHORT_NAMES.each do |pattern, short| return short if period.to_s.match?(pattern) end period.to_s.split.first.to_s[0, 3].capitalize end
Source
# File lib/bom_rain_report.rb, line 155 def format_rain_entry(day) plain = format_rain_entry_plain(day) return nil unless plain percent = parse_rain_chance_percent(day[:rain_chance]) mm = parse_rainfall_mm(day[:rainfall]) style = rain_style_for_mm(mm) bar = apply_rain_chance_bar(plain, percent, style: style) bar == plain ? bar : "#{bar}#{IrcFormat::RESET}" end
Source
# File lib/bom_rain_report.rb, line 103 def format_rain_entry_plain(day) chance = day[:rain_chance] amount = day[:rainfall] return nil if chance.nil? && amount.nil? parts = [format_period_short(day[:period])] parts << chance if chance parts << compact_rainfall(amount) if amount temps = format_rain_temps(day) parts << temps if temps parts.join(" ") end
Source
# File lib/bom_rain_report.rb, line 170 def format_rain_forecast(days) entries = days.filter_map { |day| format_rain_entry(day) } return nil if entries.empty? entries.join(rain_day_divider) end
Source
# File lib/bom_rain_report.rb, line 55 def format_rain_temps(day) min = compact_temp_celsius(day[:min]) max = compact_temp_celsius(day[:max]) if min && max "#{min}-#{max}°C" elsif max "#{max}°C" elsif min "#{min}°C" end end
Source
# File lib/bom_rain_report.rb, line 72 def parse_rain_chance_percent(chance) text = chance.to_s.strip return 0.0 if text.empty? match = text.match(/\A(\d+(?:\.\d+)?)\s*%/) match ? match[1].to_f : 0.0 end
Source
# File lib/bom_rain_report.rb, line 80 def parse_rainfall_mm(amount) text = amount.to_s.strip.downcase return 0.0 if text.empty? numbers = text.scan(/(\d+(?:\.\d+)?)/).flatten.map(&:to_f) return 0.0 if numbers.empty? numbers.max end
Source
# File lib/bom_rain_report.rb, line 124 def rain_chance_bar_fill_length(bar_zone, percent) percent = [[percent.to_f, 0].max, 100].min zone_width = bar_zone.to_s.length return 0 if percent <= 0 || zone_width.zero? return zone_width if percent >= 100 [(percent * zone_width / 100.0).round, zone_width].min end
Source
# File lib/bom_rain_report.rb, line 116 def rain_chance_bar_zone(plain) text = plain.to_s return "" if text.empty? return "" unless text.match?(/\A\S+\s+\d+(?:\.\d+)?%/) text end
Source
# File lib/bom_rain_report.rb, line 166 def rain_day_divider " #{IrcFormat.muted('|')} " end
Source
# File lib/bom_rain_report.rb, line 95 def rain_style_components(mm) mm = [mm.to_f, 0].max _stop, fg, bg = RAIN_STYLE_STOPS.reduce(RAIN_STYLE_STOPS.first) do |chosen, candidate| mm >= candidate[0] ? candidate : chosen end [fg, bg] end
Source
# File lib/bom_rain_report.rb, line 90 def rain_style_for_mm(mm) fg, bg = rain_style_components(mm) IrcFormat.color(fg, bg) end