ahoward-tagz 5.1.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -58,17 +58,15 @@ RAILS
58
58
 
59
59
  in a view
60
60
 
61
- <%=
62
- table_{
63
- rows.each do |row|
64
- tr_{
65
- row.each do |cell|
66
- td_{ cell }
67
- end
68
- }
69
- end
70
- }
71
- %>
61
+ table_{
62
+ rows.each do |row|
63
+ tr_{
64
+ row.each do |cell|
65
+ td_{ cell }
66
+ end
67
+ }
68
+ end
69
+ }
72
70
 
73
71
  in a controller
74
72
 
@@ -99,6 +97,12 @@ URIS
99
97
  http://rubyforge.org/projects/codeforpeople
100
98
 
101
99
  HISTORY
100
+ 6.0.0
101
+ - reorganize lib to avoid dumping a few constants into the includee - aka
102
+ don't absolutely minimize namespace pollution. there is now reason to
103
+ thing this version shouldn't be backwards compat - i bumped the version
104
+ just in case
105
+
102
106
  5.1.0
103
107
  - attribute/content auto-escaping can be turned off with
104
108
 
@@ -147,241 +151,4 @@ HISTORY
147
151
 
148
152
  SAMPLES
149
153
 
150
- <========< samples/a.rb >========>
151
-
152
- ~ > cat samples/a.rb
153
-
154
- #
155
- # in the simplest case tagz generates html using a syntax which safely mixes
156
- # in to any object
157
- #
158
-
159
- require 'tagz'
160
- include Tagz.globally
161
-
162
- class GiraffeModel
163
- def link
164
- a_(:href => "/giraffe/neck/42"){ "whack!" }
165
- end
166
- end
167
-
168
- puts GiraffeModel.new.link
169
-
170
- ~ > ruby samples/a.rb
171
-
172
- <a href="/giraffe/neck/42">whack!</a>
173
-
174
-
175
- <========< samples/b.rb >========>
176
-
177
- ~ > cat samples/b.rb
178
-
179
- #
180
- # tagz.rb mixes quite easily with your favourite templating engine, avoiding
181
- # the need for '<% rows.each do |row| %> ... <% row.each do |cell| %> '
182
- # madness and other types of logic to be coded in the templating language,
183
- # leaving templating to template engines and logic and looping to ruby -
184
- # unencumbered by extra funky syntax. in rails tagz will automatically be
185
- # available in your erb templates.
186
- #
187
-
188
- require 'tagz'
189
- include Tagz.globally
190
-
191
- require 'erb'
192
-
193
- rows = %w( a b c ), %w( 1 2 3 )
194
-
195
- template = ERB.new <<-ERB
196
- <html>
197
- <body>
198
- <%=
199
- table_{
200
- rows.each do |row|
201
- tr_{
202
- row.each do |cell|
203
- td_{ cell }
204
- end
205
- }
206
- end
207
- }
208
- %>
209
- </body>
210
- </html>
211
- ERB
212
-
213
- puts template.result(binding)
214
-
215
-
216
- ~ > ruby samples/b.rb
217
-
218
- <html>
219
- <body>
220
- <table><tr><td>a</td><td>b</td><td>c</td></tr><tr><td>1</td><td>2</td><td>3</td></tr></table>
221
- </body>
222
- </html>
223
-
224
-
225
- <========< samples/c.rb >========>
226
-
227
- ~ > cat samples/c.rb
228
-
229
- #
230
- # once you've learned to generate html using tagz you're primed to generate
231
- # xml too
232
- #
233
-
234
- require 'tagz'
235
- include Tagz.globally
236
-
237
- doc =
238
- xml_{
239
- giraffe_{ 'large' }
240
- ninja_{ 'small' }
241
- }
242
-
243
- puts doc
244
-
245
- ~ > ruby samples/c.rb
246
-
247
- <xml><giraffe>large</giraffe><ninja>small</ninja></xml>
248
-
249
-
250
- <========< samples/d.rb >========>
251
-
252
- ~ > cat samples/d.rb
253
-
254
- #
255
- # tagz.rb doesn't cramp your style, allowing even invalid html to be
256
- # generated. note the use of the 'tagz' method, which can be used both to
257
- # capture output and to append content to the top of the stack.
258
- #
259
-
260
- require 'tagz'
261
- include Tagz.globally
262
-
263
- def header
264
- tagz{
265
- html_
266
- body_(:class => 'ninja-like', :id => 'giraffe-slayer')
267
-
268
- __ "<!-- this is the header -->"
269
- }
270
- end
271
-
272
- def footer
273
- tagz{
274
- __ "<!-- this is the footer -->"
275
-
276
- _body
277
- _html
278
- }
279
- end
280
-
281
- puts header, footer
282
-
283
- ~ > ruby samples/d.rb
284
-
285
- <html><body class="ninja-like" id="giraffe-slayer">
286
- <!-- this is the header -->
287
-
288
- <!-- this is the footer -->
289
- </body></html>
290
-
291
-
292
- <========< samples/e.rb >========>
293
-
294
- ~ > cat samples/e.rb
295
-
296
- #
297
- # tagz.rb allows a safer method of mixin which requires any tagz methods to be
298
- # insider a tagz block - tagz generating methods outside a tagz block with
299
- # raise an error if tagz is included this way. also notice that the error is
300
- # reported from where it was raised - not from the bowels of the the tagz.rb
301
- # lib.
302
- #
303
-
304
- require 'tagz'
305
- include Tagz
306
-
307
- puts tagz{
308
- html_{ 'works only in here' }
309
- }
310
-
311
- begin
312
- html_{ 'not out here' }
313
- rescue Object => e
314
- p :backtrace => e.backtrace
315
- end
316
-
317
-
318
- ~ > ruby samples/e.rb
319
-
320
- <html>works only in here</html>
321
- {:backtrace=>["samples/e.rb:17"]}
322
-
323
-
324
- <========< samples/f.rb >========>
325
-
326
- ~ > cat samples/f.rb
327
-
328
- #
329
- # tagz.rb can generate really compact html. this is great to save bandwidth
330
- # but can sometimes make reading the generated html a bit rough. of course
331
- # using tidy or the dom inspector in firebug obviates the issue; nevertheless
332
- # it's sometime nice to break things up a little. you can use 'tagz << "\n"'
333
- # or the special shorthand '__' or '___' to accomplish this
334
- #
335
-
336
- require 'tagz'
337
- include Tagz.globally
338
-
339
- html =
340
- div_{
341
- span_{ true }
342
- __
343
- span_{ false } # hey ryan, i fixed this ;-)
344
- ___
345
-
346
- ___ 'foo & escaped bar'
347
- }
348
-
349
- puts html
350
-
351
- ~ > ruby samples/f.rb
352
-
353
- <div><span>true</span>
354
- <span>false</span>
355
-
356
- foo & escaped bar
357
- </div>
358
-
359
-
360
- <========< samples/g.rb >========>
361
-
362
- ~ > cat samples/g.rb
363
-
364
- # tagz gives you low-level control of the output and makes even dashersized
365
- # xml tagz easy enough to work with
366
- #
367
-
368
- require 'tagz'
369
- include Tagz.globally
370
-
371
- xml =
372
- root_{
373
- tagz__('foo-bar', :key => 'foo&bar'){ 'content' }
374
-
375
- tagz__('bar-foo')
376
- tagz.concat 'content'
377
- tagz.concat tagz.escape('foo&bar')
378
- __tagz('bar-foo')
379
- }
380
-
381
- puts xml
382
-
383
-
384
- ~ > ruby samples/g.rb
385
-
386
- <root><foo-bar key="foo&amp;bar">content</foo-bar><bar-foo>contentfoo&amp;amp;bar</bar-foo></root>
387
-
154
+
@@ -0,0 +1,228 @@
1
+
2
+ This.rubyforge_project = 'codeforpeople'
3
+ This.author = "Ara T. Howard"
4
+ This.email = "ara.t.howard@gmail.com"
5
+ This.homepage = "http://github.com/ahoward/#{ This.lib }/tree/master"
6
+
7
+
8
+ task :default do
9
+ puts(Rake::Task.tasks.map{|task| task.name} - ['default'])
10
+ end
11
+
12
+
13
+ task :gemspec do
14
+ ignore_extensions = 'git', 'svn', 'tmp', /sw./, 'bak', 'gem'
15
+ ignore_directories = 'pkg'
16
+ ignore_files = 'test/log'
17
+
18
+ shiteless =
19
+ lambda do |list|
20
+ list.delete_if do |entry|
21
+ next unless test(?e, entry)
22
+ extension = File.basename(entry).split(%r/[.]/).last
23
+ ignore_extensions.any?{|ext| ext === extension}
24
+ end
25
+ list.delete_if do |entry|
26
+ next unless test(?d, entry)
27
+ dirname = File.expand_path(entry)
28
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
29
+ end
30
+ list.delete_if do |entry|
31
+ next unless test(?f, entry)
32
+ filename = File.expand_path(entry)
33
+ ignore_files.any?{|file| File.expand_path(file) == filename}
34
+ end
35
+ end
36
+
37
+ lib = This.lib
38
+ version = This.version
39
+ files = shiteless[Dir::glob("**/**")]
40
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
41
+ has_rdoc = true #File.exist?('doc')
42
+ test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
43
+
44
+ extensions = This.extensions
45
+ if extensions.nil?
46
+ %w( Makefile configure extconf.rb ).each do |ext|
47
+ extensions << ext if File.exists?(ext)
48
+ end
49
+ end
50
+ extensions = [extensions].flatten.compact
51
+
52
+ template =
53
+ if test(?e, 'gemspec.erb')
54
+ Template{ IO.read('gemspec.erb') }
55
+ else
56
+ Template {
57
+ <<-__
58
+ ## #{ lib }.gemspec
59
+ #
60
+
61
+ Gem::Specification::new do |spec|
62
+ spec.name = #{ lib.inspect }
63
+ spec.version = #{ version.inspect }
64
+ spec.platform = Gem::Platform::RUBY
65
+ spec.summary = #{ lib.inspect }
66
+
67
+ spec.files = #{ files.inspect }
68
+ spec.executables = #{ executables.inspect }
69
+
70
+ spec.require_path = "lib"
71
+
72
+ spec.has_rdoc = #{ has_rdoc.inspect }
73
+ spec.test_files = #{ test_files.inspect }
74
+ #spec.add_dependency 'lib', '>= version'
75
+ #spec.add_dependency 'fattr'
76
+
77
+ spec.extensions.push(*#{ extensions.inspect })
78
+
79
+ spec.rubyforge_project = #{ This.rubyforge_project.inspect }
80
+ spec.author = #{ This.author.inspect }
81
+ spec.email = #{ This.email.inspect }
82
+ spec.homepage = #{ This.homepage.inspect }
83
+ end
84
+ __
85
+ }
86
+ end
87
+
88
+ open("#{ lib }.gemspec", "w"){|fd| fd.puts template}
89
+ This.gemspec = "#{ lib }.gemspec"
90
+ end
91
+
92
+ task :gem => [:clean, :gemspec] do
93
+ Fu.mkdir_p This.pkgdir
94
+ before = Dir['*.gem']
95
+ cmd = "gem build #{ This.gemspec }"
96
+ `#{ cmd }`
97
+ after = Dir['*.gem']
98
+ gem = ((after - before).first || after.first) or abort('no gem!')
99
+ Fu.mv gem, This.pkgdir
100
+ This.gem = File.basename(gem)
101
+ end
102
+
103
+ task :readme do
104
+ samples = ''
105
+ prompt = '~ > '
106
+ lib = This.lib
107
+ version = This.version
108
+
109
+ Dir['sample*/*'].sort.each do |sample|
110
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
111
+
112
+ cmd = "cat #{ sample }"
113
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
114
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
115
+
116
+ cmd = "ruby #{ sample }"
117
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
118
+
119
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
120
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
121
+ end
122
+
123
+ template =
124
+ if test(?e, 'readme.erb')
125
+ Template{ IO.read('readme.erb') }
126
+ else
127
+ Template {
128
+ <<-__
129
+ NAME
130
+ #{ lib }
131
+
132
+ DESCRIPTION
133
+
134
+ INSTALL
135
+ gem install #{ lib }
136
+
137
+ SAMPLES
138
+ #{ samples }
139
+ __
140
+ }
141
+ end
142
+
143
+ open("README", "w"){|fd| fd.puts template}
144
+ end
145
+
146
+
147
+ task :clean do
148
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
149
+ end
150
+
151
+
152
+ task :release => [:clean, :gemspec, :gem] do
153
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
154
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
155
+ raise "no gems?" if gems.size < 1
156
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.pkgdir }/#{ This.gem }"
157
+ puts cmd
158
+ system cmd
159
+ end
160
+
161
+
162
+
163
+
164
+
165
+ BEGIN {
166
+ $VERBOSE = nil
167
+
168
+ require 'ostruct'
169
+ require 'erb'
170
+ require 'fileutils'
171
+
172
+ Fu = FileUtils
173
+
174
+ This = OpenStruct.new
175
+
176
+ This.file = File.expand_path(__FILE__)
177
+ This.dir = File.dirname(This.file)
178
+ This.pkgdir = File.join(This.dir, 'pkg')
179
+
180
+ lib = ENV['LIB']
181
+ unless lib
182
+ lib = File.basename(Dir.pwd)
183
+ end
184
+ This.lib = lib
185
+
186
+ version = ENV['VERSION']
187
+ unless version
188
+ name = lib.capitalize
189
+ require "./lib/#{ lib }"
190
+ version = eval(name).send(:version)
191
+ end
192
+ This.version = version
193
+
194
+ abort('no lib') unless This.lib
195
+ abort('no version') unless This.version
196
+
197
+ module Util
198
+ def indent(s, n = 2)
199
+ s = unindent(s)
200
+ ws = ' ' * n
201
+ s.gsub(%r/^/, ws)
202
+ end
203
+
204
+ def unindent(s)
205
+ indent = nil
206
+ s.each do |line|
207
+ next if line =~ %r/^\s*$/
208
+ indent = line[%r/^\s*/] and break
209
+ end
210
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
211
+ end
212
+ extend self
213
+ end
214
+
215
+ class Template
216
+ def initialize(&block)
217
+ @block = block
218
+ @template = block.call.to_s
219
+ end
220
+ def expand(b=nil)
221
+ ERB.new(Util.unindent(@template)).result(b||@block)
222
+ end
223
+ alias_method 'to_s', 'expand'
224
+ end
225
+ def Template(*args, &block) Template.new(*args, &block) end
226
+
227
+ Dir.chdir(This.dir)
228
+ }
@@ -1,14 +1,7 @@
1
1
  unless defined? Tagz
