monetra-ruby 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. data/Rakefile +35 -0
  2. data/lib/monetra.rb +239 -0
  3. data/lib/monetra/active_support.rb +42 -0
  4. data/lib/monetra/active_support/binding_of_caller.rb +84 -0
  5. data/lib/monetra/active_support/breakpoint.rb +523 -0
  6. data/lib/monetra/active_support/caching_tools.rb +62 -0
  7. data/lib/monetra/active_support/clean_logger.rb +38 -0
  8. data/lib/monetra/active_support/core_ext.rb +1 -0
  9. data/lib/monetra/active_support/core_ext/array.rb +7 -0
  10. data/lib/monetra/active_support/core_ext/array/conversions.rb +72 -0
  11. data/lib/monetra/active_support/core_ext/array/grouping.rb +46 -0
  12. data/lib/monetra/active_support/core_ext/bigdecimal.rb +3 -0
  13. data/lib/monetra/active_support/core_ext/bigdecimal/formatting.rb +7 -0
  14. data/lib/monetra/active_support/core_ext/blank.rb +50 -0
  15. data/lib/monetra/active_support/core_ext/cgi.rb +5 -0
  16. data/lib/monetra/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
  17. data/lib/monetra/active_support/core_ext/class.rb +3 -0
  18. data/lib/monetra/active_support/core_ext/class/attribute_accessors.rb +44 -0
  19. data/lib/monetra/active_support/core_ext/class/inheritable_attributes.rb +115 -0
  20. data/lib/monetra/active_support/core_ext/class/removal.rb +24 -0
  21. data/lib/monetra/active_support/core_ext/date.rb +6 -0
  22. data/lib/monetra/active_support/core_ext/date/conversions.rb +39 -0
  23. data/lib/monetra/active_support/core_ext/enumerable.rb +62 -0
  24. data/lib/monetra/active_support/core_ext/exception.rb +33 -0
  25. data/lib/monetra/active_support/core_ext/hash.rb +13 -0
  26. data/lib/monetra/active_support/core_ext/hash/conversions.rb +148 -0
  27. data/lib/monetra/active_support/core_ext/hash/diff.rb +11 -0
  28. data/lib/monetra/active_support/core_ext/hash/indifferent_access.rb +88 -0
  29. data/lib/monetra/active_support/core_ext/hash/keys.rb +53 -0
  30. data/lib/monetra/active_support/core_ext/hash/reverse_merge.rb +25 -0
  31. data/lib/monetra/active_support/core_ext/integer.rb +7 -0
  32. data/lib/monetra/active_support/core_ext/integer/even_odd.rb +24 -0
  33. data/lib/monetra/active_support/core_ext/integer/inflections.rb +15 -0
  34. data/lib/monetra/active_support/core_ext/kernel.rb +4 -0
  35. data/lib/monetra/active_support/core_ext/kernel/agnostics.rb +11 -0
  36. data/lib/monetra/active_support/core_ext/kernel/daemonizing.rb +15 -0
  37. data/lib/monetra/active_support/core_ext/kernel/reporting.rb +51 -0
  38. data/lib/monetra/active_support/core_ext/kernel/requires.rb +24 -0
  39. data/lib/monetra/active_support/core_ext/load_error.rb +38 -0
  40. data/lib/monetra/active_support/core_ext/logger.rb +16 -0
  41. data/lib/monetra/active_support/core_ext/module.rb +7 -0
  42. data/lib/monetra/active_support/core_ext/module/aliasing.rb +57 -0
  43. data/lib/monetra/active_support/core_ext/module/attr_internal.rb +31 -0
  44. data/lib/monetra/active_support/core_ext/module/attribute_accessors.rb +44 -0
  45. data/lib/monetra/active_support/core_ext/module/delegation.rb +41 -0
  46. data/lib/monetra/active_support/core_ext/module/inclusion.rb +11 -0
  47. data/lib/monetra/active_support/core_ext/module/introspection.rb +21 -0
  48. data/lib/monetra/active_support/core_ext/module/loading.rb +13 -0
  49. data/lib/monetra/active_support/core_ext/name_error.rb +20 -0
  50. data/lib/monetra/active_support/core_ext/numeric.rb +7 -0
  51. data/lib/monetra/active_support/core_ext/numeric/bytes.rb +44 -0
  52. data/lib/monetra/active_support/core_ext/numeric/time.rb +72 -0
  53. data/lib/monetra/active_support/core_ext/object.rb +2 -0
  54. data/lib/monetra/active_support/core_ext/object/extending.rb +47 -0
  55. data/lib/monetra/active_support/core_ext/object/misc.rb +34 -0
  56. data/lib/monetra/active_support/core_ext/pathname.rb +7 -0
  57. data/lib/monetra/active_support/core_ext/pathname/clean_within.rb +14 -0
  58. data/lib/monetra/active_support/core_ext/proc.rb +12 -0
  59. data/lib/monetra/active_support/core_ext/range.rb +5 -0
  60. data/lib/monetra/active_support/core_ext/range/conversions.rb +21 -0
  61. data/lib/monetra/active_support/core_ext/string.rb +13 -0
  62. data/lib/monetra/active_support/core_ext/string/access.rb +58 -0
  63. data/lib/monetra/active_support/core_ext/string/conversions.rb +19 -0
  64. data/lib/monetra/active_support/core_ext/string/inflections.rb +153 -0
  65. data/lib/monetra/active_support/core_ext/string/iterators.rb +17 -0
  66. data/lib/monetra/active_support/core_ext/string/starts_ends_with.rb +20 -0
  67. data/lib/monetra/active_support/core_ext/symbol.rb +12 -0
  68. data/lib/monetra/active_support/core_ext/time.rb +7 -0
  69. data/lib/monetra/active_support/core_ext/time/calculations.rb +188 -0
  70. data/lib/monetra/active_support/core_ext/time/conversions.rb +36 -0
  71. data/lib/monetra/active_support/dependencies.rb +187 -0
  72. data/lib/monetra/active_support/deprecation.rb +106 -0
  73. data/lib/monetra/active_support/inflections.rb +53 -0
  74. data/lib/monetra/active_support/inflector.rb +179 -0
  75. data/lib/monetra/active_support/json.rb +37 -0
  76. data/lib/monetra/active_support/json/encoders.rb +25 -0
  77. data/lib/monetra/active_support/json/encoders/core.rb +65 -0
  78. data/lib/monetra/active_support/option_merger.rb +25 -0
  79. data/lib/monetra/active_support/ordered_options.rb +50 -0
  80. data/lib/monetra/active_support/reloadable.rb +30 -0
  81. data/lib/monetra/active_support/values/time_zone.rb +180 -0
  82. data/lib/monetra/active_support/vendor/builder.rb +13 -0
  83. data/lib/monetra/active_support/vendor/builder/blankslate.rb +63 -0
  84. data/lib/monetra/active_support/vendor/builder/xchar.rb +112 -0
  85. data/lib/monetra/active_support/vendor/builder/xmlbase.rb +145 -0
  86. data/lib/monetra/active_support/vendor/builder/xmlevents.rb +63 -0
  87. data/lib/monetra/active_support/vendor/builder/xmlmarkup.rb +328 -0
  88. data/lib/monetra/active_support/vendor/flexmock.rb +84 -0
  89. data/lib/monetra/active_support/vendor/xml_simple.rb +1019 -0
  90. data/lib/monetra/active_support/version.rb +9 -0
  91. data/lib/monetra/active_support/whiny_nil.rb +38 -0
  92. data/test/test.rb +21 -0
  93. metadata +167 -0
