Class: Currency::Formatter

Inherits:
Object show all
Defined in:
lib/currency/formatter.rb

Overview

This class formats a Money value as a String. Each Currency has a default Formatter.

Defined Under Namespace

Classes: Template

Constant Summary collapse

@@default =
nil
@@empty_hash =
{ }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opt = { }) ⇒ Formatter

Returns a new instance of Formatter.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/currency/formatter.rb', line 149

def initialize(opt = { })
  @thousands_separator = ','
  @decimal_separator = '.'
  @thousands = true
  @cents = true
  @symbol = true
  @code = false
  @html = false
  @time = false
  @time_fractional_digits = 4
  @template = '#{code}#{code && " "}#{symbol}#{sign}#{whole}#{fraction}#{time && " "}#{time}'
  @template_object = nil
  @decimals = nil

  opt.each_pair{ | k, v | self.send("#{k}=", v) }
end

Instance Attribute Details

#centsObject

If true, append decimal_separator and decimal digits after whole value.



88
89
90
# File 'lib/currency/formatter.rb', line 88

def cents
  @cents
end

#codeObject

If true, append currency code.



94
95
96
# File 'lib/currency/formatter.rb', line 94

def code
  @code
end

#decimal_separatorObject

Defaults to ‘.’



82
83
84
# File 'lib/currency/formatter.rb', line 82

def decimal_separator
  @decimal_separator
end

#decimalsObject

Set the decimal_places Defaults to: nil



117
118
119
# File 'lib/currency/formatter.rb', line 117

def decimals
  @decimals
end

#htmlObject

If true, use html formatting.

Currency::Money(12.45, :EUR).to_s(:html => true; :code => true)
=> "&#8364;12.45 <span class=\"currency_code\">EUR</span>"


107
108
109
# File 'lib/currency/formatter.rb', line 107

def html
  @html
end

#symbolObject

If true, prefix value with currency symbol.



91
92
93
# File 'lib/currency/formatter.rb', line 91

def symbol
  @symbol
end

#templateObject

A template string used to format a money value. Defaults to:

'#{code}#{code && " "}#{symbol}#{sign}#{whole}#{fraction}#{time && " "}#{time}'


113
114
115
# File 'lib/currency/formatter.rb', line 113

def template
  @template
end

#thousandsObject

If true, insert thousands_separator between each 3 digits in the whole value.



85
86
87
# File 'lib/currency/formatter.rb', line 85

def thousands
  @thousands
end

#thousands_separatorObject

Defaults to ‘,’



79
80
81
# File 'lib/currency/formatter.rb', line 79

def thousands_separator
  @thousands_separator
end

#timeObject

If true, append the time.



97
98
99
# File 'lib/currency/formatter.rb', line 97

def time
  @time
end

#time_fractional_digitsObject

The number of fractional digits in the time. Defaults to 4.



101
102
103
# File 'lib/currency/formatter.rb', line 101

def time_fractional_digits
  @time_fractional_digits
end

Class Method Details

.defaultObject

Get the default Formatter.



138
139
140
# File 'lib/currency/formatter.rb', line 138

def self.default
  @@default || self.new
end

.default=(x) ⇒ Object

Set the default Formatter.



144
145
146
# File 'lib/currency/formatter.rb', line 144

def self.default=(x)
  @@default = x
end

Instance Method Details

#_format(m, currency = nil, time = nil) ⇒ Object

:nodoc:



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/currency/formatter.rb', line 194

