Class: Chamomile::Style

Inherits:
Object
  • Object
show all
Defined in:
lib/chamomile/styling/style.rb

Constant Summary collapse

BOLD =

Property symbols

:bold
ITALIC =
:italic
FAINT =
:faint
:blink
STRIKETHROUGH =
:strikethrough
UNDERLINE =
:underline
REVERSE =
:reverse
FOREGROUND =
:foreground
BACKGROUND =
:background
TAB_WIDTH =
:tab_width
INLINE =
:inline
TRANSFORM =
:transform
WIDTH =
:width
HEIGHT =
:height
MAX_WIDTH =
:max_width
MAX_HEIGHT =
:max_height
PADDING_TOP =
:padding_top
PADDING_RIGHT =
:padding_right
PADDING_BOTTOM =
:padding_bottom
PADDING_LEFT =
:padding_left
MARGIN_TOP =
:margin_top
MARGIN_RIGHT =
:margin_right
MARGIN_BOTTOM =
:margin_bottom
MARGIN_LEFT =
:margin_left
BORDER_STYLE =
:border_style
BORDER_TOP =
:border_top
BORDER_RIGHT =
:border_right
BORDER_BOTTOM =
:border_bottom
BORDER_LEFT =
:border_left
BORDER_TOP_FG =
:border_top_fg
BORDER_RIGHT_FG =
:border_right_fg
BORDER_BOTTOM_FG =
:border_bottom_fg
BORDER_LEFT_FG =
:border_left_fg
BORDER_TOP_BG =
:border_top_bg
BORDER_RIGHT_BG =
:border_right_bg
BORDER_BOTTOM_BG =
:border_bottom_bg
BORDER_LEFT_BG =
:border_left_bg
ALIGN_HORIZONTAL =
:align_horizontal
ALIGN_VERTICAL =
:align_vertical
UNDERLINE_SPACES =
:underline_spaces
STRIKETHROUGH_SPACES =
:strikethrough_spaces
COLOR_WHITESPACE =
:color_whitespace
SGR_CODES =
{
  BOLD => "1",
  FAINT => "2",
  ITALIC => "3",
  UNDERLINE => "4",
  BLINK => "5",
  REVERSE => "7",
  STRIKETHROUGH => "9",
}.freeze
DEFAULT_TAB_WIDTH =
4
EMPTY =

Empty style singleton

new.freeze

Instance Method Summary collapse

Constructor Details

#initializeStyle

Returns a new instance of Style.



61
62
63
# File 'lib/chamomile/styling/style.rb', line 61

def initialize
  @set_props = Set.new
end

Instance Method Details

#align(*positions) ⇒ Object

--- Alignment ---



171
172
173
174
175
176
# File 'lib/chamomile/styling/style.rb', line 171

def align(*positions)
  copy = dup
  copy.set_prop!(:align_horizontal, Chamomile.resolve_position(positions[0])) if positions.length >= 1
  copy.set_prop!(:align_vertical, Chamomile.resolve_position(positions[1])) if positions.length >= 2
  copy
end

#align_horizontal(pos) ⇒ Object



178
# File 'lib/chamomile/styling/style.rb', line 178

def align_horizontal(pos) = assign_prop(:align_horizontal, Chamomile.resolve_position(pos))

#align_vertical(pos) ⇒ Object



179
# File 'lib/chamomile/styling/style.rb', line 179

def align_vertical(pos) = assign_prop(:align_vertical, Chamomile.resolve_position(pos))

#background(color) ⇒ Object



78
# File 'lib/chamomile/styling/style.rb', line 78

def background(color) = assign_prop(:background, Color.parse(color))

#background_colorObject



198
# File 'lib/chamomile/styling/style.rb', line 198

def background_color = @background


70
# File 'lib/chamomile/styling/style.rb', line 70

def blink(v = true) = assign_prop(:blink, v)

#blink?Boolean

Returns:

  • (Boolean)


192
# File 'lib/chamomile/styling/style.rb', line 192

def blink? = !!@blink

#bold(v = true) ⇒ Object

--- Text attributes ---



67
# File 'lib/chamomile/styling/style.rb', line 67

def bold(v = true) = assign_prop(:bold, v)

#bold?Boolean

--- Public query methods ---

Returns:

  • (Boolean)


189
# File 'lib/chamomile/styling/style.rb', line 189

def bold? = !!@bold

#border(style, *sides) ⇒ Object

--- Border ---



132
133
134
135
136
137
# File 'lib/chamomile/styling/style.rb', line 132