@@ -0,0 +1,25 @@
1
+ module ActiveSupport
2
+ class OptionMerger #:nodoc:
3
+ instance_methods.each do |method|
4
+ undef_method(method) if method !~ /^(__|instance_eval)/
5
+ end
6
+
7
+ def initialize(context, options)
8
+ @context, @options = context, options
9
+ end
10
+
11
+ private
12
+ def method_missing(method, *arguments, &block)
13
+ merge_argument_options! arguments
14
+ @context.send(method, *arguments, &block)
15
+ end
16
+
17
+ def merge_argument_options!(arguments)
18
+ arguments << if arguments.last.respond_to? :to_hash
19
+ @options.merge(arguments.pop)
20
+ else
21
+ @options.dup
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ # OrderedHash is namespaced to prevent conflicts with other implementations
2
+ module ActiveSupport
3
+ class OrderedHash < Array #:nodoc:
4
+ def []=(key, value)
5
+ if pair = find_pair(key)
6
+ pair.pop
7
+ pair << value
8
+ else
9
+ self << [key, value]
10
+ end
11
+ end
12
+
13
+ def [](key)
14
+ pair = find_pair(key)
15
+ pair ? pair.last : nil
16
+ end
17
+
18
+ def keys
19
+ collect { |key, value| key }
20
+ end
21
+
22
+ def values
23
+ collect { |key, value| value }
24
+ end
25
+
26
+ private
27
+ def find_pair(key)
28
+ self.each { |i| return i if i.first == key }
29
+ return false
30
+ end
31
+ end
32
+ end
33
+
34
+ class OrderedOptions < ActiveSupport::OrderedHash #:nodoc:
35
+ def []=(key, value)
36
+ super(key.to_sym, value)
37
+ end
38
+
39
+ def [](key)
40
+ super(key.to_sym)
41
+ end
42
+
43
+ def method_missing(name, *args)
44
+ if name.to_s =~ /(.*)=$/
45
+ self[$1.to_sym] = args.first
46
+ else
47
+ self[name]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ # Classes that include this module will automatically be reloaded
2
+ # by the Rails dispatcher when Dependencies.mechanism = :load.
3
+ module Reloadable
4
+ class << self
5
+ def included(base) #nodoc:
6
+ raise TypeError, "Only Classes can be Reloadable!" unless base.is_a? Class
7
+
8
+ unless base.respond_to?(:reloadable?)
9
+ class << base
10
+ define_method(:reloadable?) { true }
11
+ end
12
+ end
13
+ end
14
+
15
+ def reloadable_classes
16
+ included_in_classes.select { |klass| klass.reloadable? }
17
+ end
18
+ end
19
+
20
+ # Captures the common pattern where a base class should not be reloaded,
21
+ # but its subclasses should be.
22
+ module Subclasses
23
+ def self.included(base) #nodoc:
24
+ base.send :include, Reloadable
25
+ (class << base; self; end).send(:define_method, :reloadable?) do
26
+ base != self
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,180 @@
1
+ # A value object representing a time zone. A time zone is simply a named
2
+ # offset (in seconds) from GMT. Note that two time zone objects are only
3
+ # equivalent if they have both the same offset, and the same name.
4
+ #
5
+ # A TimeZone instance may be used to convert a Time value to the corresponding
6
+ # time zone.
7
+ #
8
+ # The class also includes #all, which returns a list of all TimeZone objects.
9
+ class TimeZone
10
+ include Comparable
11
+
12
+ attr_reader :name, :utc_offset
13
+
14
+ # Create a new TimeZone object with the given name and offset. The offset is
15
+ # the number of seconds that this time zone is offset from UTC (GMT). Seconds
16
+ # were chosen as the offset unit because that is the unit that Ruby uses
17
+ # to represent time zone offsets (see Time#utc_offset).
18
+ def initialize(name, utc_offset)
19
+ @name = name
20
+ @utc_offset = utc_offset
21
+ end
22
+
23
+ # Returns the offset of this time zone as a formatted string, of the
24
+ # format "+HH:MM". If the offset is zero, this returns the empty
25
+ # string. If +colon+ is false, a colon will not be inserted into the
26
+ # result.
27
+ def formatted_offset( colon=true )
28
+ return "" if utc_offset == 0
29
+ sign = (utc_offset < 0 ? -1 : 1)
30
+ hours = utc_offset.abs / 3600
31
+ minutes = (utc_offset.abs % 3600) / 60
32
+ "%+03d%s%02d" % [ hours * sign, colon ? ":" : "", minutes ]
33
+ end
34
+
35
+ # Compute and return the current time, in the time zone represented by
36
+ # +self+.
37
+ def now
38
+ adjust(Time.now)
39
+ end
40
+
41
+ # Return the current date in this time zone.
42
+ def today
43
+ now.to_date
44
+ end
45
+
46
+ # Adjust the given time to the time zone represented by +self+.
47
+ def adjust(time)
48
+ time = time.to_time
49
+ time + utc_offset - time.utc_offset
50
+ end
51
+
52
+ # Reinterprets the given time value as a time in the current time
53
+ # zone, and then adjusts it to return the corresponding time in the
54
+ # local time zone.
55
+ def unadjust(time)
56
+ time = Time.local(*time.to_time.to_a)
57
+ time - utc_offset + time.utc_offset
58
+ end
59
+
60
+ # Compare this time zone to the parameter. The two are comapred first on
61
+ # their offsets, and then by name.
62
+ def <=>(zone)
63
+ result = (utc_offset <=> zone.utc_offset)
64
+ result = (name <=> zone.name) if result == 0
65
+ result
66
+ end
67
+
68
+ # Returns a textual representation of this time zone.
69
+ def to_s
70
+ "(GMT#{formatted_offset}) #{name}"
71
+ end
72
+
73
+ @@zones = nil
74
+
75
+ class << self
76
+ # Create a new TimeZone instance with the given name and offset.
77
+ def create(name, offset)
78
+ zone = allocate
79
+ zone.send :initialize, name, offset
80
+ zone
81
+ end
82
+
83
+ # Return a TimeZone instance with the given name, or +nil+ if no
84
+ # such TimeZone instance exists. (This exists to support the use of
85
+ # this class with the #composed_of macro.)
86
+ def new(name)
87
+ self[name]
88
+ end
89
+
90
+ # Return an array of all TimeZone objects. There are multiple TimeZone
91
+ # objects per time zone, in many cases, to make it easier for users to
92
+ # find their own time zone.
93
+ def all
94
+ unless @@zones
95
+ @@zones = []
96
+ [[-43_200, "International Date Line West" ],
97
+ [-39_600, "Midway Island", "Samoa" ],
98
+ [-36_000, "Hawaii" ],
99
+ [-32_400, "Alaska" ],
100
+ [-28_800, "Pacific Time (US & Canada)", "Tijuana" ],
101
+ [-25_200, "Mountain Time (US & Canada)", "Chihuahua", "La Paz",
102
+ "Mazatlan", "Arizona" ],
103
+ [-21_600, "Central Time (US & Canada)", "Saskatchewan", "Guadalajara",
104
+ "Mexico City", "Monterrey", "Central America" ],
105
+ [-18_000, "Eastern Time (US & Canada)", "Indiana (East)", "Bogota",
106
+ "Lima", "Quito" ],
107
+ [-14_400, "Atlantic Time (Canada)", "Caracas", "La Paz", "Santiago" ],
108
+ [-12_600, "Newfoundland" ],
109
+ [-10_800, "Brasilia", "Buenos Aires", "Georgetown", "Greenland" ],
110
+ [ -7_200, "Mid-Atlantic" ],
111
+ [ -3_600, "Azores", "Cape Verde Is." ],
112
+ [ 0, "Dublin", "Edinburgh", "Lisbon", "London", "Casablanca",
113
+ "Monrovia" ],
114
+ [ 3_600, "Belgrade", "Bratislava", "Budapest", "Ljubljana", "Prague",
115
+ "Sarajevo", "Skopje", "Warsaw", "Zagreb", "Brussels",
116
+ "Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin",
117
+ "Bern", "Rome", "Stockholm", "Vienna",
118
+ "West Central Africa" ],
119
+ [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia",
120
+ "Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk",
121
+ "Jerusalem", "Harare", "Pretoria" ],
122
+ [ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh",
123
+ "Nairobi", "Baghdad" ],
124
+ [ 12_600, "Tehran" ],
125
+ [ 14_400, "Abu Dhabi", "Muscat", "Baku", "Tbilisi", "Yerevan" ],
126
+ [ 16_200, "Kabul" ],
127
+ [ 18_000, "Ekaterinburg", "Islamabad", "Karachi", "Tashkent" ],
128
+ [ 19_800, "Chennai", "Kolkata", "Mumbai", "New Delhi" ],
129
+ [ 20_700, "Kathmandu" ],
130
+ [ 21_600, "Astana", "Dhaka", "Sri Jayawardenepura", "Almaty",
131
+ "Novosibirsk" ],
132
+ [ 23_400, "Rangoon" ],
133
+ [ 25_200, "Bangkok", "Hanoi", "Jakarta", "Krasnoyarsk" ],
134
+ [ 28_800, "Beijing", "Chongqing", "Hong Kong", "Urumqi",
135
+ "Kuala Lumpur", "Singapore", "Taipei", "Perth", "Irkutsk",
136
+ "Ulaan Bataar" ],
137
+ [ 32_400, "Seoul", "Osaka", "Sapporo", "Tokyo", "Yakutsk" ],
138
+ [ 34_200, "Darwin", "Adelaide" ],
139
+ [ 36_000, "Canberra", "Melbourne", "Sydney", "Brisbane", "Hobart",
140
+ "Vladivostok", "Guam", "Port Moresby" ],
141
+ [ 39_600, "Magadan", "Solomon Is.", "New Caledonia" ],
142
+ [ 43_200, "Fiji", "Kamchatka", "Marshall Is.", "Auckland",
143
+ "Wellington" ],
144
+ [ 46_800, "Nuku'alofa" ]].
145
+ each do |offset, *places|
146
+ places.each { |place| @@zones << create(place, offset).freeze }
147
+ end
148
+ @@zones.sort!
149
+ end
150
+ @@zones
151
+ end
152
+
153
+ # Locate a specific time zone object. If the argument is a string, it
154
+ # is interpreted to mean the name of the timezone to locate. If it is a
155
+ # numeric value it is either the hour offset, or the second offset, of the
156
+ # timezone to find. (The first one with that offset will be returned.)
157
+ # Returns +nil+ if no such time zone is known to the system.
158
+ def [](arg)
159
+ case arg
160
+ when String
161
+ all.find { |z| z.name == arg }
162
+ when Numeric
163
+ arg *= 3600 if arg.abs <= 13
164
+ all.find { |z| z.utc_offset == arg.to_i }
165
+ else
166
+ raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
167
+ end
168
+ end
169
+
170
+ # A regular expression that matches the names of all time zones in
171
+ # the USA.
172
+ US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/ unless defined?(US_ZONES)
173
+
174
+ # A convenience method for returning a collection of TimeZone objects
175
+ # for time zones in the USA.
176
+ def us_zones
177
+ all.find_all { |z| z.name =~ US_ZONES }
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #++
11
+
12
+ require 'builder/xmlmarkup'
13
+ require 'builder/xmlevents'
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+ #++
10
+
11
+ module Builder #:nodoc:
12
+
13
+ # BlankSlate provides an abstract base class with no predefined
14
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
15
+ # BlankSlate is useful as a base class when writing classes that
16
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
17
+ class BlankSlate
18
+ class << self
19
+
20
+ # Hide the method named +name+ in the BlankSlate class. Don't
21
+ # hide +instance_eval+ or any method beginning with "__".
22
+ def hide(name)
23
+ undef_method name if
24
+ instance_methods.include?(name.to_s) and
25
+ name !~ /^(__|instance_eval)/
26
+ end
27
+ end
28
+
29
+ instance_methods.each { |m| hide(m) }
30
+ end
31
+ end
32
+
33
+ # Since Ruby is very dynamic, methods added to the ancestors of
34
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
35
+ # list of available BlankSlate methods. We handle this by defining a
36
+ # hook in the Object and Kernel classes that will hide any defined
37
+ module Kernel #:nodoc:
38
+ class << self
39
+ alias_method :blank_slate_method_added, :method_added
40
+
41
+ # Detect method additions to Kernel and remove them in the
42
+ # BlankSlate class.
43
+ def method_added(name)
44
+ blank_slate_method_added(name)
45
+ return if self != Kernel
46
+ Builder::BlankSlate.hide(name)
47
+ end
48
+ end
49
+ end
50
+
51
+ class Object #:nodoc:
52
+ class << self
53
+ alias_method :blank_slate_method_added, :method_added
54
+
55
+ # Detect method additions to Object and remove them in the
56
+ # BlankSlate class.
57
+ def method_added(name)
58
+ blank_slate_method_added(name)
59
+ return if self != Object
60
+ Builder::BlankSlate.hide(name)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # The XChar library is provided courtesy of Sam Ruby (See
4
+ # http://intertwingly.net/stories/2005/09/28/xchar.rb)
5
+
6
+ # --------------------------------------------------------------------
7
+
8
+ # If the Builder::XChar module is not currently defined, fail on any
9
+ # name clashes in standard library classes.
10
+
11
+ module Builder
12
+ def self.check_for_name_collision(klass, method_name, defined_constant=nil)
13
+ if klass.instance_methods.include?(method_name)
14
+ fail RuntimeError,
15
+ "Name Collision: Method '#{method_name}' is already defined in #{klass}"
16
+ end
17
+ end
18
+ end
19
+
20
+ if ! defined?(Builder::XChar)
21
+ Builder.check_for_name_collision(String, "to_xs")
22
+ Builder.check_for_name_collision(Fixnum, "xchr")
23
+ end
24
+
25
+ ######################################################################
26
+ module Builder
27
+
28
+ ####################################################################
29
+ # XML Character converter, from Sam Ruby:
30
+ # (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
31
+ #
32
+ module XChar # :nodoc:
33
+
34
+ # See
35
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
36
+ # for details.
37
+ CP1252 = { # :nodoc:
38
+ 128 => 8364, # euro sign
39
+ 130 => 8218, # single low-9 quotation mark
40
+ 131 => 402, # latin small letter f with hook
41
+ 132 => 8222, # double low-9 quotation mark
42
+ 133 => 8230, # horizontal ellipsis
43
+ 134 => 8224, # dagger
44
+ 135 => 8225, # double dagger
45
+ 136 => 710, # modifier letter circumflex accent
46
+ 137 => 8240, # per mille sign
47
+ 138 => 352, # latin capital letter s with caron
48
+ 139 => 8249, # single left-pointing angle quotation mark
49
+ 140 => 338, # latin capital ligature oe
50
+ 142 => 381, # latin capital letter z with caron
51
+ 145 => 8216, # left single quotation mark
52
+ 146 => 8217, # right single quotation mark
53
+ 147 => 8220, # left double quotation mark
54
+ 148 => 8221, # right double quotation mark
55
+ 149 => 8226, # bullet
56
+ 150 => 8211, # en dash
57
+ 151 => 8212, # em dash
58
+ 152 => 732, # small tilde
59
+ 153 => 8482, # trade mark sign
60
+ 154 => 353, # latin small letter s with caron
61
+ 155 => 8250, # single right-pointing angle quotation mark
62
+ 156 => 339, # latin small ligature oe
63
+ 158 => 382, # latin small letter z with caron
64
+ 159 => 376, # latin capital letter y with diaeresis
65
+ }
66
+
67
+ # See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
68
+ PREDEFINED = {
69
+ 38 => '&amp;', # ampersand
70
+ 60 => '&lt;', # left angle bracket
71
+ 62 => '&gt;', # right angle bracket
72
+ }
73
+
74
+ # See http://www.w3.org/TR/REC-xml/#charsets for details.
75
+ VALID = [
76
+ [0x9, 0xA, 0xD],
77
+ (0x20..0xD7FF),
78
+ (0xE000..0xFFFD),
79
+ (0x10000..0x10FFFF)
80
+ ]
81
+ end
82
+
83
+ end
84
+
85
+
86
+ ######################################################################
87
+ # Enhance the Fixnum class with a XML escaped character conversion.
88
+ #
89
+ class Fixnum #:nodoc:
90
+ XChar = Builder::XChar if ! defined?(XChar)
91
+
92
+ # XML escaped version of chr
93
+ def xchr
94
+ n = XChar::CP1252[self] || self
95
+ n = 42 unless XChar::VALID.find {|range| range.include? n}
96
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
97
+ end
98
+ end
99
+
100
+
101
+ ######################################################################
102
+ # Enhance the String class with a XML escaped character version of
103
+ # to_s.
104
+ #
105
+ class String #:nodoc:
106
+ # XML escaped version of to_s
107
+ def to_xs
108
+ unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
109
+ rescue
110
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
111
+ end
112
+ end