# frozen_string_literal: true module Notare class Style attr_reader :name, :bold, :italic, :underline, :strike, :highlight, :color, :size, :font, :align, :indent, :spacing_before, :spacing_after ALIGNMENTS = %i[left center right justify].freeze HIGHLIGHT_COLORS = %w[ black blue cyan darkBlue darkCyan darkGray darkGreen darkMagenta darkRed darkYellow green lightGray magenta red white yellow ].freeze def initialize(name, bold: nil, italic: nil, underline: nil, strike: nil, highlight: nil, color: nil, size: nil, font: nil, align: nil, indent: nil, spacing_before: nil, spacing_after: nil) @name = name @bold = bold @italic = italic @underline = underline @strike = strike @highlight = validate_highlight(highlight) @color = normalize_color(color) @size = size @font = font @align = validate_align(align) @indent = indent @spacing_before = spacing_before @spacing_after = spacing_after end def style_id name.to_s.split("_").map(&:capitalize).join end def display_name name.to_s.split("_").map(&:capitalize).join(" ") end def paragraph_properties? !!(align || indent || spacing_before || spacing_after) end def text_properties? !!(bold || italic || underline || strike || highlight || color || size || font) end # Size in half-points for OOXML (14pt = 28 half-points) def size_half_points size ? (size * 2).to_i : nil end private def normalize_color(color) return nil if color.nil? hex = color.to_s.sub(/^#/, "").upcase return hex if hex.match?(/\A[0-9A-F]{6}\z/) raise ArgumentError, "Invalid color: #{color}. Use 6-digit hex (e.g., 'FF0000')" end def validate_align(align) return nil if align.nil? return align if ALIGNMENTS.include?(align) raise ArgumentError, "Invalid alignment: #{align}. Use #{ALIGNMENTS.join(", ")}" end def validate_highlight(highlight) return nil if highlight.nil? color = highlight.to_s return color if HIGHLIGHT_COLORS.include?(color) raise ArgumentError, "Invalid highlight color: #{highlight}. Use one of: #{HIGHLIGHT_COLORS.join(", ")}" end end end