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.
- data/CHANGELOG +1 -100
- data/lib/active_support.rb +4 -38
- data/lib/active_support/autoload.rb +28 -0
- data/lib/active_support/backtrace_cleaner.rb +9 -31
- data/lib/active_support/benchmarkable.rb +0 -1
- data/lib/active_support/buffered_logger.rb +1 -0
- data/lib/active_support/cache.rb +81 -436
- data/lib/active_support/cache/compressed_mem_cache_store.rb +13 -6
- data/lib/active_support/cache/file_store.rb +41 -139
- data/lib/active_support/cache/mem_cache_store.rb +75 -120
- data/lib/active_support/cache/memory_store.rb +27 -127
- data/lib/active_support/cache/strategy/local_cache.rb +58 -111
- data/lib/active_support/cache/synchronized_memory_store.rb +38 -2
- data/lib/active_support/callbacks.rb +48 -87
- data/lib/active_support/configurable.rb +18 -19
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +1 -1
- data/lib/active_support/core_ext/array/conversions.rb +54 -29
- data/lib/active_support/core_ext/array/extract_options.rb +1 -16
- data/lib/active_support/core_ext/array/random_access.rb +5 -19
- data/lib/active_support/core_ext/array/wrap.rb +9 -13
- data/lib/active_support/core_ext/benchmark.rb +12 -0
- data/lib/active_support/core_ext/boolean.rb +1 -0
- data/lib/active_support/core_ext/boolean/conversions.rb +11 -0
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -2
- data/lib/active_support/core_ext/class.rb +1 -1
- data/lib/active_support/core_ext/class/attribute_accessors.rb +27 -33
- data/lib/active_support/core_ext/class/delegating_attributes.rb +41 -35
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +13 -22
- data/lib/active_support/core_ext/class/removal.rb +53 -0
- data/lib/active_support/core_ext/date.rb +7 -0
- data/lib/active_support/core_ext/date/calculations.rb +8 -30
- data/lib/active_support/core_ext/date/conversions.rb +2 -2
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +5 -23
- data/lib/active_support/core_ext/enumerable.rb +9 -5
- data/lib/active_support/core_ext/exception.rb +47 -0
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +2 -3
- data/lib/active_support/core_ext/float/rounding.rb +2 -3
- data/lib/active_support/core_ext/hash/conversions.rb +145 -65
- data/lib/active_support/core_ext/hash/deep_merge.rb +7 -6
- data/lib/active_support/core_ext/hash/except.rb +0 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +0 -5
- data/lib/active_support/core_ext/hash/keys.rb +11 -10
- data/lib/active_support/core_ext/hash/slice.rb +0 -6
- data/lib/active_support/core_ext/integer.rb +1 -1
- data/lib/active_support/core_ext/integer/even_odd.rb +16 -0
- data/lib/active_support/core_ext/kernel.rb +1 -1
- data/lib/active_support/core_ext/kernel/daemonizing.rb +7 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -3
- data/lib/active_support/core_ext/kernel/reporting.rb +1 -2
- data/lib/active_support/core_ext/load_error.rb +30 -17
- data/lib/active_support/core_ext/logger.rb +1 -1
- data/lib/active_support/core_ext/module.rb +3 -5
- data/lib/active_support/core_ext/module/aliasing.rb +1 -1
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -25
- data/lib/active_support/core_ext/module/delegation.rb +10 -21
- data/lib/active_support/core_ext/module/inclusion.rb +30 -0
- data/lib/active_support/core_ext/module/introspection.rb +8 -8
- data/lib/active_support/core_ext/module/loading.rb +23 -0
- data/lib/active_support/core_ext/module/synchronization.rb +1 -2
- data/lib/active_support/core_ext/name_error.rb +1 -3
- data/lib/active_support/core_ext/nil.rb +1 -0
- data/lib/active_support/core_ext/nil/conversions.rb +5 -0
- data/lib/active_support/core_ext/object.rb +2 -6
- data/lib/active_support/core_ext/object/blank.rb +2 -20
- data/lib/active_support/core_ext/object/conversions.rb +16 -2
- data/lib/active_support/core_ext/object/duplicable.rb +1 -23
- data/lib/active_support/core_ext/object/extending.rb +77 -8
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -0
- data/lib/active_support/core_ext/object/metaclass.rb +13 -0
- data/lib/active_support/core_ext/object/misc.rb +1 -0
- data/lib/active_support/core_ext/object/tap.rb +16 -0
- data/lib/active_support/core_ext/object/with_options.rb +0 -2
- data/lib/active_support/core_ext/proc.rb +4 -4
- data/lib/active_support/core_ext/regexp.rb +22 -0
- data/lib/active_support/core_ext/rexml.rb +1 -4
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/string/access.rb +2 -4
- data/lib/active_support/core_ext/string/bytesize.rb +5 -0
- data/lib/active_support/core_ext/string/conversions.rb +1 -36
- data/lib/active_support/core_ext/string/filters.rb +0 -29
- data/lib/active_support/core_ext/string/inflections.rb +12 -1
- data/lib/active_support/core_ext/string/interpolation.rb +92 -2
- data/lib/active_support/core_ext/string/iterators.rb +13 -0
- data/lib/active_support/core_ext/string/multibyte.rb +19 -16
- data/lib/active_support/core_ext/string/output_safety.rb +35 -101
- data/lib/active_support/core_ext/string/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/string/xchar.rb +1 -1
- data/lib/active_support/core_ext/symbol.rb +1 -0
- data/lib/active_support/core_ext/symbol/to_proc.rb +14 -0
- data/lib/active_support/core_ext/time.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +7 -9
- data/lib/active_support/core_ext/time/conversions.rb +0 -1
- data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +22 -0
- data/lib/active_support/core_ext/uri.rb +4 -10
- data/lib/active_support/dependencies.rb +192 -179
- data/lib/active_support/deprecated_callbacks.rb +283 -0
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/deprecation/method_wrappers.rb +9 -10
- data/lib/active_support/deprecation/reporting.rb +1 -2
- data/lib/active_support/duration.rb +2 -6
- data/lib/active_support/hash_with_indifferent_access.rb +1 -9
- data/lib/active_support/inflections.rb +1 -1
- data/lib/active_support/inflector.rb +407 -4
- data/lib/active_support/json/backends/jsongem.rb +9 -12
- data/lib/active_support/json/decoding.rb +1 -16
- data/lib/active_support/json/encoding.rb +12 -42
- data/lib/active_support/locale/en.yml +1 -4
- data/lib/active_support/memoizable.rb +1 -1
- data/lib/active_support/message_encryptor.rb +0 -1
- data/lib/active_support/message_verifier.rb +5 -6
- data/lib/active_support/multibyte.rb +22 -7
- data/lib/active_support/multibyte/chars.rb +392 -164
- data/lib/active_support/multibyte/unicode_database.rb +71 -0
- data/lib/active_support/multibyte/utils.rb +7 -6
- data/lib/active_support/notifications.rb +113 -23
- data/lib/active_support/ordered_hash.rb +11 -35
- data/lib/active_support/ordered_options.rb +0 -6
- data/lib/active_support/rescuable.rb +4 -7
- data/lib/active_support/ruby/shim.rb +6 -4
- data/lib/active_support/test_case.rb +7 -2
- data/lib/active_support/testing/assertions.rb +0 -15
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/isolation.rb +19 -63
- data/lib/active_support/testing/performance.rb +337 -342
- data/lib/active_support/testing/setup_and_teardown.rb +29 -51
- data/lib/active_support/time.rb +3 -23
- data/lib/active_support/time_with_zone.rb +10 -5
- data/lib/active_support/values/time_zone.rb +84 -40
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/vendor.rb +16 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb +113 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder.rb +13 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb +20 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb +250 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb +115 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb +139 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb +63 -0
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb +328 -0
- data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +20 -0
- data/lib/active_support/vendor/i18n-0.1.3/README.textile +20 -0
- data/lib/active_support/vendor/i18n-0.1.3/Rakefile +5 -0
- data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +27 -0
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +204 -0
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +215 -0
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +53 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +5 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +99 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +124 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +1 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +3 -0
- data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +567 -0
- data/lib/active_support/vendor/memcache-client-1.7.5/lib/memcache.rb +1133 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone.rb +47 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone_info.rb +228 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Algiers.rb +55 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Cairo.rb +219 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Casablanca.rb +42 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Harare.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Johannesburg.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Monrovia.rb +22 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Nairobi.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +166 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/San_Juan.rb +86 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Bogota.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Caracas.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chicago.rb +283 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chihuahua.rb +136 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Denver.rb +204 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Godthab.rb +161 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Guatemala.rb +27 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Halifax.rb +274 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb +149 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Juneau.rb +194 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/La_Paz.rb +22 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Lima.rb +35 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Los_Angeles.rb +232 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mazatlan.rb +139 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mexico_City.rb +144 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Monterrey.rb +131 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/New_York.rb +282 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Phoenix.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Regina.rb +74 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Santiago.rb +205 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Sao_Paulo.rb +171 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/St_Johns.rb +288 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Tijuana.rb +196 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Almaty.rb +67 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baghdad.rb +73 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baku.rb +161 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Bangkok.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Chongqing.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Colombo.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Dhaka.rb +27 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Hong_Kong.rb +87 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Irkutsk.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jakarta.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jerusalem.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kabul.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kamchatka.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Karachi.rb +32 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kathmandu.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kolkata.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb +31 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuwait.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Magadan.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Muscat.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Novosibirsk.rb +164 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Rangoon.rb +24 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Riyadh.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Seoul.rb +34 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Shanghai.rb +35 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Singapore.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Taipei.rb +59 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tashkent.rb +47 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tbilisi.rb +78 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tehran.rb +121 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tokyo.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb +65 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Urumqi.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Vladivostok.rb +164 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yakutsk.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yekaterinburg.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yerevan.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Azores.rb +270 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/South_Georgia.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Adelaide.rb +187 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Brisbane.rb +35 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Darwin.rb +29 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Hobart.rb +193 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Melbourne.rb +185 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Perth.rb +37 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Sydney.rb +185 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Etc/UTC.rb +16 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Amsterdam.rb +228 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Athens.rb +185 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Belgrade.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Berlin.rb +188 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bratislava.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Brussels.rb +232 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bucharest.rb +181 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Budapest.rb +197 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Copenhagen.rb +179 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Dublin.rb +276 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Helsinki.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Istanbul.rb +218 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Kiev.rb +168 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Lisbon.rb +268 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Ljubljana.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/London.rb +288 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Madrid.rb +211 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Minsk.rb +170 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Moscow.rb +181 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Paris.rb +232 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Prague.rb +187 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Riga.rb +176 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Rome.rb +215 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sarajevo.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Skopje.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sofia.rb +173 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Stockholm.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Tallinn.rb +172 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vienna.rb +183 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vilnius.rb +170 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Warsaw.rb +212 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Zagreb.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Auckland.rb +202 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Fiji.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Guam.rb +22 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Honolulu.rb +28 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Majuro.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Midway.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Noumea.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Pago_Pago.rb +26 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Port_Moresby.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Tongatapu.rb +27 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/info_timezone.rb +52 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone.rb +51 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone_info.rb +44 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/offset_rationals.rb +98 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/ruby_core_support.rb +56 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/time_or_datetime.rb +292 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone.rb +508 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_definition.rb +56 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_info.rb +40 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_offset_info.rb +94 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_period.rb +198 -0
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_transition_info.rb +129 -0
- data/lib/active_support/version.rb +2 -3
- data/lib/active_support/whiny_nil.rb +7 -9
- data/lib/active_support/xml_mini.rb +1 -126
- data/lib/active_support/xml_mini/jdom.rb +0 -2
- data/lib/active_support/xml_mini/libxml.rb +86 -24
- data/lib/active_support/xml_mini/nokogiri.rb +24 -27
- data/lib/active_support/xml_mini/rexml.rb +1 -7
- metadata +191 -49
- data/lib/active_support/builder.rb +0 -6
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -17
- data/lib/active_support/core_ext/class/attribute.rb +0 -67
- data/lib/active_support/core_ext/class/subclasses.rb +0 -55
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/integer/multiple.rb +0 -6
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -13
- data/lib/active_support/core_ext/module/anonymous.rb +0 -24
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/reachable.rb +0 -10
- data/lib/active_support/core_ext/module/remove_method.rb +0 -6
- data/lib/active_support/core_ext/object/to_param.rb +0 -49
- data/lib/active_support/core_ext/object/to_query.rb +0 -27
- data/lib/active_support/core_ext/string/encoding.rb +0 -11
- data/lib/active_support/core_ext/string/exclude.rb +0 -6
- data/lib/active_support/core_ext/time/marshal.rb +0 -56
- data/lib/active_support/dependencies/autoload.rb +0 -50
- data/lib/active_support/i18n.rb +0 -8
- data/lib/active_support/inflector/inflections.rb +0 -211
- data/lib/active_support/inflector/methods.rb +0 -141
- data/lib/active_support/inflector/transliterate.rb +0 -97
- data/lib/active_support/json/backends/yajl.rb +0 -40
- data/lib/active_support/lazy_load_hooks.rb +0 -27
- data/lib/active_support/multibyte/unicode.rb +0 -393
- data/lib/active_support/notifications/fanout.rb +0 -93
- data/lib/active_support/notifications/instrumenter.rb +0 -56
- data/lib/active_support/railtie.rb +0 -100
- data/lib/active_support/xml_mini/libxmlsax.rb +0 -85
- 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
|