cheri 0.0.2

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 (79) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +98 -0
  3. data/Rakefile +121 -0
  4. data/examples/hello_world_1.rb +28 -0
  5. data/examples/table_1.rb +44 -0
  6. data/lib/cheri/awt.rb +41 -0
  7. data/lib/cheri/builder.rb +31 -0
  8. data/lib/cheri/builder/awt/connecter.rb +63 -0
  9. data/lib/cheri/builder/awt/constants.rb +1003 -0
  10. data/lib/cheri/builder/awt/main.rb +191 -0
  11. data/lib/cheri/builder/awt/types.rb +220 -0
  12. data/lib/cheri/builder/base.rb +533 -0
  13. data/lib/cheri/builder/config.rb +187 -0
  14. data/lib/cheri/builder/connecter.rb +386 -0
  15. data/lib/cheri/builder/context.rb +655 -0
  16. data/lib/cheri/builder/generator.rb +425 -0
  17. data/lib/cheri/builder/html/charsets.rb +154 -0
  18. data/lib/cheri/builder/html/common.rb +32 -0
  19. data/lib/cheri/builder/html/connecter.rb +57 -0
  20. data/lib/cheri/builder/html/element.rb +156 -0
  21. data/lib/cheri/builder/html/main.rb +116 -0
  22. data/lib/cheri/builder/html/types.rb +123 -0
  23. data/lib/cheri/builder/main.rb +483 -0
  24. data/lib/cheri/builder/swing/connecter.rb +141 -0
  25. data/lib/cheri/builder/swing/constants.rb +420 -0
  26. data/lib/cheri/builder/swing/main.rb +446 -0
  27. data/lib/cheri/builder/swing/types.rb +270 -0
  28. data/lib/cheri/builder/xml/charsets.rb +154 -0
  29. data/lib/cheri/builder/xml/common.rb +32 -0
  30. data/lib/cheri/builder/xml/connecter.rb +42 -0
  31. data/lib/cheri/builder/xml/element.rb +189 -0
  32. data/lib/cheri/builder/xml/main.rb +130 -0
  33. data/lib/cheri/builder/xml/types.rb +36 -0
  34. data/lib/cheri/cheri.rb +70 -0
  35. data/lib/cheri/cjx.rb +3 -0
  36. data/lib/cheri/explorer.rb +32 -0
  37. data/lib/cheri/explorer/explorer.rb +560 -0
  38. data/lib/cheri/html.rb +31 -0
  39. data/lib/cheri/image/Delete24.gif +0 -0
  40. data/lib/cheri/image/Find24.gif +0 -0
  41. data/lib/cheri/image/FindAgain24.gif +0 -0
  42. data/lib/cheri/image/Refresh24.gif +0 -0
  43. data/lib/cheri/image/Search24.gif +0 -0
  44. data/lib/cheri/image/Thumbs.db +0 -0
  45. data/lib/cheri/image/cheri_icon_16x16.png +0 -0
  46. data/lib/cheri/image/cheri_icon_24x24.png +0 -0
  47. data/lib/cheri/image/cheri_logo_medium.png +0 -0
  48. data/lib/cheri/image/close_10x10.png +0 -0
  49. data/lib/cheri/image/close_10x10s.png +0 -0
  50. data/lib/cheri/image/close_12x12.png +0 -0
  51. data/lib/cheri/image/close_14x14.png +0 -0
  52. data/lib/cheri/image/close_24x24.png +0 -0
  53. data/lib/cheri/image/close_dim2_12x12.png +0 -0
  54. data/lib/cheri/image/close_dim_12x12.png +0 -0
  55. data/lib/cheri/image/cls_tree.png +0 -0
  56. data/lib/cheri/image/con_tree.png +0 -0
  57. data/lib/cheri/image/jruby_14x16.png +0 -0
  58. data/lib/cheri/image/jruby_logo.png +0 -0
  59. data/lib/cheri/image/mod_tree.png +0 -0
  60. data/lib/cheri/image/obj_tree.png +0 -0
  61. data/lib/cheri/image/ruby_16x16.png +0 -0
  62. data/lib/cheri/image/vars_tree.png +0 -0
  63. data/lib/cheri/java.rb +26 -0
  64. data/lib/cheri/java/builder.rb +28 -0
  65. data/lib/cheri/java/builder/main.rb +407 -0
  66. data/lib/cheri/java/builder/util.rb +480 -0
  67. data/lib/cheri/java/java.rb +56 -0
  68. data/lib/cheri/jruby.rb +32 -0
  69. data/lib/cheri/jruby/explorer.rb +43 -0
  70. data/lib/cheri/jruby/explorer/common.rb +38 -0
  71. data/lib/cheri/jruby/explorer/dialogs.rb +383 -0
  72. data/lib/cheri/jruby/explorer/explorer.rb +904 -0
  73. data/lib/cheri/jruby/explorer/splash.rb +80 -0
  74. data/lib/cheri/jruby/explorer/viewer.rb +619 -0
  75. data/lib/cheri/jruby/explorer/viewers.rb +1057 -0
  76. data/lib/cheri/jruby/jruby.rb +59 -0
  77. data/lib/cheri/swing.rb +41 -0
  78. data/lib/cheri/xml.rb +31 -0
  79. metadata +135 -0
