activesupport 3.0.0.beta4 → 3.0.pre

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.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (333) hide show
  1. data/CHANGELOG +1 -100
  2. data/lib/active_support.rb +4 -38
  3. data/lib/active_support/autoload.rb +28 -0
  4. data/lib/active_support/backtrace_cleaner.rb +9 -31
  5. data/lib/active_support/benchmarkable.rb +0 -1
  6. data/lib/active_support/buffered_logger.rb +1 -0
  7. data/lib/active_support/cache.rb +81 -436
  8. data/lib/active_support/cache/compressed_mem_cache_store.rb +13 -6
  9. data/lib/active_support/cache/file_store.rb +41 -139
  10. data/lib/active_support/cache/mem_cache_store.rb +75 -120
  11. data/lib/active_support/cache/memory_store.rb +27 -127
  12. data/lib/active_support/cache/strategy/local_cache.rb +58 -111
  13. data/lib/active_support/cache/synchronized_memory_store.rb +38 -2
  14. data/lib/active_support/callbacks.rb +48 -87
  15. data/lib/active_support/configurable.rb +18 -19
  16. data/lib/active_support/core_ext/array.rb +0 -1
  17. data/lib/active_support/core_ext/array/access.rb +1 -1
  18. data/lib/active_support/core_ext/array/conversions.rb +54 -29
  19. data/lib/active_support/core_ext/array/extract_options.rb +1 -16
  20. data/lib/active_support/core_ext/array/random_access.rb +5 -19
  21. data/lib/active_support/core_ext/array/wrap.rb +9 -13
  22. data/lib/active_support/core_ext/benchmark.rb +12 -0
  23. data/lib/active_support/core_ext/boolean.rb +1 -0
  24. data/lib/active_support/core_ext/boolean/conversions.rb +11 -0
  25. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -2
  26. data/lib/active_support/core_ext/class.rb +1 -1
  27. data/lib/active_support/core_ext/class/attribute_accessors.rb +27 -33
  28. data/lib/active_support/core_ext/class/delegating_attributes.rb +41 -35
  29. data/lib/active_support/core_ext/class/inheritable_attributes.rb +13 -22
  30. data/lib/active_support/core_ext/class/removal.rb +53 -0
  31. data/lib/active_support/core_ext/date.rb +7 -0
  32. data/lib/active_support/core_ext/date/calculations.rb +8 -30
  33. data/lib/active_support/core_ext/date/conversions.rb +2 -2
  34. data/lib/active_support/core_ext/date_time.rb +5 -0
  35. data/lib/active_support/core_ext/date_time/calculations.rb +1 -2
  36. data/lib/active_support/core_ext/date_time/conversions.rb +5 -23
  37. data/lib/active_support/core_ext/enumerable.rb +9 -5
  38. data/lib/active_support/core_ext/exception.rb +47 -0
  39. data/lib/active_support/core_ext/file.rb +0 -1
  40. data/lib/active_support/core_ext/file/atomic.rb +2 -3
  41. data/lib/active_support/core_ext/float/rounding.rb +2 -3
  42. data/lib/active_support/core_ext/hash/conversions.rb +145 -65
  43. data/lib/active_support/core_ext/hash/deep_merge.rb +7 -6
  44. data/lib/active_support/core_ext/hash/except.rb +0 -8
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +0 -5
  46. data/lib/active_support/core_ext/hash/keys.rb +11 -10
  47. data/lib/active_support/core_ext/hash/slice.rb +0 -6
  48. data/lib/active_support/core_ext/integer.rb +1 -1
  49. data/lib/active_support/core_ext/integer/even_odd.rb +16 -0
  50. data/lib/active_support/core_ext/kernel.rb +1 -1
  51. data/lib/active_support/core_ext/kernel/daemonizing.rb +7 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +2 -3
  53. data/lib/active_support/core_ext/kernel/reporting.rb +1 -2
  54. data/lib/active_support/core_ext/load_error.rb +30 -17
  55. data/lib/active_support/core_ext/logger.rb +1 -1
  56. data/lib/active_support/core_ext/module.rb +3 -5
  57. data/lib/active_support/core_ext/module/aliasing.rb +1 -1
  58. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -25
  61. data/lib/active_support/core_ext/module/delegation.rb +10 -21
  62. data/lib/active_support/core_ext/module/inclusion.rb +30 -0
  63. data/lib/active_support/core_ext/module/introspection.rb +8 -8
  64. data/lib/active_support/core_ext/module/loading.rb +23 -0
  65. data/lib/active_support/core_ext/module/synchronization.rb +1 -2
  66. data/lib/active_support/core_ext/name_error.rb +1 -3
  67. data/lib/active_support/core_ext/nil.rb +1 -0
  68. data/lib/active_support/core_ext/nil/conversions.rb +5 -0
  69. data/lib/active_support/core_ext/object.rb +2 -6
  70. data/lib/active_support/core_ext/object/blank.rb +2 -20
  71. data/lib/active_support/core_ext/object/conversions.rb +16 -2
  72. data/lib/active_support/core_ext/object/duplicable.rb +1 -23
  73. data/lib/active_support/core_ext/object/extending.rb +77 -8
  74. data/lib/active_support/core_ext/object/instance_variables.rb +7 -0
  75. data/lib/active_support/core_ext/object/metaclass.rb +13 -0
  76. data/lib/active_support/core_ext/object/misc.rb +1 -0
  77. data/lib/active_support/core_ext/object/tap.rb +16 -0
  78. data/lib/active_support/core_ext/object/with_options.rb +0 -2
  79. data/lib/active_support/core_ext/proc.rb +4 -4
  80. data/lib/active_support/core_ext/regexp.rb +22 -0
  81. data/lib/active_support/core_ext/rexml.rb +1 -4
  82. data/lib/active_support/core_ext/string.rb +2 -3
  83. data/lib/active_support/core_ext/string/access.rb +2 -4
  84. data/lib/active_support/core_ext/string/bytesize.rb +5 -0
  85. data/lib/active_support/core_ext/string/conversions.rb +1 -36
  86. data/lib/active_support/core_ext/string/filters.rb +0 -29
  87. data/lib/active_support/core_ext/string/inflections.rb +12 -1
  88. data/lib/active_support/core_ext/string/interpolation.rb +92 -2
  89. data/lib/active_support/core_ext/string/iterators.rb +13 -0
  90. data/lib/active_support/core_ext/string/multibyte.rb +19 -16
  91. data/lib/active_support/core_ext/string/output_safety.rb +35 -101
  92. data/lib/active_support/core_ext/string/starts_ends_with.rb +14 -0
  93. data/lib/active_support/core_ext/string/xchar.rb +1 -1
  94. data/lib/active_support/core_ext/symbol.rb +1 -0
  95. data/lib/active_support/core_ext/symbol/to_proc.rb +14 -0
  96. data/lib/active_support/core_ext/time.rb +10 -0
  97. data/lib/active_support/core_ext/time/calculations.rb +7 -9
  98. data/lib/active_support/core_ext/time/conversions.rb +0 -1
  99. data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +22 -0
  100. data/lib/active_support/core_ext/uri.rb +4 -10
  101. data/lib/active_support/dependencies.rb +192 -179
  102. data/lib/active_support/deprecated_callbacks.rb +283 -0
  103. data/lib/active_support/deprecation/behaviors.rb +1 -1
  104. data/lib/active_support/deprecation/method_wrappers.rb +9 -10
  105. data/lib/active_support/deprecation/reporting.rb +1 -2
  106. data/lib/active_support/duration.rb +2 -6
  107. data/lib/active_support/hash_with_indifferent_access.rb +1 -9
  108. data/lib/active_support/inflections.rb +1 -1
  109. data/lib/active_support/inflector.rb +407 -4
  110. data/lib/active_support/json/backends/jsongem.rb +9 -12
  111. data/lib/active_support/json/decoding.rb +1 -16
  112. data/lib/active_support/json/encoding.rb +12 -42
  113. data/lib/active_support/locale/en.yml +1 -4
  114. data/lib/active_support/memoizable.rb +1 -1
  115. data/lib/active_support/message_encryptor.rb +0 -1
  116. data/lib/active_support/message_verifier.rb +5 -6
  117. data/lib/active_support/multibyte.rb +22 -7
  118. data/lib/active_support/multibyte/chars.rb +392 -164
  119. data/lib/active_support/multibyte/unicode_database.rb +71 -0
  120. data/lib/active_support/multibyte/utils.rb +7 -6
  121. data/lib/active_support/notifications.rb +113 -23
  122. data/lib/active_support/ordered_hash.rb +11 -35
  123. data/lib/active_support/ordered_options.rb +0 -6
  124. data/lib/active_support/rescuable.rb +4 -7
  125. data/lib/active_support/ruby/shim.rb +6 -4
  126. data/lib/active_support/test_case.rb +7 -2
  127. data/lib/active_support/testing/assertions.rb +0 -15
  128. data/lib/active_support/testing/declarative.rb +1 -1
  129. data/lib/active_support/testing/isolation.rb +19 -63
  130. data/lib/active_support/testing/performance.rb +337 -342
  131. data/lib/active_support/testing/setup_and_teardown.rb +29 -51
  132. data/lib/active_support/time.rb +3 -23
  133. data/lib/active_support/time_with_zone.rb +10 -5
  134. data/lib/active_support/values/time_zone.rb +84 -40
  135. data/lib/active_support/values/unicode_tables.dat +0 -0
  136. data/lib/active_support/vendor.rb +16 -0
  137. data/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb +113 -0
  138. data/lib/active_support/vendor/builder-2.1.2/lib/builder.rb +13 -0
  139. data/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb +20 -0
  140. data/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb +250 -0
  141. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb +115 -0
  142. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb +139 -0
  143. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb +63 -0
  144. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb +328 -0
  145. data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +20 -0
  146. data/lib/active_support/vendor/i18n-0.1.3/README.textile +20 -0
  147. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +5 -0
  148. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +27 -0
  149. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +204 -0
  150. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +215 -0
  151. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +53 -0
  152. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +5 -0
  153. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +99 -0
  154. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +124 -0
  155. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +1 -0
  156. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +3 -0
  157. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +567 -0
  158. data/lib/active_support/vendor/memcache-client-1.7.5/lib/memcache.rb +1133 -0
  159. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo.rb +33 -0
  160. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone.rb +47 -0
  161. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone_info.rb +228 -0
  162. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Algiers.rb +55 -0
  163. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Cairo.rb +219 -0
  164. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Casablanca.rb +42 -0
  165. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Harare.rb +18 -0
  166. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Johannesburg.rb +25 -0
  167. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Monrovia.rb +22 -0
  168. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Nairobi.rb +23 -0
  169. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +166 -0
  170. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/San_Juan.rb +86 -0
  171. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Bogota.rb +23 -0
  172. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Caracas.rb +23 -0
  173. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chicago.rb +283 -0
  174. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chihuahua.rb +136 -0
  175. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Denver.rb +204 -0
  176. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Godthab.rb +161 -0
  177. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Guatemala.rb +27 -0
  178. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Halifax.rb +274 -0
  179. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb +149 -0
  180. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Juneau.rb +194 -0
  181. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/La_Paz.rb +22 -0
  182. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Lima.rb +35 -0
  183. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Los_Angeles.rb +232 -0
  184. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mazatlan.rb +139 -0
  185. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mexico_City.rb +144 -0
  186. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Monterrey.rb +131 -0
  187. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/New_York.rb +282 -0
  188. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Phoenix.rb +30 -0
  189. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Regina.rb +74 -0
  190. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Santiago.rb +205 -0
  191. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Sao_Paulo.rb +171 -0
  192. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/St_Johns.rb +288 -0
  193. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Tijuana.rb +196 -0
  194. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Almaty.rb +67 -0
  195. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baghdad.rb +73 -0
  196. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baku.rb +161 -0
  197. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Bangkok.rb +20 -0
  198. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Chongqing.rb +33 -0
  199. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Colombo.rb +30 -0
  200. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Dhaka.rb +27 -0
  201. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Hong_Kong.rb +87 -0
  202. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Irkutsk.rb +165 -0
  203. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jakarta.rb +30 -0
  204. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jerusalem.rb +163 -0
  205. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kabul.rb +20 -0
  206. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kamchatka.rb +163 -0
  207. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Karachi.rb +32 -0
  208. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kathmandu.rb +20 -0
  209. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kolkata.rb +25 -0
  210. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb +163 -0
  211. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb +31 -0
  212. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuwait.rb +18 -0
  213. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Magadan.rb +163 -0
  214. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Muscat.rb +18 -0
  215. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Novosibirsk.rb +164 -0
  216. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Rangoon.rb +24 -0
  217. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Riyadh.rb +18 -0
  218. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Seoul.rb +34 -0
  219. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Shanghai.rb +35 -0
  220. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Singapore.rb +33 -0
  221. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Taipei.rb +59 -0
  222. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tashkent.rb +47 -0
  223. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tbilisi.rb +78 -0
  224. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tehran.rb +121 -0
  225. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tokyo.rb +30 -0
  226. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb +65 -0
  227. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Urumqi.rb +33 -0
  228. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Vladivostok.rb +164 -0
  229. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yakutsk.rb +163 -0
  230. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yekaterinburg.rb +165 -0
  231. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yerevan.rb +165 -0
  232. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Azores.rb +270 -0
  233. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb +23 -0
  234. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/South_Georgia.rb +18 -0
  235. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Adelaide.rb +187 -0
  236. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Brisbane.rb +35 -0
  237. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Darwin.rb +29 -0
  238. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Hobart.rb +193 -0
  239. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Melbourne.rb +185 -0
  240. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Perth.rb +37 -0
  241. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Sydney.rb +185 -0
  242. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Etc/UTC.rb +16 -0
  243. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Amsterdam.rb +228 -0
  244. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Athens.rb +185 -0
  245. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Belgrade.rb +163 -0
  246. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Berlin.rb +188 -0
  247. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bratislava.rb +13 -0
  248. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Brussels.rb +232 -0
  249. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bucharest.rb +181 -0
  250. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Budapest.rb +197 -0
  251. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Copenhagen.rb +179 -0
  252. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Dublin.rb +276 -0
  253. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Helsinki.rb +163 -0
  254. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Istanbul.rb +218 -0
  255. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Kiev.rb +168 -0
  256. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Lisbon.rb +268 -0
  257. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Ljubljana.rb +13 -0
  258. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/London.rb +288 -0
  259. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Madrid.rb +211 -0
  260. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Minsk.rb +170 -0
  261. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Moscow.rb +181 -0
  262. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Paris.rb +232 -0
  263. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Prague.rb +187 -0
  264. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Riga.rb +176 -0
  265. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Rome.rb +215 -0
  266. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sarajevo.rb +13 -0
  267. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Skopje.rb +13 -0
  268. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sofia.rb +173 -0
  269. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Stockholm.rb +165 -0
  270. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Tallinn.rb +172 -0
  271. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vienna.rb +183 -0
  272. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vilnius.rb +170 -0
  273. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Warsaw.rb +212 -0
  274. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Zagreb.rb +13 -0
  275. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Auckland.rb +202 -0
  276. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Fiji.rb +23 -0
  277. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Guam.rb +22 -0
  278. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Honolulu.rb +28 -0
  279. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Majuro.rb +20 -0
  280. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Midway.rb +25 -0
  281. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Noumea.rb +25 -0
  282. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Pago_Pago.rb +26 -0
  283. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Port_Moresby.rb +20 -0
  284. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Tongatapu.rb +27 -0
  285. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/info_timezone.rb +52 -0
  286. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone.rb +51 -0
  287. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone_info.rb +44 -0
  288. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/offset_rationals.rb +98 -0
  289. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/ruby_core_support.rb +56 -0
  290. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/time_or_datetime.rb +292 -0
  291. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone.rb +508 -0
  292. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_definition.rb +56 -0
  293. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_info.rb +40 -0
  294. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_offset_info.rb +94 -0
  295. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_period.rb +198 -0
  296. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_transition_info.rb +129 -0
  297. data/lib/active_support/version.rb +2 -3
  298. data/lib/active_support/whiny_nil.rb +7 -9
  299. data/lib/active_support/xml_mini.rb +1 -126
  300. data/lib/active_support/xml_mini/jdom.rb +0 -2
  301. data/lib/active_support/xml_mini/libxml.rb +86 -24
  302. data/lib/active_support/xml_mini/nokogiri.rb +24 -27
  303. data/lib/active_support/xml_mini/rexml.rb +1 -7
  304. metadata +191 -49
  305. data/lib/active_support/builder.rb +0 -6
  306. data/lib/active_support/core_ext/array/uniq_by.rb +0 -17
  307. data/lib/active_support/core_ext/class/attribute.rb +0 -67
  308. data/lib/active_support/core_ext/class/subclasses.rb +0 -55
  309. data/lib/active_support/core_ext/file/path.rb +0 -5
  310. data/lib/active_support/core_ext/integer/multiple.rb +0 -6
  311. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -13
  312. data/lib/active_support/core_ext/module/anonymous.rb +0 -24
  313. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  314. data/lib/active_support/core_ext/module/reachable.rb +0 -10
  315. data/lib/active_support/core_ext/module/remove_method.rb +0 -6
  316. data/lib/active_support/core_ext/object/to_param.rb +0 -49
  317. data/lib/active_support/core_ext/object/to_query.rb +0 -27
  318. data/lib/active_support/core_ext/string/encoding.rb +0 -11
  319. data/lib/active_support/core_ext/string/exclude.rb +0 -6
  320. data/lib/active_support/core_ext/time/marshal.rb +0 -56
  321. data/lib/active_support/dependencies/autoload.rb +0 -50
  322. data/lib/active_support/i18n.rb +0 -8
  323. data/lib/active_support/inflector/inflections.rb +0 -211
  324. data/lib/active_support/inflector/methods.rb +0 -141
  325. data/lib/active_support/inflector/transliterate.rb +0 -97
  326. data/lib/active_support/json/backends/yajl.rb +0 -40
  327. data/lib/active_support/lazy_load_hooks.rb +0 -27
  328. data/lib/active_support/multibyte/unicode.rb +0 -393
  329. data/lib/active_support/notifications/fanout.rb +0 -93
  330. data/lib/active_support/notifications/instrumenter.rb +0 -56
  331. data/lib/active_support/railtie.rb +0 -100
  332. data/lib/active_support/xml_mini/libxmlsax.rb +0 -85
  333. data/lib/active_support/xml_mini/nokogirisax.rb +0 -83
