twitter_cldr_js 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. data/Gemfile +5 -0
  2. data/History.txt +11 -1
  3. data/README.md +103 -13
  4. data/Rakefile +1 -1
  5. data/lib/assets/javascripts/twitter_cldr/af.js +1815 -0
  6. data/lib/assets/javascripts/twitter_cldr/ar.js +1815 -0
  7. data/lib/assets/javascripts/twitter_cldr/be.js +1815 -0
  8. data/lib/assets/javascripts/twitter_cldr/bg.js +1815 -0
  9. data/lib/assets/javascripts/twitter_cldr/bn.js +1815 -0
  10. data/lib/assets/javascripts/twitter_cldr/ca.js +1815 -0
  11. data/lib/assets/javascripts/twitter_cldr/cs.js +1815 -0
  12. data/lib/assets/javascripts/twitter_cldr/cy.js +1815 -0
  13. data/lib/assets/javascripts/twitter_cldr/da.js +1815 -0
  14. data/lib/assets/javascripts/twitter_cldr/de.js +1815 -0
  15. data/lib/assets/javascripts/twitter_cldr/el.js +1815 -0
  16. data/lib/assets/javascripts/twitter_cldr/en.js +1815 -0
  17. data/lib/assets/javascripts/twitter_cldr/es.js +1815 -0
  18. data/lib/assets/javascripts/twitter_cldr/eu.js +1815 -0
  19. data/lib/assets/javascripts/twitter_cldr/fa.js +1815 -0
  20. data/lib/assets/javascripts/twitter_cldr/fi.js +1815 -0
  21. data/lib/assets/javascripts/twitter_cldr/fil.js +1815 -0
  22. data/lib/assets/javascripts/twitter_cldr/fr.js +1815 -0
  23. data/lib/assets/javascripts/twitter_cldr/ga.js +1815 -0
  24. data/lib/assets/javascripts/twitter_cldr/gl.js +1815 -0
  25. data/lib/assets/javascripts/twitter_cldr/he.js +1815 -0
  26. data/lib/assets/javascripts/twitter_cldr/hi.js +1815 -0
  27. data/lib/assets/javascripts/twitter_cldr/hu.js +1815 -0
  28. data/lib/assets/javascripts/twitter_cldr/id.js +1815 -0
  29. data/lib/assets/javascripts/twitter_cldr/it.js +1815 -0
  30. data/lib/assets/javascripts/twitter_cldr/ja.js +1815 -0
  31. data/lib/assets/javascripts/twitter_cldr/ko.js +1815 -0
  32. data/lib/assets/javascripts/twitter_cldr/lv.js +1815 -0
  33. data/lib/assets/javascripts/twitter_cldr/msa.js +1815 -0
  34. data/lib/assets/javascripts/twitter_cldr/nl.js +1815 -0
  35. data/lib/assets/javascripts/twitter_cldr/no.js +1815 -0
  36. data/lib/assets/javascripts/twitter_cldr/pl.js +1815 -0
  37. data/lib/assets/javascripts/twitter_cldr/pt.js +1815 -0
  38. data/lib/assets/javascripts/twitter_cldr/ro.js +1815 -0
  39. data/lib/assets/javascripts/twitter_cldr/ru.js +1815 -0
  40. data/lib/assets/javascripts/twitter_cldr/sk.js +1815 -0
  41. data/lib/assets/javascripts/twitter_cldr/sq.js +1815 -0
  42. data/lib/assets/javascripts/twitter_cldr/sr.js +1815 -0
  43. data/lib/assets/javascripts/twitter_cldr/sv.js +1815 -0
  44. data/lib/assets/javascripts/twitter_cldr/ta.js +1815 -0
  45. data/lib/assets/javascripts/twitter_cldr/th.js +1815 -0
  46. data/lib/assets/javascripts/twitter_cldr/tr.js +1815 -0
  47. data/lib/assets/javascripts/twitter_cldr/uk.js +1815 -0
  48. data/lib/assets/javascripts/twitter_cldr/ur.js +1815 -0
  49. data/lib/assets/javascripts/twitter_cldr/zh-cn.js +1815 -0
  50. data/lib/assets/javascripts/twitter_cldr/zh-tw.js +1815 -0
  51. data/lib/twitter_cldr/js/compiler.rb +12 -3
  52. data/lib/twitter_cldr/js/mustache/bundle.coffee +19 -1
  53. data/lib/twitter_cldr/js/mustache/calendars/additional_date_format_selector.coffee +85 -0
  54. data/lib/twitter_cldr/js/mustache/calendars/datetime.coffee +248 -226
  55. data/lib/twitter_cldr/js/mustache/calendars/timespan.coffee +19 -18
  56. data/lib/twitter_cldr/js/mustache/numbers/numbers.coffee +62 -19
  57. data/lib/twitter_cldr/js/mustache/plurals/rules.coffee +1 -1
  58. data/lib/twitter_cldr/js/mustache/shared/bidi.coffee +433 -0
  59. data/lib/twitter_cldr/js/mustache/shared/calendar.coffee +25 -0
  60. data/lib/twitter_cldr/js/mustache/shared/currencies.coffee +5 -11
  61. data/lib/twitter_cldr/js/mustache/shared/lists.coffee +40 -0
  62. data/lib/twitter_cldr/js/mustache/shared/prerender/bidi_classes.json +1 -0
  63. data/lib/twitter_cldr/js/mustache/utilities.coffee +87 -0
  64. data/lib/twitter_cldr/js/renderers.rb +23 -19
  65. data/lib/twitter_cldr/js/renderers/bundle.rb +8 -2
  66. data/lib/twitter_cldr/js/renderers/calendars/additional_date_format_selector_renderer.rb +18 -0
  67. data/lib/twitter_cldr/js/renderers/calendars/datetime_renderer.rb +13 -9
  68. data/lib/twitter_cldr/js/renderers/numbers/numbers_renderer.rb +17 -3
  69. data/lib/twitter_cldr/js/renderers/shared/bidi_renderer.rb +77 -0
  70. data/lib/twitter_cldr/js/renderers/shared/calendar_renderer.rb +20 -0
  71. data/lib/twitter_cldr/js/renderers/shared/currencies_renderer.rb +2 -2
  72. data/lib/twitter_cldr/js/renderers/shared/list_renderer.rb +22 -0
  73. data/lib/twitter_cldr/js/tasks/tasks.rake +9 -5
  74. data/lib/twitter_cldr/js/tasks/tasks.rb +6 -5
  75. data/lib/twitter_cldr/js/version.rb +1 -1
  76. data/spec/js/calendars/additional_date_format_selector.spec.js +126 -0
  77. data/spec/js/calendars/datetime.spec.js +29 -2
  78. data/spec/js/calendars/timespan.spec.js +45 -1
  79. data/spec/js/numbers/abbreviated/abbreviated_number.spec.js +47 -0
  80. data/spec/js/numbers/abbreviated/long_decimal.spec.js +57 -0
  81. data/spec/js/numbers/abbreviated/short_decimal.spec.js +57 -0
  82. data/spec/js/numbers/currency.spec.js +2 -2
  83. data/spec/js/numbers/decimal.spec.js +1 -1
  84. data/spec/js/numbers/helpers/fraction.spec.js +1 -1
  85. data/spec/js/numbers/helpers/integer.spec.js +1 -1
  86. data/spec/js/numbers/number.spec.js +1 -1
  87. data/spec/js/numbers/percent.spec.js +1 -1
  88. data/spec/js/plurals/plural_rules.spec.js +1 -1
  89. data/spec/js/shared/bidi.spec.js +105 -0
  90. data/spec/js/shared/calendar.spec.js +51 -0
  91. data/spec/js/shared/classpath_bidi_test.txt +217202 -0
  92. data/spec/js/shared/lists.spec.js +100 -0
  93. data/spec/js/utilities.spec.js +120 -0
  94. data/twitter_cldr_js.gemspec +1 -1
  95. metadata +68 -37
  96. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_af.js +0 -887
  97. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_ar.js +0 -887
  98. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_ca.js +0 -887
  99. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_cs.js +0 -887
  100. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_da.js +0 -887
  101. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_de.js +0 -887
  102. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_el.js +0 -887
  103. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_en.js +0 -887
  104. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_es.js +0 -887
  105. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_eu.js +0 -887
  106. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_fa.js +0 -887
  107. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_fi.js +0 -887
  108. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_fil.js +0 -887
  109. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_fr.js +0 -887
  110. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_he.js +0 -887
  111. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_hi.js +0 -887
  112. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_hu.js +0 -887
  113. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_id.js +0 -887
  114. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_it.js +0 -887
  115. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_ja.js +0 -887
  116. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_ko.js +0 -887
  117. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_msa.js +0 -887
  118. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_nl.js +0 -887
  119. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_no.js +0 -887
  120. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_pl.js +0 -887
  121. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_pt.js +0 -887
  122. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_ru.js +0 -887
  123. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_sv.js +0 -887
  124. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_th.js +0 -887
  125. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_tr.js +0 -887
  126. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_uk.js +0 -887
  127. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_ur.js +0 -887
  128. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_zh-cn.js +0 -887
  129. data/lib/assets/javascripts/twitter_cldr/twitter_cldr_zh-tw.js +0 -887
