ahoward-tagz 5.1.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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