jig 0.1.0 → 0.1.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.
- data/.DS_Store +0 -0
- data/History.txt +17 -4
- data/Manifest.txt +5 -0
- data/README.txt +15 -31
- data/Rakefile +5 -5
- data/lib/jig.rb +64 -30
- data/lib/jig/css.rb +0 -3
- data/lib/jig/xhtml.rb +91 -108
- data/lib/jig/xml.rb +27 -3
- data/test/jig.rb +14 -0
- data/test/jig_spec.rb +110 -0
- data/test/test_jig.rb +7 -0
- data/test/test_parse.rb +88 -0
- data/todo +7 -0
- metadata +21 -11
data/.DS_Store
ADDED
Binary file
|
data/History.txt
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
-
== 0.1.
|
1
|
+
== 0.1.1 / 2008-02-28
|
2
|
+
|
3
|
+
* Jig#syntax to help with jig comparison
|
4
|
+
* Jig#terse_inspect to help with nested inspect and gaps with processing
|
5
|
+
* testing of Jig#parse
|
6
|
+
* to_yaml of jigs with procs
|
7
|
+
* Callable objects are now rendered to strings via to_yaml
|
8
|
+
* Attribute gaps have their own class now instead of being adhoc gap filters.
|
9
|
+
* Gap#== checks classes
|
10
|
+
* Gap with filter was being replaced by a plain gap.
|
11
|
+
Ignore filling if filling is the same gap.
|
12
|
+
* Jig#parse correction
|
13
|
+
* cleanup up some documentation typos
|
14
|
+
* reimplemented Jig.parse with StringScanner, fixed bugs
|
15
|
+
|
16
|
+
== 0.1.0 / 2007-05-11
|
17
|
+
|
2
18
|
* Initial Release
|
3
|
-
* basic jig support
|
4
|
-
* XML, XHMTL support
|
5
|
-
* CSS support (experimental)
|
data/Manifest.txt
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
.DS_Store
|
1
2
|
History.txt
|
2
3
|
Manifest.txt
|
3
4
|
README.txt
|
@@ -6,7 +7,11 @@ lib/jig.rb
|
|
6
7
|
lib/jig/css.rb
|
7
8
|
lib/jig/xhtml.rb
|
8
9
|
lib/jig/xml.rb
|
10
|
+
test/jig.rb
|
11
|
+
test/jig_spec.rb
|
9
12
|
test/test_css.rb
|
10
13
|
test/test_jig.rb
|
14
|
+
test/test_parse.rb
|
11
15
|
test/test_xhtml.rb
|
12
16
|
test/test_xml.rb
|
17
|
+
todo
|
data/README.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Jig
|
2
2
|
by Gary R. Wright
|
3
|
-
|
3
|
+
http://jig.rubyforge.org
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
|
-
|
6
|
+
|
7
7
|
A jig is a data structure designed to facilitate construction and
|
8
8
|
manipulation of strings with an inherent hierarchical syntax. The
|
9
9
|
idea is derived from the <bigwig> project (http://www.brics.dk/bigwig/)
|
@@ -15,7 +15,7 @@ other tools.
|
|
15
15
|
|
16
16
|
A jig is an ordered sequence of objects (usually strings) and named
|
17
17
|
_gaps_. When rendered as a string by Jig#to_s, the objects are
|
18
|
-
rendered
|
18
|
+
rendered calling #to_s on each object in order. The gaps are skipped.
|
19
19
|
|
20
20
|
A new jig may be constructed from an existing jig by 'plugging' one
|
21
21
|
or more of the named gaps. The new jig shares the objects and their
|
@@ -24,14 +24,10 @@ the 'plug'. Gaps may be plugged by any object or sequence of
|
|
24
24
|
objects. When a gap is plugged with another jig, the contents
|
25
25
|
(including gaps) are incorporated into the new jig.
|
26
26
|
|
27
|
-
In addition to strings and gaps, a Jig may contain a proc object
|
28
|
-
(or lambda or method). Procs within a jig are not evaluated until
|
29
|
-
the jig is rendered as a string by #to_s.
|
30
|
-
|
31
27
|
Several subclasses (Jig::XML, Jig::XHTML, Jig::CSS) are defined to
|
32
28
|
help in the construction of XML, XHTML, and CSS documents.
|
33
29
|
|
34
|
-
This is a jig with a single gap named
|
30
|
+
This is a jig with a single gap named :alpha.
|
35
31
|
Jig.new(:alpha) # => <#Jig: [:alpha]>
|
36
32
|
This is a jig with two objects, 'before' and 'after' separated by
|
37
33
|
a gap named :middle.
|
@@ -42,44 +38,32 @@ This operation doesn't change j. It can be used again:
|
|
42
38
|
j.plug(:middle, " and ") # => #<Jig: ["before", " and ", "after"]>
|
43
39
|
There is a destructive version of plug that modifies
|
44
40
|
the jig in place:
|
45
|
-
j.plug!(:middle, "filled")
|
46
|
-
j
|
41
|
+
j.plug!(:middle, "filled") # => #<Jig: ["before", "filled", "after"]>
|
42
|
+
j # => #<Jig: ["before", "filled", "after"]>
|
47
43
|
There are a number of ways to construct a Jig and many of
|
48
44
|
them insert an implicit gap into the Jig. This gap is
|
49
|
-
identified as
|
45
|
+
identified as :___ and is used as the default gap
|
50
46
|
for plug operations when one isn't provided:
|
51
47
|
|
52
|
-
puts Jig.new("A", :___, "C").plug("B")
|
53
|
-
puts Jig.new.plug('filled') # => filled
|
54
|
-
|
55
|
-
The % operator is an alias for Jig#plug
|
48
|
+
puts Jig.new("A", :___, "C").plug("B") # => ABC
|
56
49
|
|
57
|
-
|
58
|
-
|
59
|
-
puts name % data # => Wright, Gary
|
50
|
+
In order to make Jig's more useful for HTML generation,
|
51
|
+
the Jig::XHTML class supports a variety of convenience methods;
|
60
52
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
X = Jig::XML
|
65
|
-
puts b = X.element("body") # => <body></body>
|
66
|
-
puts b.plug("text") # => <body>text</body>
|
53
|
+
HT = Jig::XHTML
|
54
|
+
puts b = HT.element("body") # => <body></body>
|
55
|
+
puts b.plug("text") # => <body>text</body>
|
67
56
|
|
68
57
|
Method missing makes this even simpler:
|
69
58
|
|
70
59
|
b = HT.span
|
71
|
-
puts b.plug("text")
|
60
|
+
puts b.plug("text") # => <span>text</span>
|
72
61
|
|
73
62
|
Attributes can be specified with a hash:
|
74
63
|
|
75
|
-
summary =
|
64
|
+
summary = HT.p(:class => "summary")
|
76
65
|
puts summary.plug("This is a summary") # => <p class="summary">This is a summary</p>
|
77
66
|
|
78
|
-
See the Jig::XML for more information about attributes and gaps.
|
79
|
-
The Jig::XHTML class has a variety of convenience methods for
|
80
|
-
constructing XHTML documents. The Jig::CSS class generates jigs
|
81
|
-
that represent CSS rules.
|
82
|
-
|
83
67
|
== REQUIREMENTS:
|
84
68
|
|
85
69
|
* Ruby 1.8
|
data/Rakefile
CHANGED
@@ -7,12 +7,12 @@ require './lib/jig.rb'
|
|
7
7
|
|
8
8
|
Hoe.new('jig', Jig::VERSION) do |p|
|
9
9
|
p.rubyforge_name = 'jig'
|
10
|
-
p.
|
11
|
-
p.email = 'gwright@rubyforge.org'
|
12
|
-
p.summary = 'a data structure that supports construction and manipulation of strings with hierarchical structure'
|
10
|
+
p.summary = 'A Jig is a data structure that supports construction and manipulation of strings with hierarchical structure.'
|
13
11
|
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
14
|
-
p.url = "http://jig.rubyforge.org"
|
15
12
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
13
|
+
p.author = "Gary R. Wright"
|
14
|
+
p.email = "gwright@rubyforge.org"
|
15
|
+
p.url = "http://jig.rubyforge.org"
|
16
16
|
end
|
17
17
|
|
18
18
|
task :spec do
|
@@ -31,7 +31,7 @@ RCOV = "rcov"
|
|
31
31
|
desc "generate a unit test coverage report in coverage/unit; see coverage/unit/index.html afterwards"
|
32
32
|
task :rcov do
|
33
33
|
tests = FileList['test/test_*.rb']
|
34
|
-
sh "#{RCOV}
|
34
|
+
sh "#{RCOV} -Ilib #{tests}"
|
35
35
|
end
|
36
36
|
|
37
37
|
|
data/lib/jig.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'strscan'
|
1
2
|
|
2
3
|
=begin rdoc
|
3
4
|
A jig is an ordered sequence of objects and named gaps. During construction,
|
@@ -39,7 +40,7 @@ replaced with the same sequence of objects.
|
|
39
40
|
puts j.plug(:separator, '/') # => "first/middle/last"
|
40
41
|
=end
|
41
42
|
class Jig
|
42
|
-
VERSION = '0.1.
|
43
|
+
VERSION = '0.1.2'
|
43
44
|
autoload :XML, "jig/xml"
|
44
45
|
autoload :XHTML, "jig/xhtml"
|
45
46
|
autoload :CSS, "jig/css"
|
@@ -52,7 +53,6 @@ class Jig
|
|
52
53
|
class Gap
|
53
54
|
ATTRS = :__a
|
54
55
|
GAP = :___
|
55
|
-
|
56
56
|
# the name associated with the gap
|
57
57
|
attr :name
|
58
58
|
|
@@ -67,7 +67,11 @@ class Jig
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def inspect
|
70
|
-
"
|
70
|
+
"#<#{self.class.name}: [#{name}, #{filter.inspect}]>"
|
71
|
+
end
|
72
|
+
|
73
|
+
def terse_inspect
|
74
|
+
filter && "#{name}{}".to_sym || name
|
71
75
|
end
|
72
76
|
|
73
77
|
# Pass the replacement items through the filter.
|
@@ -78,7 +82,9 @@ class Jig
|
|
78
82
|
# Two gaps are equal if they have the same name and
|
79
83
|
# use the same filter.
|
80
84
|
def ==(other)
|
81
|
-
|
85
|
+
self.class == other.class &&
|
86
|
+
name == other.name &&
|
87
|
+
filter == other.filter
|
82
88
|
end
|
83
89
|
|
84
90
|
# Change the name of the gap.
|
@@ -107,11 +113,10 @@ class Jig
|
|
107
113
|
# If _open_ is provided, a single line of text will be wrapped with the _open_
|
108
114
|
# and _close_ strings but multiple lines of text will be formatted as a block
|
109
115
|
# comment. If _close_ is not provided it is taken to be the <i>open.reverse</i>.
|
110
|
-
# Jig[Jig::Gap.comment]
|
111
|
-
# Jig[Jig::Gap.comment("# ")]
|
112
|
-
# Jig[Jig::Gap.comment("// ")]
|
113
|
-
# Jig[Jig::Gap.comment(" *", "/* ")]
|
114
|
-
# Jig[Jig::Gap.comment(" ", "<-- ", " -->")] # text reformated as XML comments
|
116
|
+
# Jig[Jig::Gap.comment] # text reformated to 72 columns
|
117
|
+
# Jig[Jig::Gap.comment("# ")] # text reformated as Ruby comments
|
118
|
+
# Jig[Jig::Gap.comment("// ")] # text reformated as Javascript comments
|
119
|
+
# Jig[Jig::Gap.comment(" *", "/* ")] # text reformated as C comments
|
115
120
|
#
|
116
121
|
# If the default gap name isn't appropriate you must fill in all the arguments:
|
117
122
|
# Jig[Jig::Gap.comment("# ", nil, nil, 72, :alternate)] # alternate gap name
|
@@ -192,24 +197,44 @@ class Jig
|
|
192
197
|
#
|
193
198
|
# A.new.secret # NoMethodError
|
194
199
|
# A.new.to_jig.to_s # secret: xyzzy
|
200
|
+
|
201
|
+
Before = /[^%]*/
|
202
|
+
Replace = /%\{(.?)(.+)\1\}/
|
203
|
+
|
195
204
|
def parse(string=nil, context=nil)
|
196
205
|
wrapper = context || Module.new.class_eval { binding }
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
+
scanner = StringScanner.new(string)
|
207
|
+
raw = []
|
208
|
+
while !scanner.eos?
|
209
|
+
if before = scanner.scan(Before)
|
210
|
+
if replace = scanner.scan(Replace)
|
211
|
+
raw << before
|
212
|
+
raw << interpolate(replace, wrapper)
|
213
|
+
else
|
214
|
+
raw << before
|
215
|
+
raw << scanner.getch unless scanner.eos?
|
216
|
+
end
|
206
217
|
else
|
207
|
-
|
218
|
+
raw << scanner.rest
|
219
|
+
scanner.terminate
|
208
220
|
end
|
209
|
-
|
221
|
+
end
|
210
222
|
Jig.new(*raw)
|
211
223
|
end
|
212
224
|
|
225
|
+
def interpolate(replace, context)
|
226
|
+
all, delimiter, content = *(replace.match(Replace))
|
227
|
+
|
228
|
+
case delimiter
|
229
|
+
when ':'
|
230
|
+
content.to_sym
|
231
|
+
when '!', ''
|
232
|
+
eval("lambda {#{content}}", context)
|
233
|
+
else
|
234
|
+
parse_other(delimiter, content)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
213
238
|
def parse_other(delim, stripped)
|
214
239
|
raise ArgumentError, "invalid delimiter: \"#{delim}\""
|
215
240
|
end
|
@@ -233,7 +258,7 @@ class Jig
|
|
233
258
|
# puts j # => "i is 1"
|
234
259
|
#
|
235
260
|
# If no arguments are given and no block is given, the jig is constructed
|
236
|
-
# with a single default gap named <tt
|
261
|
+
# with a single default gap named <tt>:\___</tt> (also known as Jig::GAP).
|
237
262
|
# one_gap = Jig.new
|
238
263
|
# one_gap.gaps # => [:___]
|
239
264
|
def initialize(*items, &block)
|
@@ -286,6 +311,12 @@ class Jig
|
|
286
311
|
contents.zip(rawgaps).flatten.eql?(rhs.contents.zip(rhs.rawgaps).flatten)
|
287
312
|
end
|
288
313
|
|
314
|
+
# Construct and array that represents the syntax of the jig including its
|
315
|
+
# gaps. Gaps are only distinguished by their name and not their semantics.
|
316
|
+
def syntax
|
317
|
+
contents.zip(gaps).flatten
|
318
|
+
end
|
319
|
+
|
289
320
|
# Returns true if +rhs+ is an instance of Jig or one of Jig's subclasses and
|
290
321
|
# the two jigs have equal gap lists and contents (via Array#==).
|
291
322
|
# Procs are not evaluated by Jig#==.
|
@@ -309,7 +340,7 @@ class Jig
|
|
309
340
|
end
|
310
341
|
|
311
342
|
# Returns true if the string representation of the jig matches the
|
312
|
-
#
|
343
|
+
# +rhs.to_str+ using String#=~. Procs are evaluated by Jig#===.
|
313
344
|
def ===(rhs)
|
314
345
|
to_s =~ rhs.to_str
|
315
346
|
end
|
@@ -324,7 +355,7 @@ class Jig
|
|
324
355
|
# Jig.new(1,:a,2).inspect # => #<Jig: [1, :a, 2]>
|
325
356
|
# Jig.new(Gap.new(:example) { |x| x.to_s.reverse }) # => #<Jig: [:example{}]>
|
326
357
|
def inspect
|
327
|
-
info = rawgaps.map {|g| g.
|
358
|
+
info = rawgaps.map {|g| g.terse_inspect }
|
328
359
|
"#<Jig: #{contents.zip(info).flatten[0..-2].inspect}>"
|
329
360
|
end
|
330
361
|
|
@@ -602,12 +633,12 @@ class Jig
|
|
602
633
|
dup.after!(*args)
|
603
634
|
end
|
604
635
|
|
605
|
-
# call-seq
|
636
|
+
# call-seq:
|
606
637
|
# split(pattern=$;, [limit])
|
607
638
|
#
|
608
639
|
# With no arguments, the jig is split at the gap positions into an
|
609
|
-
# array of strings. If arguments are provided, the
|
610
|
-
# rendered to a string and the result of String#split (with the
|
640
|
+
# array of strings. If arguments are provided, the jig is
|
641
|
+
# rendered to a string by #to_s and the result of String#split (with the
|
611
642
|
# arguments) is returned.
|
612
643
|
def split(*args)
|
613
644
|
if args.empty?
|
@@ -672,6 +703,7 @@ class Jig
|
|
672
703
|
alias inspect :to_s
|
673
704
|
undef to_s
|
674
705
|
def to_s; call.to_s; end
|
706
|
+
def to_yaml(opts={}); call.to_yaml(opts); end
|
675
707
|
#:startdoc:
|
676
708
|
}
|
677
709
|
contents.last << i
|
@@ -804,8 +836,10 @@ class Jig
|
|
804
836
|
gaps.each_with_index do |gap, index|
|
805
837
|
match = index + adjust
|
806
838
|
items = block_given? && yield(gap)
|
807
|
-
|
808
|
-
|
839
|
+
if items != gap
|
840
|
+
fill = rawgaps.at(match).fill(items)
|
841
|
+
adjust += plug_gap!(match, fill) - 1
|
842
|
+
end
|
809
843
|
end
|
810
844
|
self
|
811
845
|
end
|
@@ -829,8 +863,8 @@ class Jig
|
|
829
863
|
end
|
830
864
|
|
831
865
|
# :stopdoc:
|
832
|
-
# This method alters the current jig by replacing a gap with a
|
833
|
-
#
|
866
|
+
# This method alters the current jig by replacing a gap with a (possibly
|
867
|
+
# empty) sequence of objects. The contents and rawgap arrays
|
834
868
|
# are modified such that the named gap is removed and the sequence of
|
835
869
|
# objects are put in the logical position of the former gap.
|
836
870
|
#
|
data/lib/jig/css.rb
CHANGED
@@ -229,9 +229,6 @@ class Jig
|
|
229
229
|
end
|
230
230
|
end
|
231
231
|
|
232
|
-
# Returns a standard jig representation of the CSS jig. Gaps that are
|
233
|
-
# used internally by the CSS class are closed. #to_jig should be used before
|
234
|
-
# combining one or more CSS jigs.
|
235
232
|
def to_jig
|
236
233
|
Jig.new(plug( :__s => nil, :__de => nil, :__ds => nil ))
|
237
234
|
end
|
data/lib/jig/xhtml.rb
CHANGED
@@ -2,8 +2,8 @@ require 'jig'
|
|
2
2
|
require 'jig/xml'
|
3
3
|
|
4
4
|
class Jig
|
5
|
-
|
6
|
-
|
5
|
+
# Jig::XHTML is a subclass of Jig::XML and is designed to assist in the
|
6
|
+
# construction of XHTML documents.
|
7
7
|
class XHTML < XML
|
8
8
|
attr_accessor :extra
|
9
9
|
protected :extra
|
@@ -35,8 +35,8 @@ class Jig
|
|
35
35
|
class <<self
|
36
36
|
# Construct a jig for an XHTML element with _tag as the tag and include
|
37
37
|
# an ID attribute with a guaranteed unique value.
|
38
|
-
|
39
|
-
|
38
|
+
# Example:
|
39
|
+
# puts Jig::XHTML.element_with_id('div') # <div id="x2354322">\n</div>
|
40
40
|
def element_with_id(tag, *args)
|
41
41
|
attrs = { 'id' => :id }
|
42
42
|
attrs = attrs.merge!(args.pop) if args.last.respond_to?(:fetch)
|
@@ -49,11 +49,11 @@ class Jig
|
|
49
49
|
|
50
50
|
# Construct a jig for an emtpy XHTML element with _tag as the tag and include
|
51
51
|
# an ID attribute with a guaranteed unique value. The selected id is
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
# accessible via the eid attribute.
|
53
|
+
# Example:
|
54
|
+
# j = Jig::XHTML.element_with_id('input', :name=>'login')
|
55
|
+
# puts j # <input name="login" id="x2354328"/>
|
56
|
+
# puts j.eid # x2354328
|
57
57
|
def element_with_id!(tag, *args)
|
58
58
|
attrs = { 'id' => :id }
|
59
59
|
attrs = attrs.merge!(args.pop) if args.last.respond_to?(:fetch)
|
@@ -64,10 +64,10 @@ class Jig
|
|
64
64
|
jig.plug!(:id, jig.eid)
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
# Construct an element based on the method name. If the method name
|
68
|
+
# ends in '_with_id' or '_with_id!', the element is constructed with
|
69
|
+
# a unique XML id attribute otherwise the Jig::XML element construction
|
70
|
+
# rules apply.
|
71
71
|
def method_missing(sym, *args, &block)
|
72
72
|
text = sym.to_s
|
73
73
|
if text.to_s =~ /_with_id!*$/
|
@@ -83,43 +83,26 @@ class Jig
|
|
83
83
|
:frameset, %{"-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"}
|
84
84
|
}
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
# puts X.doctype(:strict).gaps.size # 0
|
86
|
+
# Construct an XHTML DOCTYPE declaration. The first argument, _dtype_, specifies
|
87
|
+
# the type of document: :strict, :transitional, or :frameset. Any additional
|
88
|
+
# arguments are rendered after the DOCTYPE declaration. A default gap is *not*
|
89
|
+
# inserted if their are no arguments. Examples:
|
90
|
+
#
|
91
|
+
# puts X.doctype(:strict) # <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd>
|
92
|
+
# puts X.doctype(:strict).gaps.size # 0
|
94
93
|
def doctype(dtype, *args, &block)
|
95
94
|
new(%{<!DOCTYPE html PUBLIC #{DOCTYPES.fetch(dtype)}>\n}, *args, &block)
|
96
95
|
end
|
97
96
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
# document with three gaps, <tt>:title</tt>, <tt>:head</tt>, and <tt>:___</tt>
|
105
|
-
# is generated. The default gap represents the contents of the body element.
|
106
|
-
#
|
107
|
-
# With a single symbol argument, <i>doctype</i>, an XHTMl document is generated
|
108
|
-
# with a corresponding DOCTYPE declaration (see #doctype).
|
109
|
-
#
|
110
|
-
# If any arguments are provided other than a doctype, the additional arguments
|
111
|
-
# are used as the contents of the HTML element.
|
112
|
-
#
|
113
|
-
# A trailing hash argument is assumed to represent additional XML attributes for
|
114
|
-
# the html element.
|
115
|
-
# X.xhtml # transitional document with :title, :head, and :___
|
116
|
-
# X.xhtml :strict # strict document with :title, :head, and :___
|
117
|
-
# X.xhtml(:strict, head, body) # strict document with explicit head & body
|
118
|
-
# X.xhtml(head, body) # transitional document with explicit head & body
|
119
|
-
# X.xhtml :lang => 'jp' # transition document with HTML attributes merged
|
97
|
+
# Construct a generic XHTML document. If the first argument is a symbol it is
|
98
|
+
# used to look up a matching DOCTYPE declaration (see #doctype).
|
99
|
+
# X.xhtml # transitional document with :title, :head, and :___
|
100
|
+
# X.xhtml :strict # strict document with :title, :head, and :___
|
101
|
+
# X.xhtml :lang => 'jp' # transition document with HTML attributes merged
|
102
|
+
# X.xhtml(head, body) # transitional document with explicit head & body
|
120
103
|
def xhtml(dtype=:transitional, *args, &block)
|
121
|
-
|
122
|
-
dtype
|
104
|
+
if dtype.respond_to?(:fetch)
|
105
|
+
dtype,*args = :transitional,dtype
|
123
106
|
end
|
124
107
|
attrs = {:lang=>'en', "xml:lang"=>'en', :xmlns=>'http://www.w3.org/1999/xhtml'}
|
125
108
|
attrs.merge!(args.pop) if args.last.respond_to?(:fetch)
|
@@ -129,11 +112,11 @@ class Jig
|
|
129
112
|
doctype(dtype,html(*args))
|
130
113
|
end
|
131
114
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
115
|
+
# A convenience method for constructing an XHTML element with a named
|
116
|
+
# CSS class and an unique XHTML element ID.
|
117
|
+
#
|
118
|
+
# X.container('span', 'urgent', 'This is urgent!')
|
119
|
+
# => <span class="urgent" id="x2337852"></span>
|
137
120
|
def container(tag, css, *args)
|
138
121
|
args.push(Proc.new) if block_given?
|
139
122
|
args.push(:class => css)
|
@@ -142,26 +125,26 @@ class Jig
|
|
142
125
|
jig
|
143
126
|
end
|
144
127
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
128
|
+
# An even shorter way to construct a div container
|
129
|
+
#
|
130
|
+
# X.divc('urgent', 'This is urgent!')
|
131
|
+
# => <div class="urgent" id="x2337852"></div>
|
149
132
|
def divc(css_class, *args, &block)
|
150
133
|
container(:div, css_class, *args, &block)
|
151
134
|
end
|
152
135
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
136
|
+
# Generate a link element for a favicon. Extra attributes
|
137
|
+
# may be specified via the optional argument, _extra_.
|
138
|
+
#
|
139
|
+
# X.link_favicon
|
140
|
+
# => <link src="/favicon.ico" type="image/x-icon" rel="icon"/>
|
158
141
|
def link_favicon(extra={})
|
159
142
|
attrs = {:type=>"image/x-icon", :rel=>"icon", :src=>'/favicon.ico'}
|
160
143
|
attrs.merge! extra
|
161
144
|
link!(attrs)
|
162
145
|
end
|
163
146
|
|
164
|
-
|
147
|
+
# XXX: is this no longer needed?
|
165
148
|
def normalize_args(args, attrs={}) # :nodoc"
|
166
149
|
attrs.merge!(args.pop) if args.last.respond_to?(:fetch)
|
167
150
|
args.push(Proc.new) if block_given?
|
@@ -169,18 +152,18 @@ class Jig
|
|
169
152
|
return args, attrs
|
170
153
|
end
|
171
154
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
155
|
+
# Generate a CSS style sheet element. If a 'src' attribute
|
156
|
+
# is provided the contents is empty. Without a 'src' attribute
|
157
|
+
# a CDATA block wraps the contents of the element.
|
158
|
+
#
|
159
|
+
# j = Jig::XHTML.style
|
160
|
+
# puts j.plug('/* CSS style sheet */')
|
161
|
+
#
|
162
|
+
# <style media="all" type="text/css">
|
163
|
+
# <![CDATA[
|
164
|
+
# /* CSS style sheet */
|
165
|
+
# ]]>
|
166
|
+
# </style>
|
184
167
|
def style(*args, &block)
|
185
168
|
attrs = {:type=>"text/css", :media=>"all"}
|
186
169
|
attrs.merge!(args.pop) if args.last.respond_to?(:fetch)
|
@@ -197,16 +180,16 @@ class Jig
|
|
197
180
|
link!('rel' => 'stylesheet', 'type' => 'text/css', 'href' => src)
|
198
181
|
end
|
199
182
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
183
|
+
# Generate a script element. XXX
|
184
|
+
#
|
185
|
+
# j = Jig::XHTML.script
|
186
|
+
# puts j.plug(cdata("# the script"))
|
187
|
+
#
|
188
|
+
# <script type=">
|
189
|
+
# <![CDATA[
|
190
|
+
# # the script
|
191
|
+
# ]]>
|
192
|
+
# </script>
|
210
193
|
def script(*args, &block)
|
211
194
|
attrs = args.pop if args.last.respond_to?(:fetch)
|
212
195
|
args.push(Proc.new) if block_given?
|
@@ -233,12 +216,12 @@ class Jig
|
|
233
216
|
new(a({:href=>"#", :onclick => "toggle(#{body.eid})"}, '(details)'), body)
|
234
217
|
end
|
235
218
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
219
|
+
# Generate a Javascript comment.
|
220
|
+
#
|
221
|
+
# j = Jig::XHTML.js_comment
|
222
|
+
# puts j.plug("comment")
|
223
|
+
#
|
224
|
+
# /* comment */
|
242
225
|
def js_comment(*args, &block)
|
243
226
|
gap = Jig::Gap.new(:comment) { |*filling|
|
244
227
|
filling.map {|item|
|
@@ -248,30 +231,30 @@ class Jig
|
|
248
231
|
new(gap, "\n").plug(:comment, *args)
|
249
232
|
end
|
250
233
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
234
|
+
# Generate a multiline Javascript comment.
|
235
|
+
#
|
236
|
+
# j = Jig::XHTML.js_comments
|
237
|
+
# puts j.plug("line 1\nline 2")
|
238
|
+
#
|
239
|
+
# /*
|
240
|
+
# line 1
|
241
|
+
# line 2
|
242
|
+
# */
|
260
243
|
def js_mlcomment(*args, &block)
|
261
244
|
new("/*\n", new(*args, &block), "\n */\n")
|
262
245
|
end
|
263
246
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
247
|
+
# Generate an inline script element for javascript.
|
248
|
+
# The body of the script is wrapped in a CDATA block.
|
249
|
+
#
|
250
|
+
# j = Jig::XHTML.javascript
|
251
|
+
# puts j.plug("// the script")
|
252
|
+
#
|
253
|
+
# <script type="text/javascript" language="JavaScript">
|
254
|
+
# <![CDATA[
|
255
|
+
# // the script
|
256
|
+
# ]]>
|
257
|
+
# </script>
|
275
258
|
def javascript(*args, &block)
|
276
259
|
attrs = {:type=>"text/javascript", :language=>"JavaScript"}
|
277
260
|
attrs.merge!(args.pop) if args.last.respond_to?(:fetch)
|
data/lib/jig/xml.rb
CHANGED
@@ -78,6 +78,26 @@ class Jig
|
|
78
78
|
j = X.div('inner', :style=> color) # => <div style="color: red">inner</div>
|
79
79
|
j.to_s # => <div style="color: green">inner</div>
|
80
80
|
=end
|
81
|
+
|
82
|
+
class ALGap < Gap
|
83
|
+
def fill(h)
|
84
|
+
h && h.map { |k,v| Jig::XML.attribute(k, v) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class AGap < Gap
|
89
|
+
attr_accessor :aname
|
90
|
+
|
91
|
+
def initialize(name, aname)
|
92
|
+
super(name)
|
93
|
+
self.aname = aname
|
94
|
+
end
|
95
|
+
|
96
|
+
def fill(fill)
|
97
|
+
Jig::XML.attribute(aname, fill)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
81
101
|
class XML < Jig
|
82
102
|
# Converts _hash_ into attribute value pairs and pushes them
|
83
103
|
# on the end of the jig.
|
@@ -117,7 +137,8 @@ class Jig
|
|
117
137
|
when nil, false
|
118
138
|
""
|
119
139
|
when Symbol
|
120
|
-
|
140
|
+
AGap.new(value, aname)
|
141
|
+
#Gap.new(value) { |fill| attribute(aname, fill) }
|
121
142
|
when Gap
|
122
143
|
value
|
123
144
|
when Proc, Method
|
@@ -157,7 +178,8 @@ class Jig
|
|
157
178
|
private :parse_other
|
158
179
|
|
159
180
|
ATTRS = Gap::ATTRS # :nodoc:
|
160
|
-
ATTRS_GAP =
|
181
|
+
ATTRS_GAP = Jig::ALGap.new(ATTRS)
|
182
|
+
#ATTRS_GAP = Gap.new(ATTRS) { |h| h && h.map { |k,v| Jig::XML.attribute(k, v) } } # :nodoc:
|
161
183
|
|
162
184
|
Element_Cache = {} # :nodoc:
|
163
185
|
# Construct a generic XML element with two gaps:
|
@@ -295,17 +317,19 @@ class Jig
|
|
295
317
|
#
|
296
318
|
# \<!-- This is a comment -->
|
297
319
|
def comment(*args)
|
320
|
+
#:stopdoc:
|
298
321
|
args.push(lambda{|*x| yield(*x) }) if block_given?
|
299
322
|
args.push GAP if args.empty?
|
300
323
|
jig = (Cache[:comment] ||= new("<!-- ".freeze, GAP, " -->\n".freeze).freeze)
|
301
324
|
jig.plug(GAP, *args)
|
325
|
+
#:startdoc:
|
302
326
|
end
|
303
327
|
|
304
328
|
# Construct a multiline XML comment element.
|
305
329
|
#
|
306
330
|
# Jig::XML.comment("first line\nsecond line")
|
307
331
|
#
|
308
|
-
#
|
332
|
+
# \<!--
|
309
333
|
# first line
|
310
334
|
# second line
|
311
335
|
# -->
|
data/test/jig.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
module Asserts
|
3
|
+
def assert_as_string(expected, jig, message='')
|
4
|
+
case expected
|
5
|
+
when String
|
6
|
+
assert_equal(expected, jig.to_s, message)
|
7
|
+
when Regexp
|
8
|
+
assert_match(expected, jig.to_s, message)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
def assert_not_similar(a, b, mess="")
|
12
|
+
assert_not_match(a, b, mess)
|
13
|
+
end
|
14
|
+
end
|
data/test/jig_spec.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# A Rspec file for Jig
|
2
|
+
#
|
3
|
+
#
|
4
|
+
require File.dirname(__FILE__) + '/../lib/jig'
|
5
|
+
|
6
|
+
context "A null jig" do
|
7
|
+
setup do
|
8
|
+
@jig = Jig.null
|
9
|
+
end
|
10
|
+
specify "should be an instance of Jig" do
|
11
|
+
@jig.should_be_an_instance_of Jig
|
12
|
+
end
|
13
|
+
specify "should be full" do
|
14
|
+
@jig.should_be_full
|
15
|
+
end
|
16
|
+
specify "should serialize as the null string" do
|
17
|
+
@jig.to_s.should == ""
|
18
|
+
end
|
19
|
+
specify "should test as null" do
|
20
|
+
@jig.should_be_null
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "A new jig" do
|
25
|
+
setup do
|
26
|
+
@jig = Jig.new
|
27
|
+
end
|
28
|
+
specify "should be an instance of Jig" do
|
29
|
+
@jig.should_be_an_instance_of Jig
|
30
|
+
end
|
31
|
+
specify "should have a default gap" do
|
32
|
+
@jig.should_have_gap :___
|
33
|
+
end
|
34
|
+
specify "should have only one gap" do
|
35
|
+
@jig.gap_count.should == 1
|
36
|
+
end
|
37
|
+
specify "should serialize as the null string" do
|
38
|
+
@jig.to_s.should == ""
|
39
|
+
end
|
40
|
+
specify "should not have a default gap after plug(:alpha)" do
|
41
|
+
@jig.plug(Jig::Gap.new(:alpha)).should_not_have_gap :___
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "A jig with a single gap named :alpha" do
|
46
|
+
setup do
|
47
|
+
@jig = Jig.new(:alpha)
|
48
|
+
end
|
49
|
+
specify 'should have one gap named :alpha' do
|
50
|
+
@jig.gap_list.should == [:alpha]
|
51
|
+
end
|
52
|
+
specify 'should serialize as the null string' do
|
53
|
+
@jig.to_s.should == ""
|
54
|
+
end
|
55
|
+
specify 'should match "beta" when you plug gap :alpha with "beta"' do
|
56
|
+
@jig.plug(:alpha, "beta").to_s.should == "beta"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "A jig with two gaps named :alpha" do
|
61
|
+
setup do
|
62
|
+
@jig = Jig.new(:alpha, :alpha)
|
63
|
+
end
|
64
|
+
specify 'should have two gaps named :alpha' do
|
65
|
+
@jig.gap_list.should == [:alpha, :alpha]
|
66
|
+
end
|
67
|
+
specify 'should match "hoho" when you plug gap :alpha with "ho"' do
|
68
|
+
@jig.plug(:alpha, "ho").to_s.should == "hoho"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "A jig with two gaps named :alpha and :beta" do
|
73
|
+
setup do
|
74
|
+
@jig = Jig.new(:alpha, :beta)
|
75
|
+
end
|
76
|
+
specify 'should have two gaps named :alpha, :beta' do
|
77
|
+
@jig.gap_list.should == [:alpha, :beta]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "A jig constructed by parsing 'a<:alpha:>b'" do
|
82
|
+
setup do
|
83
|
+
@jig = Jig.parse "a<:alpha:>b"
|
84
|
+
end
|
85
|
+
specify 'should have one gap named :alpha' do
|
86
|
+
@jig.gap_list.should == [:alpha]
|
87
|
+
end
|
88
|
+
specify 'should match "ab"' do
|
89
|
+
@jig.should_match "ab"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "A jig constructed by parsing 'a<:alpha,beta:>b'" do
|
94
|
+
setup do
|
95
|
+
Xjig = Class.new(Jig)
|
96
|
+
Xjig.enable :xml
|
97
|
+
@jig = Xjig.parse "a<:alpha,beta:>b"
|
98
|
+
end
|
99
|
+
specify 'should have one gap named :beta' do
|
100
|
+
@jig.gap_list.should == [:beta]
|
101
|
+
end
|
102
|
+
specify 'should match "ab"' do
|
103
|
+
@jig.should_match "ab"
|
104
|
+
end
|
105
|
+
specify 'should match "aalpha=1b" after plug :beta with 1' do
|
106
|
+
@jig.plug(:beta, 1).should_match "aalpha=1b"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# vim: syntax=Ruby
|
data/test/test_jig.rb
CHANGED
@@ -432,6 +432,13 @@ class MultipleGaps < Test::Unit::TestCase
|
|
432
432
|
assert_equal("<form onsubmit=\"ab\">\n</form>\n", j2.plug(:gap1, "X").to_s)
|
433
433
|
end
|
434
434
|
|
435
|
+
def xtest_depth
|
436
|
+
a = X.new
|
437
|
+
b = X.new(:"a/b")
|
438
|
+
assert_equal(0, a[Jig::GAP].depth)
|
439
|
+
assert_equal(1, b[:"a/b"].depth)
|
440
|
+
end
|
441
|
+
|
435
442
|
def test_escape
|
436
443
|
ok = 'a'
|
437
444
|
bad = '<'
|
data/test/test_parse.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
|
2
|
+
require 'jig'
|
3
|
+
require 'test/jig'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class TestParse < Test::Unit::TestCase
|
7
|
+
J = Jig
|
8
|
+
include Asserts
|
9
|
+
def test_string
|
10
|
+
source = "chunky bacon"
|
11
|
+
j = Jig.parse(source)
|
12
|
+
assert_equal(source, j.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_with_newline
|
16
|
+
source = "before %{:alpha:} after\n"
|
17
|
+
j = Jig.parse(source)
|
18
|
+
assert_equal([:alpha], j.gaps)
|
19
|
+
assert_equal("before ", j[0].to_s)
|
20
|
+
assert_equal(" after\n", j[2].to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_gap
|
24
|
+
source = "chunky %{:adjective:} bacon"
|
25
|
+
j = Jig.parse(source)
|
26
|
+
assert_equal([:adjective], j.gaps)
|
27
|
+
assert_equal("chunky ", j[0].to_s)
|
28
|
+
assert_equal(" bacon", j[2].to_s)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_agap
|
32
|
+
source = "<input%{=type,itype=} />"
|
33
|
+
j = Jig::XML.parse(source)
|
34
|
+
assert_equal([:itype], j.gaps)
|
35
|
+
assert_equal("<input", j[0].to_s)
|
36
|
+
assert_equal(" />", j[2].to_s)
|
37
|
+
jp = j.plug(:itype => 'password')
|
38
|
+
assert_equal("<input type=\"password\" />", jp.to_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_agap_error
|
42
|
+
source = "<input%{=type=} />"
|
43
|
+
assert_raise(ArgumentError) { Jig::XHTML.parse(source) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_jig_agap_error
|
47
|
+
source = "<input%{=type,itype=} />"
|
48
|
+
assert_raise(ArgumentError) { Jig.parse(source) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_syntax_error
|
52
|
+
source = "%{ , # invalid syntax }"
|
53
|
+
assert_raise(ArgumentError) { Jig.parse(source) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_lgap
|
57
|
+
a = 2
|
58
|
+
j = Jig.parse("%{!a + 1!}", binding)
|
59
|
+
assert_equal("3", j.to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_lgap_error
|
63
|
+
j = Jig.parse("%{!b + 1!}")
|
64
|
+
assert_raise(NameError) { j.to_s }
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_yield
|
68
|
+
j = Jig.parse("%{!yield + 1!}") { 5 }
|
69
|
+
assert_equal("6", j.to_s)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_instance_binding
|
73
|
+
klass = Class.new {
|
74
|
+
def to_jig
|
75
|
+
Jig.parse("secret: %{!secret!}", binding)
|
76
|
+
end
|
77
|
+
def secret
|
78
|
+
"xyzzy"
|
79
|
+
end
|
80
|
+
private :secret
|
81
|
+
}
|
82
|
+
|
83
|
+
instance = klass.new
|
84
|
+
assert_raise(NoMethodError) { instance.secret }
|
85
|
+
assert_equal("secret: xyzzy", instance.to_jig.to_s)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
data/todo
ADDED
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: jig
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date:
|
8
|
-
summary: a data structure that supports construction and manipulation of strings with hierarchical structure
|
6
|
+
version: 0.1.2
|
7
|
+
date: 2008-02-28 00:00:00 -05:00
|
8
|
+
summary: A Jig is a data structure that supports construction and manipulation of strings with hierarchical structure.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: gwright@rubyforge.org
|
12
12
|
homepage: http://jig.rubyforge.org
|
13
13
|
rubyforge_project: jig
|
14
|
-
description: "A jig is
|
14
|
+
description: "A jig is an ordered sequence of objects (usually strings) and named _gaps_. When rendered as a string by Jig#to_s, the objects are rendered calling #to_s on each object in order. The gaps are skipped. A new jig may be constructed from an existing jig by 'plugging' one or more of the named gaps. The new jig shares the objects and their ordering from the original jig but with the named gap replaced with the 'plug'. Gaps may be plugged by any object or sequence of objects. When a gap is plugged with another jig, the contents (including gaps) are incorporated into the new jig. Several subclasses (Jig::XML, Jig::XHTML, Jig::CSS) are defined to help in the construction of XML, XHTML, and CSS documents. This is a jig with a single gap named :alpha. Jig.new(:alpha) # => <#Jig: [:alpha]> This is a jig with two objects, 'before' and 'after' separated by a gap named :middle. j = Jig.new('before', :middle, 'after) # => #<Jig: [\"before\", :middle, \"after\"]> The plug operation derives a new jig from the old jig. j.plug(:middle, \", during, and\") # => #<Jig: [\"before\", \", during, and \", \"after\"]> This operation doesn't change j. It can be used again: j.plug(:middle, \" and \") # => #<Jig: [\"before\", \" and \", \"after\"]> There is a destructive version of plug that modifies the jig in place: j.plug!(:middle, \"filled\") # => #<Jig: [\"before\", \"filled\", \"after\"]> j # => #<Jig: [\"before\", \"filled\", \"after\"]> There are a number of ways to construct a Jig and many of them insert an implicit gap into the Jig. This gap is identified as :___ and is used as the default gap for plug operations when one isn't provided:"
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
@@ -25,9 +25,11 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
|
-
- Gary Wright
|
30
|
+
- Gary R. Wright
|
30
31
|
files:
|
32
|
+
- .DS_Store
|
31
33
|
- History.txt
|
32
34
|
- Manifest.txt
|
33
35
|
- README.txt
|
@@ -36,19 +38,27 @@ files:
|
|
36
38
|
- lib/jig/css.rb
|
37
39
|
- lib/jig/xhtml.rb
|
38
40
|
- lib/jig/xml.rb
|
41
|
+
- test/jig.rb
|
42
|
+
- test/jig_spec.rb
|
39
43
|
- test/test_css.rb
|
40
44
|
- test/test_jig.rb
|
45
|
+
- test/test_parse.rb
|
41
46
|
- test/test_xhtml.rb
|
42
47
|
- test/test_xml.rb
|
48
|
+
- todo
|
43
49
|
test_files:
|
44
50
|
- test/test_css.rb
|
45
51
|
- test/test_jig.rb
|
52
|
+
- test/test_parse.rb
|
46
53
|
- test/test_xhtml.rb
|
47
54
|
- test/test_xml.rb
|
48
|
-
rdoc_options:
|
49
|
-
|
50
|
-
|
51
|
-
|
55
|
+
rdoc_options:
|
56
|
+
- --main
|
57
|
+
- README.txt
|
58
|
+
extra_rdoc_files:
|
59
|
+
- History.txt
|
60
|
+
- Manifest.txt
|
61
|
+
- README.txt
|
52
62
|
executables: []
|
53
63
|
|
54
64
|
extensions: []
|
@@ -63,5 +73,5 @@ dependencies:
|
|
63
73
|
requirements:
|
64
74
|
- - ">="
|
65
75
|
- !ruby/object:Gem::Version
|
66
|
-
version: 1.
|
76
|
+
version: 1.4.0
|
67
77
|
version:
|