-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxml2.rb
126 lines (104 loc) · 2.37 KB
/
xml2.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
class XMLGrammar
def initialize(out)
@out = out
end
def self.generate(out, &block)
new(out).instance_eval(&block)
end
def self.element(tagname, attributes={})
@allowed_attributes ||= {}
@allowed_attributes[tagname] = attributes
class_eval %Q{
def #{tagname}(attributes={}, &block)
tag(:#{tagname},attributes,&block)
end
}
end
OPT = :opt
REQ = :req
BOOL = :bool
def self.allowed_attributes
@allowed_attributes
end
def content(text)
@out << text.to_s
nil
end
def comment(text)
@out << "<!-- #{text} -->"
nil
end
def tag(tagname, attributes={})
@out << "<#{tagname}"
allowed = self.class.allowed_attributes[tagname]
attributes.each_pair do |key,value|
raise "unknown attribute: #{key}" unless allowed.include? key
@out << " #{key}='#{value}'"
end
allowed.each_pair do |key,value|
next if attributes.has_key? key
if value == REQ
raise "required attribute '#{key}' missing in <#{tagname}>"
elsif value.is_a? String
@out << " #{key}='#{value}'"
end
end
if block_given?
@out << "\n"
content = yield
if content
@out << content.to_s
end
@out << "</#{tagname}>"
else
@out << "/>\n"
end
nil
end
end
class HTMLForm < XMLGrammar
element :form,
:action => REQ,
:method => "GET",
:enctype => "application/x-www-form-urlencoded",
:name => OPT
element :input,
:type => "text",
:name => OPT,
:value => OPT,
:maxlength => OPT,
:size => OPT,
:src => OPT,
:checked => BOOL,
:disabled => BOOL,
:readonly => BOOL
element :textarea,
:rows => REQ,
:cols => REQ,
:name => OPT,
:disabled => BOOL,
:readonly => BOOL
element :button,
:name => OPT,
:value => OPT,
:type => "submit",
:disabled => OPT
end
puts '--------------------'
p XMLGrammar.instance_variables
p HTMLForm.instance_variables
puts '--------------------'
HTMLForm.generate(STDOUT) do
comment "This is a simple HTML form"
form :name => "registration", :action => "http://www.example.com/register.cgi" do
content "Name:"
input :name => "name"
content "Address:"
textarea :name => "address", :rows=>6, :cols=>40 do
"Please enter your mailing address here"
end
button do
"Submit"
end
end
end