@@ -1,141 +0,0 @@
1
- module ActiveSupport
2
- # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
3
- # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
4
- # in inflections.rb.
5
- #
6
- # The Rails core team has stated patches for the inflections library will not be accepted
7
- # in order to avoid breaking legacy applications which may be relying on errant inflections.
8
- # If you discover an incorrect inflection and require it for your application, you'll need
9
- # to correct it yourself (explained below).
10
- module Inflector
11
- extend self
12
-
13
- # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
14
- # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
15
- #
16
- # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
17
- #
18
- # Examples:
19
- # "active_record".camelize # => "ActiveRecord"
20
- # "active_record".camelize(:lower) # => "activeRecord"
21
- # "active_record/errors".camelize # => "ActiveRecord::Errors"
22
- # "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
23
- def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
24
- if first_letter_in_uppercase
25
- lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
26
- else
27
- lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
28
- end
29
- end
30
-
31
- # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
32
- #
33
- # Changes '::' to '/' to convert namespaces to paths.
34
- #
35
- # Examples:
36
- # "ActiveRecord".underscore # => "active_record"
37
- # "ActiveRecord::Errors".underscore # => active_record/errors
38
- def underscore(camel_cased_word)
39
- word = camel_cased_word.to_s.dup
40
- word.gsub!(/::/, '/')
41
- word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
42
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
43
- word.tr!("-", "_")
44
- word.downcase!
45
- word
46
- end
47
-
48
- # Replaces underscores with dashes in the string.
49
- #
50
- # Example:
51
- # "puni_puni" # => "puni-puni"
52
- def dasherize(underscored_word)
53
- underscored_word.gsub(/_/, '-')
54
- end
55
-
56
- # Removes the module part from the expression in the string.
57
- #
58
- # Examples:
59
- # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
60
- # "Inflections".demodulize # => "Inflections"
61
- def demodulize(class_name_in_module)
62
- class_name_in_module.to_s.gsub(/^.*::/, '')
63
- end
64
-
65
- # Creates a foreign key name from a class name.
66
- # +separate_class_name_and_id_with_underscore+ sets whether
67
- # the method should put '_' between the name and 'id'.
68
- #
69
- # Examples:
70
- # "Message".foreign_key # => "message_id"
71
- # "Message".foreign_key(false) # => "messageid"
72
- # "Admin::Post".foreign_key # => "post_id"
73
- def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
74
- underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
75
- end
76
-
77
- # Ruby 1.9 introduces an inherit argument for Module#const_get and
78
- # #const_defined? and changes their default behavior.
79
- if Module.method(:const_get).arity == 1
80
- # Tries to find a constant with the name specified in the argument string:
81
- #
82
- # "Module".constantize # => Module
83
- # "Test::Unit".constantize # => Test::Unit
84
- #
85
- # The name is assumed to be the one of a top-level constant, no matter whether
86
- # it starts with "::" or not. No lexical context is taken into account:
87
- #
88
- # C = 'outside'
89
- # module M
90
- # C = 'inside'
91
- # C # => 'inside'
92
- # "C".constantize # => 'outside', same as ::C
93
- # end
94
- #
95
- # NameError is raised when the name is not in CamelCase or the constant is
96
- # unknown.
97
- def constantize(camel_cased_word)
98
- names = camel_cased_word.split('::')
99
- names.shift if names.empty? || names.first.empty?
100
-
101
- constant = Object
102
- names.each do |name|
103
- constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
104
- end
105
- constant
106
- end
107
- else
108
- def constantize(camel_cased_word) #:nodoc:
109
- names = camel_cased_word.split('::')
110
- names.shift if names.empty? || names.first.empty?
111
-
112
- constant = Object
113
- names.each do |name|
114
- constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
115
- end
116
- constant
117
- end
118
- end
119
-
120
- # Turns a number into an ordinal string used to denote the position in an
121
- # ordered sequence such as 1st, 2nd, 3rd, 4th.
122
- #
123
- # Examples:
124
- # ordinalize(1) # => "1st"
125
- # ordinalize(2) # => "2nd"
126
- # ordinalize(1002) # => "1002nd"
127
- # ordinalize(1003) # => "1003rd"
128
- def ordinalize(number)
129
- if (11..13).include?(number.to_i % 100)
130
- "#{number}th"
131
- else
132
- case number.to_i % 10
133
- when 1; "#{number}st"
134
- when 2; "#{number}nd"
135
- when 3; "#{number}rd"
136
- else "#{number}th"
137
- end
138
- end
139
- end
140
- end
141
- end
@@ -1,97 +0,0 @@
1
- # encoding: utf-8
2
- require 'active_support/core_ext/string/multibyte'
3
-
4
- module ActiveSupport
5
- module Inflector
6
-
7
- # Replaces non-ASCII characters with an ASCII approximation, or if none
8
- # exists, a replacement character which defaults to "?".
9
- #
10
- # transliterate("Ærøskøbing")
11
- # # => "AEroskobing"
12
- #
13
- # Default approximations are provided for Western/Latin characters,
14
- # e.g, "ø", "ñ", "é", "ß", etc.
15
- #
16
- # This method is I18n aware, so you can set up custom approximations for a
17
- # locale. This can be useful, for example, to transliterate German's "ü"
18
- # and "ö" to "ue" and "oe", or to add support for transliterating Russian
19
- # to ASCII.
20
- #
21
- # In order to make your custom transliterations available, you must set
22
- # them as the <tt>i18n.transliterate.rule</tt> i18n key:
23
- #
24
- # # Store the transliterations in locales/de.yml
25
- # i18n:
26
- # transliterate:
27
- # rule:
28
- # ü: "ue"
29
- # ö: "oe"
30
- #
31
- # # Or set them using Ruby
32
- # I18n.backend.store_translations(:de, :i18n => {
33
- # :transliterate => {
34
- # :rule => {
35
- # "ü" => "ue",
36
- # "ö" => "oe"
37
- # }
38
- # }
39
- # })
40
- #
41
- # The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that maps
42
- # characters to ASCII approximations as shown above, or, for more complex
43
- # requirements, a Proc:
44
- #
45
- # I18n.backend.store_translations(:de, :i18n => {
46
- # :transliterate => {
47
- # :rule => lambda {|string| MyTransliterator.transliterate(string)}
48
- # }
49
- # })
50
- #
51
- # Now you can have different transliterations for each locale:
52
- #
53
- # I18n.locale = :en
54
- # transliterate("Jürgen")
55
- # # => "Jurgen"
56
- #
57
- # I18n.locale = :de
58
- # transliterate("Jürgen")
59
- # # => "Juergen"
60
- def transliterate(string, replacement = "?")
61
- I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
62
- ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
63
- :replacement => replacement)
64
- end
65
-
66
- # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
67
- #
68
- # ==== Examples
69
- #
70
- # class Person
71
- # def to_param
72
- # "#{id}-#{name.parameterize}"
73
- # end
74
- # end
75
- #
76
- # @person = Person.find(1)
77
- # # => #<Person id: 1, name: "Donald E. Knuth">
78
- #
79
- # <%= link_to(@person.name, person_path(@person)) %>
80
- # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
81
- def parameterize(string, sep = '-')
82
- # replace accented chars with their ascii equivalents
83
- parameterized_string = transliterate(string)
84
- # Turn unwanted chars into the separator
85
- parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
86
- unless sep.nil? || sep.empty?
87
- re_sep = Regexp.escape(sep)
88
- # No more than one of the separator in a row.
89
- parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
90
- # Remove leading/trailing separator.
91
- parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
92
- end
93
- parameterized_string.downcase
94
- end
95
-
96
- end
97
- end
@@ -1,40 +0,0 @@
1
- require 'yajl-ruby' unless defined?(Yajl)
2
-
3
- module ActiveSupport
4
- module JSON
5
- module Backends
6
- module Yajl
7
- ParseError = ::Yajl::ParseError
8
- extend self
9
-
10
- # Parses a JSON string or IO and convert it into an object
11
- def decode(json)
12
- data = ::Yajl::Parser.new.parse(json)
13
- if ActiveSupport.parse_json_times
14
- convert_dates_from(data)
15
- else
16
- data
17
- end
18
- end
19
-
20
- private
21
- def convert_dates_from(data)
22
- case data
23
- when nil
24
- nil
25
- when DATE_REGEX
26
- DateTime.parse(data)
27
- when Array
28
- data.map! { |d| convert_dates_from(d) }
29
- when Hash
30
- data.each do |key, value|
31
- data[key] = convert_dates_from(value)
32
- end
33
- else
34
- data
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,27 +0,0 @@
1
- module ActiveSupport
2
- @load_hooks = Hash.new {|h,k| h[k] = [] }
3
- @loaded = {}
4
-
5
- def self.on_load(name, options = {}, &block)
6
- if base = @loaded[name]
7
- execute_hook(base, options, block)
8
- else
9
- @load_hooks[name] << [block, options]
10
- end
11
- end
12
-
13
- def self.execute_hook(base, options, block)
14
- if options[:yield]
15
- block.call(base)
16
- else
17
- base.instance_eval(&block)
18
- end
19
- end
20
-
21
- def self.run_load_hooks(name, base = Object)
22
- @loaded[name] = base
23
- @load_hooks[name].each do |hook, options|
24
- execute_hook(base, options, hook)
25
- end
26
- end
27
- end
@@ -1,393 +0,0 @@
1
- module ActiveSupport
2
- module Multibyte
3
- module Unicode
4
-
5
- extend self
6
-
7
- # A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more
8
- # information about normalization.
9
- NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
10
-
11
- # The Unicode version that is supported by the implementation
12
- UNICODE_VERSION = '5.1.0'
13
-
14
- # The default normalization used for operations that require normalization. It can be set to any of the
15
- # normalizations in NORMALIZATION_FORMS.
16
- #
17
- # Example:
18
- # ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
19
- attr_accessor :default_normalization_form
20
- @default_normalization_form = :kc
21
-
22
- # Hangul character boundaries and properties
23
- HANGUL_SBASE = 0xAC00
24
- HANGUL_LBASE = 0x1100
25
- HANGUL_VBASE = 0x1161
26
- HANGUL_TBASE = 0x11A7
27
- HANGUL_LCOUNT = 19
28
- HANGUL_VCOUNT = 21
29
- HANGUL_TCOUNT = 28
30
- HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
31
- HANGUL_SCOUNT = 11172
32
- HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
33
- HANGUL_JAMO_FIRST = 0x1100
34
- HANGUL_JAMO_LAST = 0x11FF
35
-
36
- # All the unicode whitespace
37
- WHITESPACE = [
38
- (0x0009..0x000D).to_a, # White_Space # Cc [5] <control-0009>..<control-000D>
39
- 0x0020, # White_Space # Zs SPACE
40
- 0x0085, # White_Space # Cc <control-0085>
41
- 0x00A0, # White_Space # Zs NO-BREAK SPACE
42
- 0x1680, # White_Space # Zs OGHAM SPACE MARK
43
- 0x180E, # White_Space # Zs MONGOLIAN VOWEL SEPARATOR
44
- (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE
45
- 0x2028, # White_Space # Zl LINE SEPARATOR
46
- 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR
47
- 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE
48
- 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE
49
- 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
50
- ].flatten.freeze
51
-
52
- # BOM (byte order mark) can also be seen as whitespace, it's a non-rendering character used to distinguish
53
- # between little and big endian. This is not an issue in utf-8, so it must be ignored.
54
- LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
55
-
56
- # Returns a regular expression pattern that matches the passed Unicode codepoints
57
- def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
58
- array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
59
- end
60
- TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
61
- LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
62
-
63
- # Unpack the string at codepoints boundaries. Raises an EncodingError when the encoding of the string isn't
64
- # valid UTF-8.
65
- #
66
- # Example:
67
- # Unicode.u_unpack('Café') #=> [67, 97, 102, 233]
68
- def u_unpack(string)
69
- begin
70
- string.unpack 'U*'
71
- rescue ArgumentError
72
- raise EncodingError, 'malformed UTF-8 character'
73
- end
74
- end
75
-
76
- # Detect whether the codepoint is in a certain character class. Returns +true+ when it's in the specified
77
- # character class and +false+ otherwise. Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
78
- # <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
79
- #
80
- # Primarily used by the grapheme cluster support.
81
- def in_char_class?(codepoint, classes)
82
- classes.detect { |c| database.boundary[c] === codepoint } ? true : false
83
- end
84
-
85
- # Unpack the string at grapheme boundaries. Returns a list of character lists.
86
- #
87
- # Example:
88
- # Unicode.g_unpack('क्षि') #=> [[2325, 2381], [2359], [2367]]
89
- # Unicode.g_unpack('Café') #=> [[67], [97], [102], [233]]
90
- def g_unpack(string)
91
- codepoints = u_unpack(string)
92
- unpacked = []
93
- pos = 0
94
- marker = 0
95
- eoc = codepoints.length
96
- while(pos < eoc)
97
- pos += 1
98
- previous = codepoints[pos-1]
99
- current = codepoints[pos]
100
- if (
101
- # CR X LF
102
- one = ( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or
103
- # L X (L|V|LV|LVT)
104
- two = ( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
105
- # (LV|V) X (V|T)
106
- three = ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
107
- # (LVT|T) X (T)
108
- four = ( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or
109
- # X Extend
110
- five = (database.boundary[:extend] === current)
111
- )
112
- else
113
- unpacked << codepoints[marker..pos-1]
114
- marker = pos
115
- end
116
- end
117
- unpacked
118
- end
119
-
120
- # Reverse operation of g_unpack.
121
- #
122
- # Example:
123
- # Unicode.g_pack(Unicode.g_unpack('क्षि')) #=> 'क्षि'
124
- def g_pack(unpacked)
125
- (unpacked.flatten).pack('U*')
126
- end
127
-
128
- # Re-order codepoints so the string becomes canonical.
129
- def reorder_characters(codepoints)
130
- length = codepoints.length- 1
131
- pos = 0
132
- while pos < length do
133
- cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
134
- if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
135
- codepoints[pos..pos+1] = cp2.code, cp1.code
136
- pos += (pos > 0 ? -1 : 1)
137
- else
138
- pos += 1
139
- end
140
- end
141
- codepoints
142
- end
143
-
144
- # Decompose composed characters to the decomposed form.
145
- def decompose_codepoints(type, codepoints)
146
- codepoints.inject([]) do |decomposed, cp|
147
- # if it's a hangul syllable starter character
148
- if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
149
- sindex = cp - HANGUL_SBASE
150
- ncp = [] # new codepoints
151
- ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
152
- ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
153
- tindex = sindex % HANGUL_TCOUNT
154
- ncp << (HANGUL_TBASE + tindex) unless tindex == 0
155
- decomposed.concat ncp
156
- # if the codepoint is decomposable in with the current decomposition type
157
- elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatability)
158
- decomposed.concat decompose_codepoints(type, ncp.dup)
159
- else
160
- decomposed << cp
161
- end
162
- end
163
- end
164
-
165
- # Compose decomposed characters to the composed form.
166
- def compose_codepoints(codepoints)
167
- pos = 0
168
- eoa = codepoints.length - 1
169
- starter_pos = 0
170
- starter_char = codepoints[0]
171
- previous_combining_class = -1
172
- while pos < eoa
173
- pos += 1
174
- lindex = starter_char - HANGUL_LBASE
175
- # -- Hangul
176
- if 0 <= lindex and lindex < HANGUL_LCOUNT
177
- vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
178
- if 0 <= vindex and vindex < HANGUL_VCOUNT
179
- tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
180
- if 0 <= tindex and tindex < HANGUL_TCOUNT
181
- j = starter_pos + 2
182
- eoa -= 2
183
- else
184
- tindex = 0
185
- j = starter_pos + 1
186
- eoa -= 1
187
- end
188
- codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
189
- end
190
- starter_pos += 1
191
- starter_char = codepoints[starter_pos]
192
- # -- Other characters
193
- else
194
- current_char = codepoints[pos]
195
- current = database.codepoints[current_char]
196
- if current.combining_class > previous_combining_class
197
- if ref = database.composition_map[starter_char]
198
- composition = ref[current_char]
199
- else
200
- composition = nil
201
- end
202
- unless composition.nil?
203
- codepoints[starter_pos] = composition
204
- starter_char = composition
205
- codepoints.delete_at pos
206
- eoa -= 1
207
- pos -= 1
208
- previous_combining_class = -1
209
- else
210
- previous_combining_class = current.combining_class
211
- end
212
- else
213
- previous_combining_class = current.combining_class
214
- end
215
- if current.combining_class == 0
216
- starter_pos = pos
217
- starter_char = codepoints[pos]
218
- end
219
- end
220
- end
221
- codepoints
222
- end
223
-
224
- # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
225
- #
226
- # Passing +true+ will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.
227
- def tidy_bytes(string, force = false)
228
- if force
229
- return string.unpack("C*").map do |b|
230
- tidy_byte(b)
231
- end.flatten.compact.pack("C*").unpack("U*").pack("U*")
232
- end
233
-
234
- bytes = string.unpack("C*")
235
- conts_expected = 0
236
- last_lead = 0
237
-
238
- bytes.each_index do |i|
239
-
240
- byte = bytes[i]
241
- is_ascii = byte < 128
242
- is_cont = byte > 127 && byte < 192
243
- is_lead = byte > 191 && byte < 245
244
- is_unused = byte > 240
245
- is_restricted = byte > 244
246
-
247
- # Impossible or highly unlikely byte? Clean it.
248
- if is_unused || is_restricted
249
- bytes[i] = tidy_byte(byte)
250
- elsif is_cont
251
- # Not expecting contination byte? Clean up. Otherwise, now expect one less.
252
- conts_expected == 0 ? bytes[i] = tidy_byte(byte) : conts_expected -= 1
253
- else
254
- if conts_expected > 0
255
- # Expected continuation, but got ASCII or leading? Clean backwards up to
256
- # the leading byte.
257
- (1..(i - last_lead)).each {|j| bytes[i - j] = tidy_byte(bytes[i - j])}
258
- conts_expected = 0
259
- end
260
- if is_lead
261
- # Final byte is leading? Clean it.
262
- if i == bytes.length - 1
263
- bytes[i] = tidy_byte(bytes.last)
264
- else
265
- # Valid leading byte? Expect continuations determined by position of
266
- # first zero bit, with max of 3.
267
- conts_expected = byte < 224 ? 1 : byte < 240 ? 2 : 3
268
- last_lead = i
269
- end
270
- end
271
- end
272
- end
273
- bytes.empty? ? "" : bytes.flatten.compact.pack("C*").unpack("U*").pack("U*")
274
- end
275
-
276
- # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for
277
- # passing strings to databases and validations.
278
- #
279
- # * <tt>string</tt> - The string to perform normalization on.
280
- # * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
281
- # <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
282
- # ActiveSupport::Multibyte.default_normalization_form
283
- def normalize(string, form=nil)
284
- form ||= @default_normalization_form
285
- # See http://www.unicode.org/reports/tr15, Table 1
286
- codepoints = u_unpack(string)
287
- case form
288
- when :d
289
- reorder_characters(decompose_codepoints(:canonical, codepoints))
290
- when :c
291
- compose_codepoints(reorder_characters(decompose_codepoints(:canonical, codepoints)))
292
- when :kd
293
- reorder_characters(decompose_codepoints(:compatability, codepoints))
294
- when :kc
295
- compose_codepoints(reorder_characters(decompose_codepoints(:compatability, codepoints)))
296
- else
297
- raise ArgumentError, "#{form} is not a valid normalization variant", caller
298
- end.pack('U*')
299
- end
300
-
301
- def apply_mapping(string, mapping) #:nodoc:
302
- u_unpack(string).map do |codepoint|
303
- cp = database.codepoints[codepoint]
304
- if cp and (ncp = cp.send(mapping)) and ncp > 0
305
- ncp
306
- else
307
- codepoint
308
- end
309
- end.pack('U*')
310
- end
311
-
312
- # Holds data about a codepoint in the Unicode database
313
- class Codepoint
314
- attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
315
- end
316
-
317
- # Holds static data from the Unicode database
318
- class UnicodeDatabase
319
- ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
320
-
321
- attr_writer(*ATTRIBUTES)
322
-
323
- def initialize
324
- @codepoints = Hash.new(Codepoint.new)
325
- @composition_exclusion = []
326
- @composition_map = {}
327
- @boundary = {}
328
- @cp1252 = {}
329
- end
330
-
331
- # Lazy load the Unicode database so it's only loaded when it's actually used
332
- ATTRIBUTES.each do |attr_name|
333
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
334
- def #{attr_name} # def codepoints
335
- load # load
336
- @#{attr_name} # @codepoints
337
- end # end
338
- EOS
339
- end
340
-
341
- # Loads the Unicode database and returns all the internal objects of UnicodeDatabase.
342
- def load
343
- begin
344
- @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
345
- rescue Exception => e
346
- raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
347
- end
348
-
349
- # Redefine the === method so we can write shorter rules for grapheme cluster breaks
350
- @boundary.each do |k,_|
351
- @boundary[k].instance_eval do
352
- def ===(other)
353
- detect { |i| i === other } ? true : false
354
- end
355
- end if @boundary[k].kind_of?(Array)
356
- end
357
-
358
- # define attr_reader methods for the instance variables
359
- class << self
360
- attr_reader(*ATTRIBUTES)
361
- end
362
- end
363
-
364
- # Returns the directory in which the data files are stored
365
- def self.dirname
366
- File.dirname(__FILE__) + '/../values/'
367
- end
368
-
369
- # Returns the filename for the data file for this version
370
- def self.filename
371
- File.expand_path File.join(dirname, "unicode_tables.dat")
372
- end
373
- end
374
-
375
- private
376
-
377
- def tidy_byte(byte)
378
- if byte < 160
379
- [database.cp1252[byte] || byte].pack("U").unpack("C*")
380
- elsif byte < 192
381
- [194, byte]
382
- else
383
- [195, byte - 64]
384
- end
385
- end
386
-
387
- def database
388
- @database ||= UnicodeDatabase.new
389
- end
390
-
391
- end
392
- end
393
- end