2
2
 
3
3
  module Tagz
4
- unless defined?(Tagz::VERSION)
5
- Tagz::VERSION = [
6
- Tagz::VERSION_MAJOR = 5,
7
- Tagz::VERSION_MINOR = 1,
8
- Tagz::VERSION_TEENY = 0
9
- ].join('.')
10
- def Tagz.version() Tagz::VERSION end
11
- end
4
+ def Tagz.version() '6.0.0' end
12
5
 
13
6
  private
14
7
 
@@ -141,176 +134,16 @@ unless defined? Tagz
141
134
  end
142
135
  end
143
136
 
144
- class Document < ::String
145
- def Document.for other
146
- Document === other ? other : Document.new(other.to_s)
147
- end
148
-
149
- def element
150
- Element.new(*a, &b)
151
- end
152
- alias_method 'e', 'element'
153
-
154
- alias_method 'write', 'concat'
155
- alias_method 'push', 'concat'
156
-
157
- def << string
158
- case string
159
- when Document
160
- super string.to_s
161
- else
162
- super Tagz.escape_content(string)
163
- end
164
- self
165
- end
166
- def concat string
167
- self << string
168
- end
169
- #alias_method 'concat', '<<'
170
-
171
- def escape(*strings)
172
- XChar.escape(strings.join)
173
- end
174
- alias_method 'h', 'escape'
175
-
176
- def puts string
177
- write "#{ string }\n"
178
- end
179
-
180
- def document
181
- self
182
- end
183
- alias_method 'doc', 'document'
184
-
185
- def + other
186
- self.dup << other
187
- end
188
-
189
- def to_s
190
- self
191
- end
192
-
193
- def to_str
194
- self
195
- end
196
- end
197
-
198
- class Element < ::String
199
- def Element.attributes options
200
- unless options.empty?
201
- ' ' <<
202
- options.map do |key, value|
203
- key = Tagz.escape_attribute(key)
204
- value = Tagz.escape_attribute(value)
205
- if value =~ %r/"/
206
- raise ArgumentError, value if value =~ %r/'/
207
- value = "'#{ value }'"
208
- else
209
- raise ArgumentError, value if value =~ %r/"/
210
- value = "\"#{ value }\""
211
- end
212
- [key, value].join('=')
213
- end.join(' ')
214
- else
215
- ''
216
- end
217
- end
218
-
219
- attr 'name'
220
-
221
- def initialize name, *argv, &block
222
- options = {}
223
- content = []
224
-
225
- argv.each do |arg|
226
- case arg
227
- when Hash
228
- options.update arg
229
- else
230
- content.push arg
231
- end
232
- end
233
-
234
- content.push block.call if block
235
- content.compact!
236
-
237
- @name = name.to_s
238
-
239
- if content.empty?
240
- replace "<#{ @name }#{ Element.attributes options }>"
241
- else
242
- replace "<#{ @name }#{ Element.attributes options }>#{ content.join }</#{ name }>"
243
- end
244
- end
245
- end
246
-
247
- module XChar
248
- # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
249
- #
250
- CP1252 = {
251
- 128 => 8364, # euro sign
252
- 130 => 8218, # single low-9 quotation mark
253
- 131 => 402, # latin small letter f with hook
254
- 132 => 8222, # double low-9 quotation mark
255
- 133 => 8230, # horizontal ellipsis
256
- 134 => 8224, # dagger
257
- 135 => 8225, # double dagger
258
- 136 => 710, # modifier letter circumflex accent
259
- 137 => 8240, # per mille sign
260
- 138 => 352, # latin capital letter s with caron
261
- 139 => 8249, # single left-pointing angle quotation mark
262
- 140 => 338, # latin capital ligature oe
263
- 142 => 381, # latin capital letter z with caron
264
- 145 => 8216, # left single quotation mark
265
- 146 => 8217, # right single quotation mark
266
- 147 => 8220, # left double quotation mark
267
- 148 => 8221, # right double quotation mark
268
- 149 => 8226, # bullet
269
- 150 => 8211, # en dash
270
- 151 => 8212, # em dash
271
- 152 => 732, # small tilde
272
- 153 => 8482, # trade mark sign
273
- 154 => 353, # latin small letter s with caron
274
- 155 => 8250, # single right-pointing angle quotation mark
275
- 156 => 339, # latin small ligature oe
276
- 158 => 382, # latin small letter z with caron
277
- 159 => 376} # latin capital letter y with diaeresis
278
-
279
- # http://www.w3.org/TR/REC-xml/#dt-chardata
280
- #
281
- PREDEFINED = {
282
- 38 => '&amp;', # ampersand
283
- 60 => '&lt;', # left angle bracket
284
- 62 => '&gt;'} # right angle bracket
285
-
286
- # http://www.w3.org/TR/REC-xml/#charsets
287
- #
288
- VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF), (0xE000..0xFFFD), (0x10000..0x10FFFF)]
289
-
290
- def XChar.escape(string)
291
- string.unpack('U*').map{|n| xchr(n)}.join # ASCII, UTF-8
292
- rescue
293
- string.unpack('C*').map{|n| xchr(n)}.join # ISO-8859-1, WIN-1252
294
- end
295
-
296
- def XChar.xchr(n)
297
- (@xchr ||= {})[n] ||= ((
298
- n = XChar::CP1252[n] || n
299
- n = 42 unless XChar::VALID.find{|range| range.include? n}
300
- XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
301
- ))
302
- end
303
- end
304
-
137
+ # escape support
138
+ #
305
139
  def Tagz.escapeHTML(*strings)