@@ -11,6 +11,7 @@ module TwitterCldr
11
11
  def initialize(options = {})
12
12
  @locales = options[:locales] || TwitterCldr.supported_locales
13
13
  @features = options[:features] || renderers.keys
14
+ @prerender = options[:prerender].nil? ? true : options[:prerender]
14
15
  end
15
16
 
16
17
  def compile_each(options = {})
@@ -21,12 +22,16 @@ module TwitterCldr
21
22
 
22
23
  @features.each do |feature|
23
24
  renderer_const = renderers[feature]
24
- contents << renderer_const.new(:locale => locale).render if renderer_const
25
+ contents << renderer_const.new(:locale => locale, :prerender => @prerender).render if renderer_const
25
26
  end
26
27
 
27
28
  bundle = TwitterCldr::Js::Renderers::Bundle.new
29
+ bundle[:locale] = locale
28
30
  bundle[:contents] = contents
29
- result = CoffeeScript.compile(bundle.render, :bare => true)
31
+ result = CoffeeScript.compile(bundle.render, :bare => false)
32
+
33
+ # required alias definition that adds twitter_cldr to Twitter's static build process
34
+ result.gsub!(/\/\*<<module_def>>\s+\*\//, %Q(/*-module-*/\n/*_lib/twitter_cldr_*/))
30
35
  result = Uglifier.compile(result) if options[:minify]
31
36
 
32
37
  yield result, TwitterCldr.twitter_locale(locale)
@@ -40,8 +45,12 @@ module TwitterCldr
40
45
  :plural_rules => TwitterCldr::Js::Renderers::PluralRules::PluralRulesRenderer,
41
46
  :timespan => TwitterCldr::Js::Renderers::Calendars::TimespanRenderer,
42
47
  :datetime => TwitterCldr::Js::Renderers::Calendars::DateTimeRenderer,
48
+ :additional_date_format_selector => TwitterCldr::Js::Renderers::Calendars::AdditionalDateFormatSelectorRenderer,
43
49
  :numbers => TwitterCldr::Js::Renderers::Numbers::NumbersRenderer,
44
- :currencies => TwitterCldr::Js::Renderers::Shared::CurrenciesRenderer
50
+ :currencies => TwitterCldr::Js::Renderers::Shared::CurrenciesRenderer,
51
+ :lists => TwitterCldr::Js::Renderers::Shared::ListRenderer,
52
+ :bidi => TwitterCldr::Js::Renderers::Shared::BidiRenderer,
53
+ :calendar => TwitterCldr::Js::Renderers::Shared::CalendarRenderer
45
54
  }