@@ -0,0 +1,425 @@
1
+ #--
2
+ # Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ #
24
+
25
+ module Cheri
26
+ module Builder
27
+
28
+ class Generator
29
+ module Template
30
+ class << self
31
+ def append_features(clazz)
32
+ Cheri::Builder.module_included(@ext,clazz) if @ext
33
+ Cheri::Builder.module_included(self,clazz)
34
+ super
35
+ end
36
+ private :append_features
37
+
38
+ def factory
39
+ @fct
40
+ end
41
+
42
+ def connecter
43
+ @ctr
44
+ end
45
+
46
+ def consumer
47
+ @cns
48
+ end
49
+ end #self
50
+ end #Template
51
+
52
+ class TypeBuilder < Cheri::Builder::AbstractBuilder
53
+ def initialize(mod,clazz,*r,&k)
54
+ super(*r,&k)
55
+ @mod = mod
56
+ @clazz = clazz
57
+ end
58
+ # returns the module to which this builder belongs
59
+ def mod
60
+ @mod
61
+ end
62
+ def run
63
+ @obj = @clazz.new(*@args)
64
+ @ctx.call(self,&@blk) if @blk
65
+ @obj
66
+ end
67
+ end #TypeBuilder
68
+
69
+ class CherifyBuilder < Cheri::Builder::AbstractBuilder
70
+ def initialize(mod,ctx,sym,*args,&k)
71
+ raise Cheri.argument_error(args.length,1) unless args.length == 1
72
+ super(ctx,sym,*args,&k)
73
+ @mod = mod
74
+ @obj = args.first
75
+ end
76
+ def mod
77
+ @mod
78
+ end
79
+ def run
80
+ @ctx.call(self,&@blk) if @blk
81
+ @obj
82
+ end
83
+ end
84
+
85
+ class CheriYieldBuilder < CherifyBuilder
86
+ def child?
87
+ false
88
+ end
89
+ end
90
+
91
+ class TypeFactory
92
+ def initialize(mod,types)
93
+ raise Cheri.type_error(types,Hash) unless Hash === types
94
+ @mod = mod
95
+ @types = types
96
+ @inv = types.invert
97
+ end
98
+ def builder(ctx,sym,*r,&k)
99
+ if (clazz = @types[sym])
100
+ TypeBuilder.new(@mod,clazz,ctx,sym,*r,&k)
101
+ elsif @inv[r.first.class]
102
+ if sym == :cherify
103
+ CherifyBuilder.new(@mod,ctx,sym,*r,&k)
104
+ elsif sym == :cheri_yield
105
+ CheriYieldBuilder.new(@mod,ctx,sym,*r,&k)
106
+ else
107
+ nil
108
+ end
109
+ else
110
+ nil
111
+ end
112
+ end
113
+ end #TypeFactory
114
+
115
+ class AutoFactory
116
+ def initialize(mod,types)
117
+ raise Cheri.type_error(types,Hash) unless Hash === types
118
+ @mod = mod
119
+ @types = types
120
+ @inv = types.invert
121
+ end
122
+ def builder(ctx,sym,*r,&k)
123
+ if (clazz = @types[sym])
124
+ bld = clazz.new(ctx,sym,*r,&k)
125
+ elsif @inv[r.first.class]
126
+ if sym == :cherify
127
+ CherifyBuilder.new(@mod,ctx,sym,*r,&k)
128
+ elsif sym == :cheri_yield
129
+ CheriYieldBuilder.new(@mod,ctx,sym,*r,&k)
130
+ else
131
+ nil
132
+ end
133
+ else
134
+ nil
135
+ end
136
+ end
137
+ end #AutoFactory
138
+
139
+ CamelCase = /([a-z])([A-Z])/ #:nodoc:
140
+ RubyCase = '\1_\2' #:nodoc:
141
+ Sep = '::' #:nodoc:
142
+ def initialize(*r,&k)
143
+ raise ArgumentError,"no args or block supplied" unless k || !r.empty?
144
+ raise ArgumentError,"no arguments permitted when block supplied" if k && !r.empty?
145
+ @args = r
146
+ @blk = k if k
147
+ end
148
+
149
+ def run
150
+ if @blk
151
+ eb = EvalBuilder.new(&@blk)
152
+ create_mod(eb)
153
+ else
154
+ # _really_ simple builder
155
+ @types = {}
156
+ @ctr = TypeConnecter.new
157
+ if Hash === @args.last
158
+ @args.pop.each_pair do |clazz,adder|
159
+ add_type(clazz,nil,adder)
160
+ end
161
+ end
162
+ @args.each do |clazz|
163
+ add_type(clazz)
164
+ end
165
+ create_simple_mod
166
+ end
167
+ end
168
+
169
+ def add_type(clazz,sym=nil,adder=:add)
170
+ raise Cheri.type_error(clazz,Class) unless Class === clazz
171
+ raise Cheri.type_error(sym,Symbol,String) if sym && !(Symbol === sym || String === sym)
172
+ raise Cheri.type_error(adder,Symbol,String) unless Symbol === adder || String === adder
173
+ sym ||= make_sym(clazz)
174
+ adder = adder.to_sym
175
+ warn "warning: redefining type #{sym} => #{clazz}" if @types[sym]
176
+ @types[sym] = clazz
177
+ @ctr.add_type(clazz).connect(Object,adder)
178
+ end
179
+ private :add_type
180
+
181
+ def make_sym(clazz)
182
+ if (s = (name = clazz.name).rindex(Sep))
183
+ name = name[s+2,name.length-s-2]
184
+ end
185
+ name.gsub(CamelCase,RubyCase).downcase!.to_sym
186
+ end
187
+ private :make_sym
188
+
189
+ def create_simple_mod
190
+ mod = Template.dup
191
+ mod.instance_variable_set(:@fct, fct = TypeFactory.new(mod,@types))
192
+ mod.const_set('Factory',fct)
193
+ mod.instance_variable_set(:@ctr,@ctr)
194
+ mod.const_set('Connecter',@ctr)
195
+ mod.instance_variable_set(:@cns,Cheri::Builder::DefaultConsumer)
196
+ mod.const_set('Consumer',Cheri::Builder::DefaultConsumer)
197
+ mod.send(:include,Cheri::Builder)
198
+ mod
199
+ end
200
+ private :create_simple_mod
201
+
202
+ def create_mod(eb)
203
+ mapped = eb.__mapped
204
+ unmapped = eb.__unmapped
205
+ ext = eb.__ext
206
+ pkg = eb.__pkg
207
+ tc = eb.__tc
208
+ # sc = eb.__sc
209
+ # this may be valid if the user is just adding connecters to an existing builder
210
+ if mapped.empty? && unmapped.empty? && !pkg && !(ext && tc)
211
+ raise BuilderException,"no build classes specified!"
212
+ end
213
+ # map any unmapped class names to symbols
214
+ unless unmapped.empty?
215
+ iv = mapped.invert
216
+ unmapped.each do |unm|
217
+ unless iv[unm]
218
+ sym = make_sym(unm)
219
+ if (dupl = mapped[sym])
220
+ warn "warning: derived symbol #{sym} (#{unm}) conflicts with symbol for #{dupl} -- ignoring"
221
+ else
222
+ mapped[sym] = unm
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ # separate the Java classes (if any)
229
+ jmapped = nil
230
+ if !mapped.empty? && defined?Cheri::Java::Builder
231
+ jmapped = {}
232
+ mapped.each_pair do |sym,clazz|
233
+ jmapped[sym] = clazz if clazz.respond_to?(:java_class)
234
+ end
235
+ if jmapped.empty?
236
+ jmapped = nil
237
+ else
238
+ jmapped.each_key do |sym|
239
+ mapped.delete(sym)
240
+ end
241
+ end
242
+ end
243
+
244
+ # separate the auto classes (self-building, e.g. Cheri::Xml::Elem), if any
245
+ # doesn't (currently) apply to Java classes (and likely never will)
246
+ amapped = nil
247
+ unless mapped.empty?
248
+ amapped = {}
249
+ mapped.each_pair do |sym,clazz|
250
+ if clazz < Cheri::Builder::Frame
251
+ amapped[sym] = clazz
252
+ end
253
+ end
254
+ if amapped.empty?
255
+ amapped = nil
256
+ else
257
+ amapped.each_key do |sym|
258
+ mapped.delete(sym)
259
+ end
260
+ end
261
+ end
262
+
263
+ mapped = nil if mapped.empty?
264
+
265
+ # create the module
266
+ mod = Template.dup
267
+ mod.send(:include,Cheri::Builder)
268
+ # determine if we need a SuperFactory
269
+ fcount = 0
270
+ fcount += 1 if mapped
271
+ fcount += 1 if jmapped
272
+ fcount += 1 if amapped
273
+ fcount += pkg.length if pkg
274
+
275
+ # setup the factory(s)
276
+ if fcount > 1
277
+ fct = SuperFactory.new do |f|
278
+ f << TypeFactory.new(mod,mapped) if mapped
279
+ f << AutoFactory.new(mod,amapped) if amapped
280
+ f << Cheri::Java::Builder::GenericBuilderFactory.new(mod,jmapped) if jmapped
281
+ pkg.each do |p|
282
+ f << Cheri::Java::Builder::PackageFactory.new(p,mod)
283
+ end if pkg
284
+ end
285
+ elsif mapped
286
+ fct = TypeFactory.new(mod,mapped)
287
+ elsif amapped
288
+ fct = AutoFactory.new(mod,amapped)
289
+ elsif jmapped
290
+ fct = Cheri::Java::Builder::GenericBuilderFactory.new(mod,jmapped)
291
+ elsif pkg
292
+ fct = Cheri::Java::Builder::PackageFactory.new(pkg.first,mod)
293
+ else
294
+ fct = nil
295
+ end
296
+ if fct
297
+ mod.instance_variable_set(:@fct,fct)
298
+ mod.const_set('Factory',fct)
299
+ end
300
+
301
+ # setup connecter
302
+ if tc
303
+ mod.instance_variable_set(:@ctr,tc)
304
+ mod.const_set('Connecter',tc)
305
+ end
306
+
307
+ # setup consumers - TODO: pkg builders?
308
+ if mapped || amapped || jmapped
309
+ if (amapped || mapped) && jmapped
310
+ cns = SuperConsumer[Cheri::Java::Builder::DefaultConsumer,Cheri::Builder::DefaultConsumer]
311
+ elsif amapped || mapped
312
+ cns = Cheri::Builder::DefaultConsumer
313
+ else
314
+ cns = Cheri::Java::Builder::DefaultConsumer
315
+ end
316
+ mod.instance_variable_set(:@cns,cns)
317
+ mod.const_set('Consumer',cns)
318
+ end
319
+
320
+ # setup extend builder, if any
321
+ ext ||= Cheri::Java::Builder if jmapped || pkg
322
+ if ext
323
+ mod.instance_variable_set(:@ext,ext)
324
+ mod.module_eval do
325
+ def self.extends
326
+ @ext
327
+ end
328
+ end
329
+ end
330
+ mod
331
+ end
332
+ private :create_mod
333
+
334
+ class EvalBuilder
335
+ keep = /^(__|=|<|>|class|to_s|eql\?|equal\?|inspect|instance_|respond_to\?)/
336
+ instance_methods.each do |m|
337
+ undef_method m unless m =~ keep
338
+ end
339
+
340
+ def initialize(*r,&k)
341
+ @__mapped = {}
342
+ @__unmapped = []
343
+ instance_eval(&k)
344
+ end
345
+
346
+ def __mapped
347
+ @__mapped
348
+ end
349
+
350
+ def __unmapped
351
+ @__unmapped
352
+ end
353
+
354
+ def __ext
355
+ @__ext
356
+ end
357
+
358
+ def __pkg
359
+ @__pkg
360
+ end
361
+
362
+ def __tc
363
+ @__tc
364
+ end
365
+
366
+ def extend_builder(bld)
367
+ return unless bld
368
+ raise BuilderException,"only one extend_builder may be specified" if @__ext
369
+ unless bld.respond_to?(:factory) || bld.respond_to?(:connecter) ||
370
+ bld.respond_to?(:consumer) || bld.respond_to?(:resolver)
371
+ raise ArgumentError,"not a valid builder: #{bld}"
372
+ end
373
+ @__ext = bld
374
+ end
375
+
376
+ def build(type,sym=nil)
377
+ raise Cheri.type_error(type,Class) unless Class === type
378
+ if sym
379
+ if Symbol === sym
380
+ add_mapped(type,sym)
381
+ elsif Array === sym
382
+ sym.each do |s|
383
+ raise Cheri.type_error(s,Symbol) unless Symbol === s
384
+ add_mapped(type,s)
385
+ end
386
+ else
387
+ raise Cheri.type_error(sym,Symbol,Array)
388
+ end
389
+ else
390
+ @__unmapped << type unless @__unmapped.include?(type)
391
+ end
392
+ end
393
+
394
+ def add_mapped(type,sym)
395
+ warn "warning: redefining :#{sym} from #{@__mapped[sym]} to #{type}" if @__mapped[sym]
396
+ @__mapped[sym] = type
397
+ end
398
+ private :add_mapped
399
+
400
+ def build_package(str)
401
+ raise Cheri.type_error(str,String) unless String === str
402
+ raise BuilderException,"packages supported only for Java (JRuby)" unless defined?JRUBY_VERSION
403
+ require 'cheri/java/builder'
404
+ if @__pkg
405
+ @__pkg << str unless @__pkg.include?(str)
406
+ else
407
+ @__pkg = [str]
408
+ end
409
+ end
410
+
411
+ def type(mod,&k)
412
+ @__tc ||= TypeConnecter.new
413
+ @__tc.type(mod,&k)
414
+ end
415
+ alias_method :types, :type
416
+ alias_method :symbol, :type
417
+ alias_method :symbols, :type
418
+
419
+
420
+ end #EvalBuilder
421
+
422
+ end #Generator
423
+
424
+ end #Builder
425
+ end #Cheri
@@ -0,0 +1,154 @@
1
+ #--
2
+ # Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ #
24
+
25
+ module Cheri
26
+ module Html
27
+ module Charsets
28
+ SPECIAL = /[\000-\010\013\014\016-\037\046\074\076\200-\377]/
29
+ HIBYTES = /[\200-\377]/
30
+ class << self
31
+ def special?(str)
32
+ str =~ SPECIAL
33
+ end
34
+ # Returns a Charset if +str+ requires translation, else +nil+
35
+ def charset(str)
36
+ return nil unless str =~ SPECIAL
37
+ if str =~ HIBYTES
38
+ Utf8.detect?(str) ? Utf8 : Win1252
39
+ else
40
+ Iso8859
41
+ end
42
+ end
43
+ end #self
44
+ module Charset
45
+ def xlat(i,o)
46
+ m = @map
47
+ i.each_byte do |b| o << m[b]; end
48
+ end
49
+ def map
50
+ @map
51
+ end
52
+ end
53
+
54
+ module Win1252
55
+ extend Charset
56
+ @map = Array.new(256)
57
+ map = @map
58
+ 0.upto(31) do |i| map[i] = 32; end
59
+ map[9] = ?\t
60
+ map[10] = ?\n
61
+ map[13] = ?\r
62
+ 32.upto(127) do |i| map[i] = i; end
63
+ map[38] = '&amp;'
64
+ map[60] = '&lt;'
65
+ map[62] = '&gt;'
66
+ # windows-1252 mappings
67
+ map[128] = '&euro;'
68
+ map[129] = '?' #undefined
69
+ map[130] = '&sbquo;'
70
+ map[131] = '&fnof;'
71
+ map[132] = '&bdquo;'
72
+ map[133] = '&hellip;'
73
+ map[134] = '&dagger;'
74
+ map[135] = '&Dagger;'
75
+ map[136] = '&circ;'
76
+ map[137] = '&permil;'
77
+ map[138] = '&Scaron;'
78
+ map[139] = '&lsaquo;'
79
+ map[140] = '&OElig;'
80
+ map[141] = '?' #undefined
81
+ map[142] = '&#x17D;'
82
+ map[143] = '?' #undefined
83
+ map[144] = '?' #undefined
84
+ map[145] = '&lsquo;'
85
+ map[146] = '&rsquo;'
86
+ map[147] = '&ldquo;'
87
+ map[148] = '&rdquo;'
88
+ map[149] = '&bull;'
89
+ map[150] = '&ndash;'
90
+ map[151] = '&mdash;'
91
+ map[152] = '&tilde;'
92
+ map[153] = '&trade;'
93
+ map[154] = '&scaron;'
94
+ map[155] = '&rsaquo;'
95
+ map[156] = '&oelig;'
96
+ map[157] = '?' #undefined
97
+ map[158] = '&#x17E;'
98
+ map[159] = '&Yuml;'
99
+ # 160-255 same for windows-1252 & ISO 8859-1 (Latin-1)
100
+ 160.upto(255) do |i| map[i] = "&##{i};"; end
101
+ end
102
+
103
+ module Iso8859
104
+ extend Charset
105
+ # using same map for windows-1252 & ISO 8859-1, since the
106
+ # only detectable difference is use of 0x80-0x9f
107
+ @map = Win1252.map
108
+ end
109
+
110
+ module Utf8
111
+ extend Charset
112
+
113
+ # TODO: not quite correct for EO, F0, F4 ?
114
+ def self.detect?(str)
115
+ d = @detect
116
+ ct = 0
117
+ begin
118
+ str.each_byte do |b|
119
+ if b < 128
120
+ return false if ct > 0
121
+ elsif b < 192
122
+ return false if (ct -= 1) < 0
123
+ else
124
+ return false unless ct == 0
125
+ ct += d[b]
126
+ end
127
+ end
128
+ ct == 0
129
+ rescue
130
+ false
131
+ end
132
+ end
133
+
134
+ @map = Array.new(256)
135
+ map = @map
136
+ 0.upto(31) do |i| map[i] = 32; end
137
+ map[9] = ?\t
138
+ map[10] = ?\n
139
+ map[13] = ?\r
140
+ 32.upto(255) do |i| map[i] = i; end
141
+ map[38] = '&amp;'
142
+ map[60] = '&lt;'
143
+ map[62] = '&gt;'
144
+
145
+ @detect = Array.new(256)
146
+ det = @detect
147
+ 0x80.upto(0xBF) do |i| det[i] = -1; end
148
+ 0xC2.upto(0xDF) do |i| det[i] = 1; end
149
+ 0xE0.upto(0xEF) do |i| det[i] = 2; end
150
+ 0xF0.upto(0xF4) do |i| det[i] = 3; end
151
+ end
152
+ end #Charsets
153
+ end #Html
154
+ end #Cheri