306
140
  XChar.escape(strings.join)
307
141
  end
142
+
308
143
  def Tagz.escape(*strings)
309
144
  XChar.escape(strings.join)
310
145
  end
311
146
 
312
- NoEscape = lambda{|v|v}
313
-
314
147
  # support for configuring attribute escaping
315
148
  #
316
149
  def Tagz.escape_attribute!(*args, &block)
@@ -373,16 +206,191 @@ unless defined? Tagz
373
206
  escape_content!{|value| XChar.escape(value)}
374
207
  end
375
208
 
376
- module Globally; include Tagz; end
377
209
  def Tagz.globally
378
210
  Globally
379
211
  end
380
212
 
381
- module Privately; include Tagz; end
382
213
  def Tagz.privately
383
214
  Privately
384
215
  end
385
216
 
217
+ # hide away our own shit to minimize pollution
218
+ #
219
+ module TagzConstants
220
+ class Document < ::String
221
+ def Document.for other
222
+ Document === other ? other : Document.new(other.to_s)
223
+ end
224
+
225
+ def element
226
+ Element.new(*a, &b)
227
+ end
228
+ alias_method 'e', 'element'
229
+
230
+ alias_method 'write', 'concat'
231
+ alias_method 'push', 'concat'
232
+
233
+ def << string
234
+ case string
235
+ when Document
236
+ super string.to_s
237
+ else
238
+ super Tagz.escape_content(string)
239
+ end
240
+ self
241
+ end
242
+ def concat string
243
+ self << string
244
+ end
245
+ #alias_method 'concat', '<<'
246
+
247
+ def escape(*strings)
248
+ XChar.escape(strings.join)
249
+ end
250
+ alias_method 'h', 'escape'
251
+
252
+ def puts string
253
+ write "#{ string }\n"
254
+ end
255
+
256
+ def document
257
+ self
258
+ end
259
+ alias_method 'doc', 'document'
260
+
261
+ def + other
262
+ self.dup << other
263
+ end
264
+
265
+ def to_s
266
+ self
267
+ end
268
+
269
+ def to_str
270
+ self
271
+ end
272
+ end
273
+
274
+ class Element < ::String
275
+ def Element.attributes options
276
+ unless options.empty?
277
+ ' ' <<
278
+ options.map do |key, value|
279
+ key = Tagz.escape_attribute(key)
280
+ value = Tagz.escape_attribute(value)
281
+ if value =~ %r/"/
282
+ raise ArgumentError, value if value =~ %r/'/
283
+ value = "'#{ value }'"
284
+ else
285
+ raise ArgumentError, value if value =~ %r/"/
286
+ value = "\"#{ value }\""
287
+ end
288
+ [key, value].join('=')
289
+ end.join(' ')
290
+ else
291
+ ''
292
+ end
293
+ end
294
+
295
+ attr 'name'
296
+
297
+ def initialize name, *argv, &block
298
+ options = {}
299
+ content = []
300
+
301
+ argv.each do |arg|
302
+ case arg
303
+ when Hash
304
+ options.update arg
305
+ else
306
+ content.push arg
307
+ end
308
+ end
309
+
310
+ content.push block.call if block
311
+ content.compact!
312
+
313
+ @name = name.to_s
314
+
315
+ if content.empty?
316
+ replace "<#{ @name }#{ Element.attributes options }>"
317
+ else
318
+ replace "<#{ @name }#{ Element.attributes options }>#{ content.join }</#{ name }>"
319
+ end
320
+ end
321
+ end
322
+
323
+ module XChar
324
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
325
+ #
326
+ CP1252 = {
327
+ 128 => 8364, # euro sign
328
+ 130 => 8218, # single low-9 quotation mark
329
+ 131 => 402, # latin small letter f with hook
330
+ 132 => 8222, # double low-9 quotation mark
331
+ 133 => 8230, # horizontal ellipsis
332
+ 134 => 8224, # dagger
333
+ 135 => 8225, # double dagger
334
+ 136 => 710, # modifier letter circumflex accent
335
+ 137 => 8240, # per mille sign
336
+ 138 => 352, # latin capital letter s with caron
337
+ 139 => 8249, # single left-pointing angle quotation mark
338
+ 140 => 338, # latin capital ligature oe
339
+ 142 => 381, # latin capital letter z with caron
340
+ 145 => 8216, # left single quotation mark
341
+ 146 => 8217, # right single quotation mark
342
+ 147 => 8220, # left double quotation mark
343
+ 148 => 8221, # right double quotation mark
344
+ 149 => 8226, # bullet
345
+ 150 => 8211, # en dash
346
+ 151 => 8212, # em dash
347
+ 152 => 732, # small tilde
348
+ 153 => 8482, # trade mark sign
349
+ 154 => 353, # latin small letter s with caron
350
+ 155 => 8250, # single right-pointing angle quotation mark
351
+ 156 => 339, # latin small ligature oe
352
+ 158 => 382, # latin small letter z with caron
353
+ 159 => 376} # latin capital letter y with diaeresis
354
+
355
+ # http://www.w3.org/TR/REC-xml/#dt-chardata
356
+ #
357
+ PREDEFINED = {
358
+ 38 => '&amp;', # ampersand
359
+ 60 => '&lt;', # left angle bracket
360
+ 62 => '&gt;'} # right angle bracket
361
+
362
+ # http://www.w3.org/TR/REC-xml/#charsets
363
+ #
364
+ VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF), (0xE000..0xFFFD), (0x10000..0x10FFFF)]
365
+
366
+ def XChar.escape(string)
367
+ string.unpack('U*').map{|n| xchr(n)}.join # ASCII, UTF-8
368
+ rescue
369
+ string.unpack('C*').map{|n| xchr(n)}.join # ISO-8859-1, WIN-1252
370
+ end
371
+
372
+ def XChar.xchr(n)
373
+ (@xchr ||= {})[n] ||= ((
374
+ n = XChar::CP1252[n] || n
375
+ n = 42 unless XChar::VALID.find{|range| range.include? n}
376
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
377
+ ))
378
+ end
379
+ end
380
+
381
+ NoEscape = lambda{|v|v}
382
+
383
+ module Globally; include ::Tagz; end
384
+ module Privately; include ::Tagz; end
385
+ end
386
+
387
+ # const_missing support
388
+ #
389
+ def Tagz.const_missing(const)
390
+ super unless TagzConstants.const_defined?(const)
391
+ TagzConstants.const_get(const)
392
+ end
393
+
386
394
  %w( tagz tagz__ __tagz method_missing ).each{|m| module_function(m)}