46
55
  end
47
56
  end
@@ -10,6 +10,24 @@
10
10
  // Description: Provides date, time, number, and list formatting functionality for various Twitter-supported locales in Javascript.
11
11
  ###
12
12
 
13
+ # required alias definition that adds twitter_cldr to Twitter's static build process
14
+ ###<<module_def>>###
15
+
13
16
  TwitterCldr = {}
17
+ {{#is_rtl?}}
18
+ TwitterCldr.is_rtl = true;
19
+ {{/is_rtl?}}
20
+ {{^is_rtl?}}
21
+ TwitterCldr.is_rtl = false;
22
+ {{/is_rtl?}}
23
+
24
+ {{> utilities}}
14
25
  {{{contents}}}
15
- exports[key] = obj for key, obj of TwitterCldr if exports? # for node
26
+
27
+ root = if exports?
28
+ exports
29
+ else
30
+ this.TwitterCldr = {}
31
+ this.TwitterCldr
32
+
33
+ root[key] = obj for key, obj of TwitterCldr
@@ -0,0 +1,85 @@
1
+ # Copyright 2012 Twitter, Inc
2
+ # http://www.apache.org/licenses/LICENSE-2.0
3
+
4
+ class TwitterCldr.AdditionalDateFormatSelector
5
+ constructor: (pattern_hash) ->
6
+ @pattern_hash = pattern_hash
7
+
8
+ find_closest: (goal_pattern) ->
9
+ if !goal_pattern? || goal_pattern.trim().length == 0
10
+ null
11
+ else
12
+ ranks = this.rank(goal_pattern)
13
+ min_rank = 100
14
+ min_key = null
15
+
16
+ for key, rank of ranks
17
+ if rank < min_rank
18
+ min_rank = rank
19
+ min_key = key
20
+
21
+ min_key
22
+
23
+ patterns: ->
24
+ key for key of @pattern_hash
25
+
26
+ separate: (pattern_key) ->
27
+ last_char = ""
28
+ result = []
29
+
30
+ for cur_char in pattern_key
31
+ if cur_char == last_char
32
+ result[result.length - 1] += cur_char
33
+ else
34
+ result.push(cur_char)
35
+
36
+ last_char = cur_char
37
+
38
+ result
39
+
40
+ all_separated_patterns: ->
41
+ this.separate(key) for key of @pattern_hash
42
+
43
+ score: (entities, goal_entities) ->
44
+ # weight existence a little more heavily than the others
45
+ score = this.exist_score(entities, goal_entities) * 2
46
+ score += this.position_score(entities, goal_entities)
47
+ score + this.count_score(entities, goal_entities)
48
+
49
+ position_score: (entities, goal_entities) ->
50
+ sum = 0
51
+
52
+ for index, goal_entity of goal_entities
53
+ found = entities.indexOf(goal_entity)
54
+ if found > -1
55
+ sum += Math.abs(found - index)
56
+
57
+ sum
58
+
59
+ exist_score: (entities, goal_entities) ->
60
+ count = 0
61
+
62
+ for goal_entity in goal_entities
63
+ count += 1 unless (entity for entity in entities when entity[0] == goal_entity[0]).length > 0
64
+
65
+ count
66
+
67
+ count_score: (entities, goal_entities) ->
68
+ sum = 0
69
+
70
+ for goal_entity in goal_entities
71
+ found_entity = (entity for entity in entities when entity[0] == goal_entity[0])[0]
72
+
73
+ if found_entity?
74
+ sum += Math.abs(found_entity.length - goal_entity.length)
75
+
76
+ sum
77
+
78
+ rank: (goal_pattern) ->
79
+ separated_goal_pattern = this.separate(goal_pattern)
80
+ result = {}
81
+
82
+ for separated_pattern in this.all_separated_patterns()
83
+ result[separated_pattern.join("")] = this.score(separated_pattern, separated_goal_pattern)
84
+
85
+ result
@@ -1,240 +1,262 @@
1
1
  # Copyright 2012 Twitter, Inc
2
2
  # http://www.apache.org/licenses/LICENSE-2.0
3
3
 
4
- TwitterCldr.DateTimeFormatter = class DateTimeFormatter
5
- constructor: ->
6
- @tokens = `{{{tokens}}}`
7
- @calendar = `{{{calendar}}}`
8
- @weekday_keys = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]
9
- @methods = # ignoring u, l, g, j, A
10
- 'G': 'era'
11
- 'y': 'year'
12
- 'Y': 'year_of_week_of_year'
13
- 'Q': 'quarter'
14
- 'q': 'quarter_stand_alone'
15
- 'M': 'month'
16
- 'L': 'month_stand_alone'
17
- 'w': 'week_of_year'
18
- 'W': 'week_of_month'
19
- 'd': 'day'
20
- 'D': 'day_of_month'
21
- 'F': 'day_of_week_in_month'
22
- 'E': 'weekday'
23
- 'e': 'weekday_local'
24
- 'c': 'weekday_local_stand_alone'
25
- 'a': 'period'
26
- 'h': 'hour'
27
- 'H': 'hour'
28
- 'K': 'hour'
29
- 'k': 'hour'
30
- 'm': 'minute'
31
- 's': 'second'
32
- 'S': 'second_fraction'
33
- 'z': 'timezone'
34
- 'Z': 'timezone'
35
- 'v': 'timezone_generic_non_location'
36
- 'V': 'timezone_metazone'
37
-
38
- format: (obj, options) ->
39
- format_token = (token) =>
40
- result = ""
41
-
42
- switch token.type
43
- when "pattern"
44
- return this.result_for_token(token, obj)
45
- else
46
- if token.value.length > 0 && token.value[0] == "'" && token.value[token.value.length - 1] == "'"
47
- return token.value.substring(1, token.value.length - 1)
48
- else
49
- return token.value
50
-
51
- tokens = this.get_tokens(obj, options)
52
- return (format_token(token) for token in tokens).join("")
53
-
54
- get_tokens: (obj, options) ->
55
- return @tokens[options.format || "date_time"][options.type || "default"]
56
-
57
- result_for_token: (token, date) ->
58
- return this[@methods[token.value[0]]](date, token.value, token.value.length)
59
-
60
- era: (date, pattern, length) ->
61
- switch length
4
+ class TwitterCldr.DateTimeFormatter
5
+ constructor: ->
6
+ @tokens = `{{{tokens}}}`
7
+ @weekday_keys = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]
8
+ @methods = # ignoring u, l, g, j, A
9
+ 'G': 'era'
10
+ 'y': 'year'
11
+ 'Y': 'year_of_week_of_year'
12
+ 'Q': 'quarter'
13
+ 'q': 'quarter_stand_alone'
14
+ 'M': 'month'
15
+ 'L': 'month_stand_alone'
16
+ 'w': 'week_of_year'
17
+ 'W': 'week_of_month'
18
+ 'd': 'day'
19
+ 'D': 'day_of_month'
20
+ 'F': 'day_of_week_in_month'
21
+ 'E': 'weekday'
22
+ 'e': 'weekday_local'
23
+ 'c': 'weekday_local_stand_alone'
24
+ 'a': 'period'
25
+ 'h': 'hour'
26
+ 'H': 'hour'
27
+ 'K': 'hour'
28
+ 'k': 'hour'
29
+ 'm': 'minute'
30
+ 's': 'second'
31
+ 'S': 'second_fraction'
32
+ 'z': 'timezone'
33
+ 'Z': 'timezone'
34
+ 'v': 'timezone_generic_non_location'
35
+ 'V': 'timezone_metazone'
36
+
37
+ format: (obj, options) ->
38
+ format_token = (token) =>
39
+ result = ""
40
+
41
+ switch token.type
42
+ when "pattern"
43
+ this.result_for_token(token, obj)
44
+ else
45
+ if token.value.length > 0 && token.value[0] == "'" && token.value[token.value.length - 1] == "'"
46
+ token.value.substring(1, token.value.length - 1)
47
+ else
48
+ token.value
49
+
50
+ tokens = this.get_tokens(obj, options)
51
+ (format_token(token) for token in tokens).join("")
52
+
53
+ get_tokens: (obj, options) ->
54
+ format = options.format || "date_time"
55
+ type = options.type || "default"
56
+
57
+ if format == "additional"
58
+ @tokens["date_time"][format][this.additional_format_selector().find_closest(options.type)]
59
+ else
60
+ @tokens[format][type]
61
+
62
+ result_for_token: (token, date) ->
63
+ this[@methods[token.value[0]]](date, token.value, token.value.length)
64
+
65
+ additional_format_selector: ->
66
+ new TwitterCldr.AdditionalDateFormatSelector(@tokens["date_time"]["additional"])
67
+
68
+ @additional_formats: ->
69
+ new TwitterCldr.DateTimeFormatter().additional_format_selector().patterns()
70
+
71
+ era: (date, pattern, length) ->
72
+ switch length
73
+ when 0
74
+ choices = ["", ""]
62
75
  when 1, 2, 3