def _format(m, currency = nil, time = nil) # :nodoc:
  # Get currency.
  currency ||= m.currency

  # Get time.
  time ||= m.time
  
  # set decimal places
  @decimals ||= currency.scale_exp

  # Setup template
  tmpl = self.template_object.clone
  # $stderr.puts "template.template = #{tmpl.template.inspect}"
  tmpl.money = m
  tmpl.currency = currency

  # Get scaled integer representation for this Currency.
  # $stderr.puts "m.currency = #{m.currency}, currency => #{currency}"
  x = m.Money_rep(currency)

  # Remove sign.
  x = - x if ( neg = x < 0 )
  tmpl.sign = neg ? '-' : nil
  
  # Convert to String.
  x = x.to_s
  
  # Keep prefixing "0" until filled to scale.
  while ( x.length <= currency.scale_exp )
    x = "0" + x
  end
  
  # Insert decimal place.
  whole = x[0 .. currency.format_left]
  fraction = x[currency.format_right .. -1]
  
  # Round the fraction to the supplied number of decimal places
  fraction = (fraction.to_f / currency.scale).round(@decimals).to_s[2..-1]
  # raise "decimals: #{@decimals}, scale_exp: #{currency.scale_exp}, x is: #{x.inspect}, currency.scale_exp is #{currency.scale_exp.inspect}, fraction: #{fraction.inspect}"
  while ( fraction.length < @decimals )
    fraction = fraction + "0" 
  end
  
  
  # raise "x is: #{x.inspect}, currency.scale_exp is #{currency.scale_exp.inspect}, fraction: #{fraction.inspect}"
  # fraction = ((fraction.to_f / currency.scale).round(decimals) * (10 ** decimals)).to_i.to_s
  
  # Do thousands.
  x = whole
  if @thousands && (@thousands_separator && ! @thousands_separator.empty?)
    x.reverse!
    x.gsub!(/(\d\d\d)/) {|y| y + @thousands_separator}
    x.sub!(/#{@thousands_separator}$/,'')
    x.reverse!
  end
  
  # Put whole and fractional parts.
  tmpl.whole = x
  tmpl.fraction = @cents && @decimal_separator ? @decimal_separator + fraction : nil

 
  # Add symbol?
  tmpl.symbol = @symbol ? ((@html && currency.symbol_html) || currency.symbol) : nil

  
  # Add currency code.
  tmpl.code = @code ? _format_Currency(currency) : nil

  # Add time.
  tmpl.time = @time && time ? _format_Time(time) : nil
  
  # Ask template to format the components.
  tmpl.format
end

#_format_Currency(c) ⇒ Object

:nodoc:



270
271
272
273
274
275
276
# File 'lib/currency/formatter.rb', line 270

def _format_Currency(c) # :nodoc:
  x = ''
  x << '<span class="currency_code">' if @html
  x << c.code.to_s
  x << '</span>' if @html
  x
end

#_format_Time(t) ⇒ Object

:nodoc:



279
280
281
282
283
# File 'lib/currency/formatter.rb', line 279

def _format_Time(t) # :nodoc:
  x = ''
  x << t.getutc.xmlschema(@time_fractional_digits) if t
  x
end

#as_input_value=(x) ⇒ Object

If passed true, formats for an input field (i.e.: as a number).



120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/currency/formatter.rb', line 120

def as_input_value=(x)
  if x
    self.thousands_separator = ''
    self.decimal_separator = '.'
    self.thousands = false
    self.cents = true
    self.symbol = false
    self.code = false
    self.html = false
    self.time = false
    self.time_fractional_digits = nil
  end
  x
end

#currency=(x) ⇒ Object

:nodoc:



167
168
169
# File 'lib/currency/formatter.rb', line 167

def currency=(x) # :nodoc:
  # DO NOTHING!
end

#format(m, opt = @@empty_hash) ⇒ Object

Format a Money object as a String.

m = Money.new("1234567.89")
m.to_s(:code => true, :symbol => false)
  => "1,234,567.89 USD"


295
296
297
298
299
300
301
302
303
304
305
# File 'lib/currency/formatter.rb', line 295

def format(m, opt = @@empty_hash)
  fmt = self

  unless opt.empty? 
    fmt = fmt.clone
    opt.each_pair{ | k, v | fmt.send("#{k}=", v) }
  end

  # $stderr.puts "format(opt = #{opt.inspect})"
  fmt._format(m, opt[:currency]) # Allow override of current currency.
end

#template_objectObject

Returns the Template object.



182
183
184
185
186
187
188
189
190
191
# File 'lib/currency/formatter.rb', line 182

def template_object
  return @template_object if @template_object

  @template_object = Template.new
  @template_object.template = @template if @template
  # $stderr.puts "template.template = #{@template_object.template.inspect}"
  @template_object.template_proc # pre-cache before clone.

  @template_object
end