387
395
  end
388
396
 
@@ -58,17 +58,15 @@ RAILS
58
58
 
59
59
  in a view
60
60
 
61
- <%=
62
- table_{
63
- rows.each do |row|
64
- tr_{
65
- row.each do |cell|
66
- td_{ cell }
67
- end
68
- }
69
- end
70
- }
71
- %>
61
+ table_{
62
+ rows.each do |row|
63
+ tr_{
64
+ row.each do |cell|
65
+ td_{ cell }
66
+ end
67
+ }
68
+ end
69
+ }
72
70
 
73
71
  in a controller
74
72
 
@@ -99,6 +97,12 @@ URIS
99
97
  http://rubyforge.org/projects/codeforpeople
100
98
 
101
99
  HISTORY
100
+ 6.0.0
101
+ - reorganize lib to avoid dumping a few constants into the includee - aka
102
+ don't absolutely minimize namespace pollution. there is now reason to
103
+ thing this version shouldn't be backwards compat - i bumped the version
104
+ just in case
105
+
102
106
  5.1.0
103
107
  - attribute/content auto-escaping can be turned off with
104
108
 
@@ -147,4 +151,4 @@ HISTORY
147
151
 
148
152
  SAMPLES
149
153
 
150
- @samples
154
+ <%= @samples %>
@@ -1,25 +1,26 @@
1
+ ## tagz.gemspec
2
+ #
1
3
 