63
- choices = @calendar["eras"]["abbr"]
76
+ choices = TwitterCldr.Calendar.calendar["eras"]["abbr"]
64
77
  else
65
- choices = @calendar["eras"]["name"]
78
+ choices = TwitterCldr.Calendar.calendar["eras"]["name"]
66
79
 
67
80
  index = if (date.getFullYear() < 0) then 0 else 1
68
- return choices[index]
69
-
70
- year: (date, pattern, length) ->
71
- year = date.getFullYear().toString()
72
-
73
- if length == 2
74
- if year.length != 1
75
- year = year.slice(-2)
76
-
77
- if length > 1
78
- year = ("0000" + year).slice(-length)
79
-
80
- return year
81
-
82
- year_of_week_of_year: (date, pattern, length) ->
83
- throw 'not implemented'
84
-
85
- day_of_week_in_month: (date, pattern, length) -> # e.g. 2nd Wed in July
86
- throw 'not implemented'
87
-
88
- quarter: (date, pattern, length) ->
89
- # the bitwise OR is used here to truncate the decimal produced by the / 3
90
- quarter = ((date.getMonth() / 3) | 0) + 1
91
-
92
- switch length
93
- when 1
94
- return quarter.toString()
95
- when 2
96
- return ("0000" + quarter.toString()).slice(-length)
97
- when 3
98
- return @calendar.quarters.format.abbreviated[quarter]
99
- when 4
100
- return @calendar.quarters.format.wide[quarter]
101
-
102
- quarter_stand_alone: (date, pattern, length) ->
103
- quarter = (date.getMonth() - 1) / 3 + 1
104
-
105
- switch length
106
- when 1
107
- return quarter.toString()
108
- when 2
109
- return ("0000" + quarter.toString()).slice(-length)
110
- when 3
111
- throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
112
- when 4
113
- throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
114
- when 5
115
- return @calendar.quarters['stand-alone'].narrow[quarter]
116
-
117
- month: (date, pattern, length) ->
118
- month_str = (date.getMonth() + 1).toString()
119
-
120
- switch length
121
- when 1
122
- return month_str
123
- when 2
124
- return ("0000" + month_str).slice(-length)
125
- when 3
126
- return @calendar.months.format.abbreviated[month_str]
127
- when 4
128
- return @calendar.months.format.wide[month_str]
129
- when 5
130
- throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
131
- else
132
- throw "Unknown date format"
133
-
134
- month_stand_alone: (date, pattern, length) ->
135
- switch length
136
- when 1
137
- return date.getMonth().toString()
138
- when 2
139
- return ("0000" + date.getMonth().toString()).slice(-length)
140
- when 3
141
- throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
142
- when 4
143
- throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
144
- when 5
145
- return @calendar.months['stand-alone'].narrow[date.month]
146
- else
147
- throw "Unknown date format"
148
-
149
- day: (date, pattern, length) ->
150
- switch length
151
- when 1
152
- return date.getDate().toString()
153
- when 2
154
- return ("0000" + date.getDate().toString()).slice(-length)
155
-
156
- weekday: (date, pattern, length) ->
157
- key = @weekday_keys[date.getDay()]
158
-
159
- switch length
160
- when 1, 2, 3
161
- return @calendar.days.format.abbreviated[key]
162
- when 4
163
- return @calendar.days.format.wide[key]
164
- when 5
165
- return @calendar.days['stand-alone'].narrow[key]
166
-
167
- weekday_local: (date, pattern, length) ->
168
- # "Like E except adds a numeric value depending on the local starting day of the week"
81
+ result = choices[index]
82
+
83
+ if result? then result else this.era(date, pattern[0..-2], length - 1)
84
+
85
+ year: (date, pattern, length) ->
86
+ year = date.getFullYear().toString()
87
+
88
+ if length == 2
89
+ if year.length != 1
90
+ year = year.slice(-2)
91
+
92
+ if length > 1
93
+ year = ("0000" + year).slice(-length)
94
+
95
+ year
96
+
97
+ year_of_week_of_year: (date, pattern, length) ->
98
+ throw 'not implemented'
99
+
100
+ day_of_week_in_month: (date, pattern, length) -> # e.g. 2nd Wed in July
101
+ throw 'not implemented'
102
+
103
+ quarter: (date, pattern, length) ->
104
+ # the bitwise OR is used here to truncate the decimal produced by the / 3
105
+ quarter = ((date.getMonth() / 3) | 0) + 1
106
+
107
+ switch length
108
+ when 1
109
+ quarter.toString()
110
+ when 2
111
+ ("0000" + quarter.toString()).slice(-length)
112
+ when 3
113
+ TwitterCldr.Calendar.calendar.quarters.format.abbreviated[quarter]
114
+ when 4
115
+ TwitterCldr.Calendar.calendar.quarters.format.wide[quarter]
116
+
117
+ quarter_stand_alone: (date, pattern, length) ->
118
+ quarter = (date.getMonth() - 1) / 3 + 1
119
+
120
+ switch length
121
+ when 1
122
+ quarter.toString()
123
+ when 2
124
+ ("0000" + quarter.toString()).slice(-length)
125
+ when 3
126
+ throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
127
+ when 4
128
+ throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
129
+ when 5
130
+ TwitterCldr.Calendar.calendar.quarters['stand-alone'].narrow[quarter]
131
+
132
+ month: (date, pattern, length) ->
133
+ month_str = (date.getMonth() + 1).toString()
134
+
135
+ switch length
136
+ when 1
137
+ month_str
138
+ when 2
139
+ ("0000" + month_str).slice(-length)
140
+ when 3
141
+ TwitterCldr.Calendar.calendar.months.format.abbreviated[month_str]
142
+ when 4
143
+ TwitterCldr.Calendar.calendar.months.format.wide[month_str]
144
+ when 5
145
+ throw 'not yet implemented (requires cldr\'s "multiple inheritance")'
146
+ else
147
+ throw "Unknown date format"
148
+
149
+ month_stand_alone: (date, pattern, length) ->
150
+ month_str = (date.getMonth() + 1).toString()
151
+
152
+ switch length
153
+ when 1
154
+ month_str
155
+ when 2
156
+ ("0000" + month_str).slice(-length)
157
+ when 3
158
+ TwitterCldr.Calendar.calendar.months['stand-alone'].abbreviated[month_str]
159
+ when 4
160
+ TwitterCldr.Calendar.calendar.months['stand-alone'].wide[month_str]
161
+ when 5
162
+ TwitterCldr.Calendar.calendar.months['stand-alone'].narrow[month_str]
163
+ else
164
+ throw "Unknown date format"
165
+
166
+ day: (date, pattern, length) ->
167
+ switch length
168
+ when 1
169
+ date.getDate().toString()
170
+ when 2
171
+ ("0000" + date.getDate().toString()).slice(-length)
172
+
173
+ weekday: (date, pattern, length) ->
174
+ key = @weekday_keys[date.getDay()]
175
+
176
+ switch length
177
+ when 1, 2, 3
178
+ TwitterCldr.Calendar.calendar.days.format.abbreviated[key]
179
+ when 4
180
+ TwitterCldr.Calendar.calendar.days.format.wide[key]
181
+ when 5
182
+ TwitterCldr.Calendar.calendar.days['stand-alone'].narrow[key]
183
+
184
+ weekday_local: (date, pattern, length) ->
185
+ # "Like E except adds a numeric value depending on the local starting day of the week"
169
186
  # CLDR does not contain data as to which day is the first day of the week, so we will assume Monday (Ruby default)