def border(style, *sides)
  copy = dup
  copy.set_prop!(:border_style, style)
  copy.send(:apply_border_sides, sides)
  copy
end

#border_background(*colors) ⇒ Object



154
155
156
157
158
# File 'lib/chamomile/styling/style.rb', line 154

def border_background(*colors)
  copy = dup
  copy.send(:apply_border_colors, colors, :bg)
  copy
end

#border_bottom(v = true) ⇒ Object



145
# File 'lib/chamomile/styling/style.rb', line 145

def border_bottom(v = true) = assign_prop(:border_bottom, v)

#border_bottom?Boolean

Returns:

  • (Boolean)


201
# File 'lib/chamomile/styling/style.rb', line 201

def border_bottom? = !!@border_bottom

#border_bottom_background(color) ⇒ Object



166
# File 'lib/chamomile/styling/style.rb', line 166

def border_bottom_background(color) = assign_prop(:border_bottom_bg, Color.parse(color))

#border_bottom_foreground(color) ⇒ Object



162
# File 'lib/chamomile/styling/style.rb', line 162

def border_bottom_foreground(color) = assign_prop(:border_bottom_fg, Color.parse(color))

#border_foreground(*colors) ⇒ Object



148
149
150
151
152
# File 'lib/chamomile/styling/style.rb', line 148

def border_foreground(*colors)
  copy = dup
  copy.send(:apply_border_colors, colors, :fg)
  copy
end

#border_left(v = true) ⇒ Object



146
# File 'lib/chamomile/styling/style.rb', line 146

def border_left(v = true) = assign_prop(:border_left, v)

#border_left?Boolean

Returns:

  • (Boolean)


202
# File 'lib/chamomile/styling/style.rb', line 202

def border_left? = !!@border_left

#border_left_background(color) ⇒ Object



167
# File 'lib/chamomile/styling/style.rb', line 167

def border_left_background(color) = assign_prop(:border_left_bg, Color.parse(color))

#border_left_foreground(color) ⇒ Object



163
# File 'lib/chamomile/styling/style.rb', line 163

def border_left_foreground(color) = assign_prop(:border_left_fg, Color.parse(color))

#border_right(v = true) ⇒ Object



144
# File 'lib/chamomile/styling/style.rb', line 144

def border_right(v = true) = assign_prop(:border_right, v)

#border_right?Boolean

Returns:

  • (Boolean)


200
# File 'lib/chamomile/styling/style.rb', line 200

def border_right? = !!@border_right

#border_right_background(color) ⇒ Object



165
# File 'lib/chamomile/styling/style.rb', line 165

def border_right_background(color) = assign_prop(:border_right_bg, Color.parse(color))

#border_right_foreground(color) ⇒ Object



161
# File 'lib/chamomile/styling/style.rb', line 161

def border_right_foreground(color) = assign_prop(:border_right_fg, Color.parse(color))

#border_style(style) ⇒ Object



139
140
141
# File 'lib/chamomile/styling/style.rb', line 139

def border_style(style)
  assign_prop(:border_style, style)
end

#border_top(v = true) ⇒ Object



143
# File 'lib/chamomile/styling/style.rb', line 143

def border_top(v = true) = assign_prop(:border_top, v)

#border_top?Boolean

Returns:

  • (Boolean)


199
# File 'lib/chamomile/styling/style.rb', line 199

def border_top? = !!@border_top

#border_top_background(color) ⇒ Object



164
# File 'lib/chamomile/styling/style.rb', line 164

def border_top_background(color) = assign_prop(:border_top_bg, Color.parse(color))

#border_top_foreground(color) ⇒ Object



160
# File 'lib/chamomile/styling/style.rb', line 160

def border_top_foreground(color) = assign_prop(:border_top_fg, Color.parse(color))

#color_whitespace(v = true) ⇒ Object



185
# File 'lib/chamomile/styling/style.rb', line 185

def color_whitespace(v = true) = assign_prop(:color_whitespace, v)

#color_whitespace?Boolean

Returns:

  • (Boolean)


205
# File 'lib/chamomile/styling/style.rb', line 205

def color_whitespace? = !!@color_whitespace

#copyObject



233
234
235
# File 'lib/chamomile/styling/style.rb', line 233

def copy
  dup
end

#faint(v = true) ⇒ Object



69
# File 'lib/chamomile/styling/style.rb', line 69

def faint(v = true) = assign_prop(:faint, v)

#faint?Boolean