2
- Gem::Specification::new do |spec|
3
- spec.name = "tagz"
4
- spec.version = "5.1.0"
5
- spec.platform = Gem::Platform::RUBY
6
- spec.summary = "tagz"
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "tagz"
6
+ spec.version = "6.0.0"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "tagz"
7
9
 
8
- spec.files = ["gen_readme.rb", "install.rb", "lib", "lib/tagz.rb", "README", "README.tmpl", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb", "samples/d.rb", "samples/e.rb", "samples/f.rb", "samples/g.rb", "tagz-5.1.0.gem", "tagz.gemspec", "test", "test/tagz.rb"]
9
- spec.executables = []
10
-
11
- spec.require_path = "lib"
10
+ spec.files = ["lib", "lib/tagz.rb", "Rakefile", "README", "readme.erb", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb", "samples/d.rb", "samples/e.rb", "samples/f.rb", "samples/g.rb", "tagz.gemspec", "test", "test/tagz.rb"]
11
+ spec.executables = []
12
+
13
+ spec.require_path = "lib"
12
14
 
13
- spec.has_rdoc = true
14
- spec.test_files = "test/tagz.rb"
15
- #spec.add_dependency 'lib', '>= version'
16
- #spec.add_dependency 'fattr'
15
+ spec.has_rdoc = true
16
+ spec.test_files = "test/tagz.rb"
17
+ #spec.add_dependency 'lib', '>= version'
18
+ #spec.add_dependency 'fattr'
17
19
 
18
- spec.extensions.push(*[])
19
-
20
- spec.rubyforge_project = 'codeforpeople'
21
- spec.author = "Ara T. Howard"
22
- spec.email = "ara.t.howard@gmail.com"
23
- spec.homepage = "http://github.com/ahoward/tagz/tree/master"
24
- end
20
+ spec.extensions.push(*[])
25
21
 
22
+ spec.rubyforge_project = "codeforpeople"
23
+ spec.author = "Ara T. Howard"
24
+ spec.email = "ara.t.howard@gmail.com"
25
+ spec.homepage = "http://github.com/ahoward/tagz/tree/master"
26
+ end
@@ -668,4 +668,40 @@ class TagzTest < Test::Unit::TestCase
668
668
  expected = "<div>\na&gt;b\nc>d\ne&gt;f\ng>h</div>"
669
669
  assert_equal expected, actual
670
670
  end
671
+
672
+ def test_500
673
+ expected = actual = nil
674
+ Module.new do
675
+ before = constants
676
+ include Tagz
677
+ after = constants
678
+ expected = %w[ TagzConstants ]
679
+ actual = after - before
680
+ end
681
+ assert_equal expected, actual
682
+ end
683
+
684
+ def test_510
685
+ expected = actual = nil
686
+ Module.new do
687
+ before = constants
688
+ include Tagz.globally
689
+ after = constants
690
+ expected = %w[ TagzConstants ]
691
+ actual = after - before
692
+ end
693
+ assert_equal expected, actual
694
+ end
695
+
696
+ def test_520
697
+ expected = actual = nil
698
+ Module.new do
699
+ before = constants
700
+ include Tagz.privately
701
+ after = constants
702
+ expected = %w[ TagzConstants ]
703
+ actual = after - before
704
+ end
705
+ assert_equal expected, actual
706
+ end
671
707
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoward-tagz
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ara T. Howard
@@ -22,12 +22,11 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
- - gen_readme.rb
26
- - install.rb
27
25
  - lib
28
26
  - lib/tagz.rb
27
+ - Rakefile
29
28
  - README
30
- - README.tmpl
29
+ - readme.erb
31
30
  - samples
32
31
  - samples/a.rb
33
32
  - samples/b.rb
@@ -36,7 +35,6 @@ files:
36
35
  - samples/e.rb
37
36
  - samples/f.rb
38
37
  - samples/g.rb
39
- - tagz-5.1.0.gem
40
38
  - tagz.gemspec
41
39
  - test
42
40
  - test/tagz.rb
@@ -1,34 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- require 'pathname'
4
-
5
- $VERBOSE=nil
6
-
7
- def indent s, n = 2
8
- ws = ' ' * n
9
- s.gsub %r/^/, ws
10
- end
11
-
12
- template = IO::read 'README.tmpl'
13
-
14
- samples = ''
15
- prompt = '~ > '
16
-
17
- Dir['sample*/*'].sort.each do |sample|
18
- samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
19
-
20
- cmd = "cat #{ sample }"
21
- samples << indent(prompt + cmd, 2) << "\n\n"
22
- samples << indent(`#{ cmd }`, 4) << "\n"
23
-
24
- cmd = "ruby #{ sample }"
25
- samples << indent(prompt + cmd, 2) << "\n\n"
26
-
27
- cmd = "ruby -Ilib #{ sample }"
28
- samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
29
- end
30
-
31
- #samples.gsub! %r/^/, ' '
32
-
33
- readme = template.gsub %r/^\s*@samples\s*$/, samples
34
- print readme
data/install.rb DELETED
@@ -1,214 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rbconfig'
3
- require 'find'
4
- require 'ftools'
5
- require 'tempfile'
6
- include Config
7
-
8
- LIBDIR = "lib"
9
- LIBDIR_MODE = 0644
10
-
11
- BINDIR = "bin"
12
- BINDIR_MODE = 0755
13
-
14
-
15
- $srcdir = CONFIG["srcdir"]
16
- $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
- $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
- $archdir = File.join($libdir, CONFIG["arch"])
19
- $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
- $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
- $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
- $ruby_ext = CONFIG['EXEEXT'] || ''
23
- $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
-
25
- if !$site_libdir
26
- $site_libdir = File.join($libdir, "site_ruby")
27
- elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
- $site_libdir = File.join($site_libdir, $version)
29
- end
30
-
31
- def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
- #{{{
33
- path = []
34
- dir = []
35
- Find.find(srcdir) do |f|
36
- next unless FileTest.file?(f)
37
- next if (f = f[srcdir.length+1..-1]) == nil
38
- next if (/CVS$/ =~ File.dirname(f))
39
- next if (/\.svn/ =~ File.dirname(f))
40
- next if f =~ %r/\.lnk/
41
- next if f =~ %r/\.svn/
42
- next if f =~ %r/\.swp/
43
- next if f =~ %r/\.svn/
44
- path.push f
45
- dir |= [File.dirname(f)]
46
- end
47
- for f in dir
48
- next if f == "."
49
- next if f == "CVS"
50
- File::makedirs(File.join(destdir, f))
51
- end
52
- for f in path
53
- next if (/\~$/ =~ f)
54
- next if (/^\./ =~ File.basename(f))
55
- unless bin
56
- File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
57
- else
58
- from = File.join(srcdir, f)
59
- to = File.join(destdir, f)
60
- shebangify(from) do |sf|
61
- $deferr.print from, " -> ", File::catname(from, to), "\n"
62
- $deferr.printf "chmod %04o %s\n", mode, to
63
- File::install(sf, to, mode, false)
64
- end
65
- end
66
- end
67
- #}}}
68
- end
69
- def shebangify f
70
- #{{{
71
- open(f) do |fd|
72
- buf = fd.read 42
73
- if buf =~ %r/^\s*#\s*!.*ruby/o
74
- ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
75
- begin
76
- fd.rewind
77
- ftmp.puts "#!#{ $ruby }"
78
- while((buf = fd.read(8192)))
79
- ftmp.write buf
80
- end
81
- ftmp.close
82
- yield ftmp.path
83
- ensure
84
- ftmp.close!
85
- end
86
- else
87
- yield f
88
- end
89
- end
90
- #}}}
91
- end
92
- def ARGV.switch
93
- #{{{
94
- return nil if self.empty?
95
- arg = self.shift
96
- return nil if arg == '--'
97
- if arg =~ /^-(.)(.*)/
98
- return arg if $1 == '-'
99
- raise 'unknown switch "-"' if $2.index('-')
100
- self.unshift "-#{$2}" if $2.size > 0
101
- "-#{$1}"
102
- else
103
- self.unshift arg
104
- nil
105
- end
106
- #}}}
107
- end
108
- def ARGV.req_arg
109
- #{{{
110
- self.shift || raise('missing argument')
111
- #}}}
112
- end
113
- def linkify d, linked = []
114
- #--{{{
115
- if test ?d, d
116
- versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
117
- versioned.each do |v|
118
- src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
119
- lnk = nil
120
- begin
121
- if test ?l, dst
122
- lnk = "#{ dst }.lnk"
123
- puts "#{ dst } -> #{ lnk }"
124
- File::rename dst, lnk
125
- end
126
- unless test ?e, dst
127
- puts "#{ src } -> #{ dst }"
128
- File::copy src, dst
129
- linked << dst
130
- end
131
- ensure
132
- if lnk
133
- at_exit do
134
- puts "#{ lnk } -> #{ dst }"
135
- File::rename lnk, dst
136
- end
137
- end
138
- end
139
- end
140
- end
141
- linked
142
- #--}}}
143
- end
144
-
145
-
146
- #
147
- # main program
148
- #
149
-
150
- libdir = $site_libdir
151
- bindir = $bindir
152
- no_linkify = false
153
- linked = nil
154
- help = false
155
-
156
- usage = <<-usage
157
- #{ File::basename $0 }
158
- -d, --destdir <destdir>
159
- -l, --libdir <libdir>
160
- -b, --bindir <bindir>
161
- -r, --ruby <ruby>
162
- -n, --no_linkify
163
- -s, --sudo
164
- -h, --help
165
- usage
166
-
167
- begin
168
- while switch = ARGV.switch
169
- case switch
170
- when '-d', '--destdir'
171
- libdir = ARGV.req_arg
172
- when '-l', '--libdir'
173
- libdir = ARGV.req_arg
174
- when '-b', '--bindir'
175
- bindir = ARGV.req_arg
176
- when '-r', '--ruby'
177
- $ruby = ARGV.req_arg
178
- when '-n', '--no_linkify'
179
- no_linkify = true
180
- when '-s', '--sudo'
181
- sudo = 'sudo'
182
- when '-h', '--help'
183
- help = true
184
- else
185
- raise "unknown switch #{switch.dump}"
186
- end
187
- end
188
- rescue
189
- STDERR.puts $!.to_s
190
- STDERR.puts usage
191
- exit 1
192
- end
193
-
194
- if help
195
- STDOUT.puts usage
196
- exit
197
- end
198
-
199
- system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
200
-
201
- unless no_linkify
202
- linked = linkify('lib') + linkify('bin')
203
- end
204
-
205
- system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
206
-
207
- install_rb(LIBDIR, libdir, LIBDIR_MODE)
208
- install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
209
-
210
- if linked
211
- linked.each{|path| File::rm_f path}
212
- end
213
-
214
- system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
Binary file