170
- switch length
187
+ switch length
171
188
  when 1, 2
172
189
  day = date.getDay()
173
- return (if day == 0 then "7" else day.toString())
190
+ if day == 0 then "7" else day.toString()
174
191
  else
175
- return this.weekday(date, pattern, length)
192
+ this.weekday(date, pattern, length)
176
193
 
177
- weekday_local_stand_alone: (date, pattern, length) ->
178
- switch length
194
+ weekday_local_stand_alone: (date, pattern, length) ->
195
+ switch length
179
196
  when 1
180
- return this.weekday_local(date, pattern, length)
197
+ this.weekday_local(date, pattern, length)
181
198
  else
182
- return this.weekday(date, pattern, length)
183
-
184
- period: (time, pattern, length) ->
185
- if time.getHours() > 11
186
- return @calendar.periods.format.wide["pm"]
187
- else
188
- return @calendar.periods.format.wide["am"]
189
-
190
- hour: (time, pattern, length) ->
191
- hour = time.getHours()
192
-
193
- switch pattern[0]
194
- when 'h'
195
- if hour > 12
196
- hour = hour - 12
197
- else if hour == 0
198
- hour = 12
199
- when 'K'
200
- if hour > 11
201
- hour = hour - 12
202
- when 'k'
203
- if hour == 0
204
- hour = 24
205
-
206
- if length == 1
207
- return hour.toString()
208
- else
209
- return ("000000" + hour.toString()).slice(-length)
210
-
211
- minute: (time, pattern, length) ->
212
- if length == 1
213
- return time.getMinutes().toString()
214
- else
215
- return ("000000" + time.getMinutes().toString()).slice(-length)
216
-
217
- second: (time, pattern, length) ->
218
- if length == 1
219
- return time.getSeconds().toString()
220
- else
221
- return ("000000" + time.getSeconds().toString()).slice(-length)
222
-
223
- second_fraction: (time, pattern, length) ->
224
- if length > 6
225
- throw 'can not use the S format with more than 6 digits'
226
-
227
- return ("000000" + Math.round(Math.pow(time.getMilliseconds() * 100.0, 6 - length)).toString()).slice(-length)
228
-
229
- timezone: (time, pattern, length) ->
230
- hours = ("00" + (time.getTimezoneOffset() / 60).toString()).slice(-2)
231
- minutes = ("00" + (time.getTimezoneOffset() % 60).toString()).slice(-2)
232
-
233
- switch length
234
- when 1, 2, 3
235
- return "-" + hours + ":" + minutes
236
- else
237
- return "UTC -" + hours + ":" + minutes
238
-
239
- timezone_generic_non_location: (time, pattern, length) ->
240
- throw 'not yet implemented (requires timezone translation data")'
199
+ this.weekday(date, pattern, length)
200
+
201
+ period: (time, pattern, length) ->
202
+ if time.getHours() > 11
203
+ TwitterCldr.Calendar.calendar.periods.format.wide["pm"]
204
+ else
205
+ TwitterCldr.Calendar.calendar.periods.format.wide["am"]
206
+
207
+ hour: (time, pattern, length) ->
208
+ hour = time.getHours()
209
+
210
+ switch pattern[0]
211
+ when 'h'
212
+ if hour > 12
213
+ hour = hour - 12
214
+ else if hour == 0
215
+ hour = 12
216
+ when 'K'
217
+ if hour > 11
218
+ hour = hour - 12
219
+ when 'k'
220
+ if hour == 0
221
+ hour = 24
222
+
223
+ if length == 1
224
+ hour.toString()
225
+ else
226
+ ("000000" + hour.toString()).slice(-length)
227
+
228
+ minute: (time, pattern, length) ->
229
+ if length == 1
230
+ time.getMinutes().toString()
231
+ else
232
+ ("000000" + time.getMinutes().toString()).slice(-length)
233
+
234
+ second: (time, pattern, length) ->
235
+ if length == 1
236
+ time.getSeconds().toString()
237
+ else
238
+ ("000000" + time.getSeconds().toString()).slice(-length)
239
+
240
+ second_fraction: (time, pattern, length) ->
241
+ if length > 6
242
+ throw 'can not use the S format with more than 6 digits'
243
+
244
+ ("000000" + Math.round(Math.pow(time.getMilliseconds() * 100.0, 6 - length)).toString()).slice(-length)
245
+
246
+ timezone: (time, pattern, length) ->
247
+ offset = time.getTimezoneOffset()
248
+
249
+ hours = ("00" + (Math.abs(offset) / 60).toString()).slice(-2)
250
+ minutes = ("00" + (Math.abs(offset) % 60).toString()).slice(-2)
251
+ sign = if offset > 0 then "-" else "+" # timezone sign is opposite to offset sign
252
+
253
+ offsetString = sign + hours + ":" + minutes
254
+
255
+ switch length
256
+ when 1, 2, 3
257
+ offsetString
258
+ else
259
+ "UTC" + offsetString
260
+
261
+ timezone_generic_non_location: (time, pattern, length) ->
262
+ throw 'not yet implemented (requires timezone translation data")'