Returns:

  • (Boolean)


191
# File 'lib/chamomile/styling/style.rb', line 191

def faint? = !!@faint

#foreground(color) ⇒ Object

--- Colors ---



77
# File 'lib/chamomile/styling/style.rb', line 77

def foreground(color) = assign_prop(:foreground, Color.parse(color))

#foreground_colorObject



197
# File 'lib/chamomile/styling/style.rb', line 197

def foreground_color = @foreground

#height(n) ⇒ Object



92
# File 'lib/chamomile/styling/style.rb', line 92

def height(n) = assign_prop(:height, n)

#inherit(other) ⇒ Object

--- Inheritance ---



209
210
211
212
213
214
215
216
217
218
# File 'lib/chamomile/styling/style.rb', line 209

def inherit(other)
  copy = dup
  other.set_props.each do |prop|
    next if copy.set_props.include?(prop)

    copy.instance_variable_set(:"@#{prop}", other.instance_variable_get(:"@#{prop}"))
    copy.set_props.add(prop)
  end
  copy
end

#inline(v = true) ⇒ Object



83
# File 'lib/chamomile/styling/style.rb', line 83

def inline(v = true) = assign_prop(:inline, v)

#inline?Boolean

Returns:

  • (Boolean)


196
# File 'lib/chamomile/styling/style.rb', line 196

def inline? = !!@inline

#italic(v = true) ⇒ Object



68
# File 'lib/chamomile/styling/style.rb', line 68

def italic(v = true) = assign_prop(:italic, v)

#italic?Boolean

Returns:

  • (Boolean)


190
# File 'lib/chamomile/styling/style.rb', line 190

def italic? = !!@italic

#margin(*args) ⇒ Object

--- Margin (CSS shorthand) ---



115
116
117
118
119
120
121
122
123
# File 'lib/chamomile/styling/style.rb', line 115

def margin(*args)
  top, right, bottom, left = expand_shorthand(args)
  copy = dup
  copy.set_prop!(:margin_top, top)
  copy.set_prop!(:margin_right, right)
  copy.set_prop!(:margin_bottom, bottom)
  copy.set_prop!(:margin_left, left)
  copy
end

#margin_bottom(n) ⇒ Object



127
# File 'lib/chamomile/styling/style.rb', line 127

def margin_bottom(n) = assign_prop(:margin_bottom, n)

#margin_left(n) ⇒ Object



128
# File 'lib/chamomile/styling/style.rb', line 128

def margin_left(n) = assign_prop(:margin_left, n)

#margin_right(n) ⇒ Object



126
# File 'lib/chamomile/styling/style.rb', line 126

def margin_right(n) = assign_prop(:margin_right, n)

#margin_top(n) ⇒ Object



125
# File 'lib/chamomile/styling/style.rb', line 125

def margin_top(n) = assign_prop(:margin_top, n)

#max_height(n) ⇒ Object



94
# File 'lib/chamomile/styling/style.rb', line 94

def max_height(n) = assign_prop(:max_height, n)

#max_width(n) ⇒ Object



93
# File 'lib/chamomile/styling/style.rb', line 93

def max_width(n) = assign_prop(:max_width, n)

#merge(other) ⇒ Object

Merge another style on top of this one. The other style's set properties win.



238
239
240
241
242
243
244
245
246
# File 'lib/chamomile/styling/style.rb', line 238

def merge(other)
  return dup if other.nil?

  copy = dup
  other.set_props.each do |prop|
    copy.set_prop!(prop, other.instance_variable_get(:"@#{prop}"))
  end
  copy
end

#padding(*args) ⇒ Object

--- Padding (CSS shorthand) ---



98
99
100
101
102
103
104
105
106
# File 'lib/chamomile/styling/style.rb', line 98

def padding(*args)
  top, right, bottom, left = expand_shorthand(args)
  copy = dup
  copy.set_prop!(:padding_top, top)
  copy.set_prop!(:padding_right, right)
  copy.set_prop!(:padding_bottom, bottom)
  copy.set_prop!(:padding_left, left)
  copy
end

#padding_bottom(n) ⇒ Object



110
# File 'lib/chamomile/styling/style.rb', line 110

def padding_bottom(n) = assign_prop(:padding_bottom, n)

#padding_left(n) ⇒ Object



111
# File 'lib/chamomile/styling/style.rb', line 111

def padding_left(n) = assign_prop(:padding_left, n)

#padding_right(n) ⇒ Object



109
# File 'lib/chamomile/styling/style.rb', line 109

def padding_right(n) = assign_prop(:padding_right, n)

#padding_top(n) ⇒ Object



108
# File 'lib/chamomile/styling/style.rb', line 108

def padding_top(n) = assign_prop(:padding_top, n)

#render(*strs) ⇒ Object

--- Render ---



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/chamomile/styling/style.rb', line 253

def render(*strs)
  text = strs.join(" ")

  # Apply transform
  text = @transform.call(text) if @transform

  # Convert tabs
  tw = effective_tab_width
  text = text.gsub("\t", " " * tw) if tw.positive?

  # Calculate dimensions
  content_width = compute_content_width
  target_height = effective_height

  # Word wrap if width is set
  text = Wrap.word_wrap(text, content_width) if content_width.positive?

  lines = text.split("\n", -1)
  lines = [""] if lines.empty?

  # Apply text SGR per line
  sgr = build_sgr
  lines = apply_sgr_to_lines(lines, sgr)

  # Alignment (inside border, after SGR)
  lines = apply_alignment(lines, content_width) if content_width.positive?

  # Enforce inner content height (before padding/border)
  if target_height.positive?
    inner_height = compute_inner_height(target_height)
    lines = enforce_height(lines, inner_height) if inner_height.positive?
  end

  # Padding
  lines = apply_padding(lines)

  # Border
  lines = apply_border(lines) if effective_border_style

  # Margin
  lines = apply_margin(lines)

  # Enforce max constraints
  lines = enforce_max_width(lines)
  lines = enforce_max_height(lines)

  lines.join("\n")
end

#reverse(v = true) ⇒ Object



73
# File 'lib/chamomile/styling/style.rb', line 73

def reverse(v = true) = assign_prop(:reverse, v)

#reverse?Boolean

Returns:

  • (Boolean)


195
# File 'lib/chamomile/styling/style.rb', line 195

def reverse? = !!@reverse

#set?(prop) ⇒ Boolean

Returns:

  • (Boolean)


229
230
231
# File 'lib/chamomile/styling/style.rb', line 229

def set?(prop)
  @set_props.include?(prop)
end

#strikethrough(v = true) ⇒ Object



71
# File 'lib/chamomile/styling/style.rb', line 71

def strikethrough(v = true) = assign_prop(:strikethrough, v)

#strikethrough?Boolean

Returns:

  • (Boolean)


193
# File 'lib/chamomile/styling/style.rb', line 193

def strikethrough? = !!@strikethrough

#strikethrough_spaces(v = true) ⇒ Object



184
# File 'lib/chamomile/styling/style.rb', line 184

def strikethrough_spaces(v = true) = assign_prop(:strikethrough_spaces, v)

#strikethrough_spaces?Boolean

Returns:

  • (Boolean)


204
# File 'lib/chamomile/styling/style.rb', line 204

def strikethrough_spaces? = !!@strikethrough_spaces

#tab_width(n) ⇒ Object

--- Utility ---



82
# File 'lib/chamomile/styling/style.rb', line 82

def tab_width(n) = assign_prop(:tab_width, n)

#transform(&block) ⇒ Object



85
86
87
# File 'lib/chamomile/styling/style.rb', line 85

def transform(&block)
  assign_prop(:transform, block)
end

#underline(v = true) ⇒ Object



72
# File 'lib/chamomile/styling/style.rb', line 72

def underline(v = true) = assign_prop(:underline, v)

#underline?Boolean

Returns:

  • (Boolean)


194
# File 'lib/chamomile/styling/style.rb', line 194

def underline? = !!@underline

#underline_spaces(v = true) ⇒ Object

--- Whitespace options ---



183
# File 'lib/chamomile/styling/style.rb', line 183

def underline_spaces(v = true) = assign_prop(:underline_spaces, v)

#underline_spaces?Boolean

Returns:

  • (Boolean)


203
# File 'lib/chamomile/styling/style.rb', line 203

def underline_spaces? = !!@underline_spaces

#unset(*props) ⇒ Object



220
221
222
223
224
225
226
227
# File 'lib/chamomile/styling/style.rb', line 220

def unset(*props)
  copy = dup
  props.each do |prop|
    copy.set_props.delete(prop)
    copy.instance_variable_set(:"@#{prop}", nil)
  end
  copy
end

#width(n) ⇒ Object

--- Dimensions ---



91
# File 'lib/chamomile/styling/style.rb', line 91

def width(n) = assign_prop(:width, n)