hobo 1.0.3 → 1.1.0.pre0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +0 -66
- data/README +3 -0
- data/Rakefile +7 -7
- data/doctest/model.rdoctest +0 -2
- data/doctest/multi_model_forms.rdoctest +0 -2
- data/doctest/scopes.rdoctest +13 -21
- data/lib/active_record/association_collection.rb +7 -16
- data/lib/hobo.rb +10 -65
- data/lib/hobo/accessible_associations.rb +1 -5
- data/lib/hobo/authentication_support.rb +1 -1
- data/lib/hobo/controller.rb +5 -5
- data/lib/hobo/hobo_helper.rb +0 -84
- data/lib/hobo/lifecycles/lifecycle.rb +37 -31
- data/lib/hobo/lifecycles/transition.rb +1 -2
- data/lib/hobo/model.rb +13 -21
- data/lib/hobo/model_controller.rb +8 -8
- data/lib/hobo/rapid_helper.rb +12 -1
- data/lib/hobo/scopes/automatic_scopes.rb +26 -13
- data/lib/hobo/scopes/named_scope_extensions.rb +16 -28
- data/lib/hobo/user_controller.rb +1 -0
- data/lib/hobo/view_hints.rb +1 -5
- data/rails_generators/hobo/templates/initializer.rb +1 -1
- data/rails_generators/hobo_front_controller/templates/summary.dryml +4 -2
- data/rails_generators/hobo_model/hobo_model_generator.rb +12 -0
- data/rails_generators/hobo_model/templates/model.rb +9 -2
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +98 -23
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +1 -1
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +3 -1
- data/{dryml_generators → rapid_generators}/rapid/cards.dryml.erb +0 -0
- data/{dryml_generators → rapid_generators}/rapid/forms.dryml.erb +0 -0
- data/{dryml_generators → rapid_generators}/rapid/pages.dryml.erb +1 -1
- data/taglibs/rapid.dryml +2 -0
- data/taglibs/rapid_core.dryml +10 -9
- data/taglibs/rapid_forms.dryml +70 -35
- data/taglibs/rapid_lifecycles.dryml +17 -4
- data/taglibs/rapid_plus.dryml +3 -3
- data/taglibs/rapid_summary.dryml +11 -0
- data/taglibs/rapid_user_pages.dryml +39 -28
- data/tasks/hobo_tasks.rake +1 -1
- metadata +45 -61
- data/hobo.gemspec +0 -226
- data/lib/hobo/dryml.rb +0 -188
- data/lib/hobo/dryml/dryml_builder.rb +0 -140
- data/lib/hobo/dryml/dryml_doc.rb +0 -159
- data/lib/hobo/dryml/dryml_generator.rb +0 -263
- data/lib/hobo/dryml/dryml_support_controller.rb +0 -13
- data/lib/hobo/dryml/parser.rb +0 -3
- data/lib/hobo/dryml/parser/attribute.rb +0 -41
- data/lib/hobo/dryml/parser/base_parser.rb +0 -254
- data/lib/hobo/dryml/parser/document.rb +0 -57
- data/lib/hobo/dryml/parser/element.rb +0 -27
- data/lib/hobo/dryml/parser/elements.rb +0 -45
- data/lib/hobo/dryml/parser/source.rb +0 -58
- data/lib/hobo/dryml/parser/text.rb +0 -13
- data/lib/hobo/dryml/parser/tree_parser.rb +0 -67
- data/lib/hobo/dryml/part_context.rb +0 -137
- data/lib/hobo/dryml/scoped_variables.rb +0 -42
- data/lib/hobo/dryml/tag_parameters.rb +0 -36
- data/lib/hobo/dryml/taglib.rb +0 -123
- data/lib/hobo/dryml/template.rb +0 -1019
- data/lib/hobo/dryml/template_environment.rb +0 -613
- data/lib/hobo/dryml/template_handler.rb +0 -187
- data/lib/hobo/static_tags +0 -98
- data/taglibs/core.dryml +0 -104
@@ -1,263 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
require 'set'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
require 'action_controller/dispatcher'
|
6
|
-
|
7
|
-
module Hobo
|
8
|
-
|
9
|
-
module Dryml
|
10
|
-
|
11
|
-
class DrymlGenerator
|
12
|
-
|
13
|
-
TEMPLATES = "#{HOBO_ROOT}/dryml_generators"
|
14
|
-
OUTPUT = "#{RAILS_ROOT}/app/views/taglibs/auto"
|
15
|
-
|
16
|
-
HEADER = "<!-- AUTOMATICALLY GENERATED FILE - DO NOT EDIT -->\n\n"
|
17
|
-
|
18
|
-
class << self
|
19
|
-
attr_accessor :run_on_every_request
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.enable
|
23
|
-
|
24
|
-
# Unfortunately the dispatcher callbacks don't give us the hook we need (after routes are reloaded)
|
25
|
-
# so we have to alias_method_chain
|
26
|
-
ActionController::Dispatcher.class_eval do
|
27
|
-
|
28
|
-
if respond_to? :reload_application
|
29
|
-
#Rails 2.3
|
30
|
-
class << self
|
31
|
-
def reload_application_with_dryml_generators
|
32
|
-
reload_application_without_dryml_generators
|
33
|
-
DrymlGenerator.run unless Hobo::Dryml::DrymlGenerator.run_on_every_request == false || Rails.env.production?
|
34
|
-
end
|
35
|
-
alias_method_chain :reload_application, :dryml_generators
|
36
|
-
end
|
37
|
-
else
|
38
|
-
#Rails <= 2.2
|
39
|
-
def reload_application_with_dryml_generators
|
40
|
-
reload_application_without_dryml_generators
|
41
|
-
DrymlGenerator.run unless Hobo::Dryml::DrymlGenerator.run_on_every_request == false || Rails.env.production?
|
42
|
-
end
|
43
|
-
alias_method_chain :reload_application, :dryml_generators
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.run
|
49
|
-
@generator ||= DrymlGenerator.new
|
50
|
-
@generator.run
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
def initialize
|
55
|
-
@templates = {}
|
56
|
-
@digests = {}
|
57
|
-
load_templates
|
58
|
-
end
|
59
|
-
|
60
|
-
attr_accessor :subsite
|
61
|
-
|
62
|
-
|
63
|
-
def load_templates
|
64
|
-
Dir["#{TEMPLATES}/**/*.dryml.erb"].each do |f|
|
65
|
-
name = f[TEMPLATES.length + 1..-11]
|
66
|
-
erb = File.read(f)
|
67
|
-
@templates[name] = ERB.new(erb, nil, '-').src
|
68
|
-
|
69
|
-
# Create output directories and parents as required
|
70
|
-
[nil, *Hobo.subsites].each do |s|
|
71
|
-
FileUtils.mkdir_p(File.dirname("#{output_dir s}/#{name}"))
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
def run
|
78
|
-
# Ensure all view hints loaded before running
|
79
|
-
Hobo::Model.all_models.*.view_hints
|
80
|
-
|
81
|
-
[nil, *Hobo.subsites].each { |s| run_for_subsite(s) }
|
82
|
-
end
|
83
|
-
|
84
|
-
|
85
|
-
def run_for_subsite(subsite)
|
86
|
-
self.subsite = subsite
|
87
|
-
@templates.each_pair do |name, src|
|
88
|
-
run_one(name, src)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
def output_dir(s=subsite)
|
94
|
-
s ? "#{OUTPUT}/#{s}" : OUTPUT
|
95
|
-
end
|
96
|
-
|
97
|
-
|
98
|
-
def run_one(name, src)
|
99
|
-
dryml = instance_eval(src, name)
|
100
|
-
if dryml_changed?(name, dryml)
|
101
|
-
out = HEADER + dryml
|
102
|
-
File.open("#{output_dir}/#{name}.dryml", 'w') { |f| f.write(out) }
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
def dryml_changed?(name, dryml)
|
108
|
-
key = "#{subsite}/#{name}"
|
109
|
-
d = digest dryml
|
110
|
-
if d != @digests[key]
|
111
|
-
@digests[key] = d
|
112
|
-
true
|
113
|
-
else
|
114
|
-
false
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
def digest(s)
|
120
|
-
OpenSSL::Digest::SHA1.hexdigest(s)
|
121
|
-
end
|
122
|
-
|
123
|
-
|
124
|
-
# --- Helper methods for the templates --- #
|
125
|
-
|
126
|
-
attr_reader :controller
|
127
|
-
|
128
|
-
|
129
|
-
def controllers
|
130
|
-
Hobo::ModelController.all_controllers(subsite).sort_by &:name
|
131
|
-
end
|
132
|
-
|
133
|
-
|
134
|
-
def models
|
135
|
-
Hobo::Model.all_models.sort_by &:name
|
136
|
-
end
|
137
|
-
|
138
|
-
def each_controller
|
139
|
-
controllers.each do |controller|
|
140
|
-
@controller = controller
|
141
|
-
yield
|
142
|
-
end
|
143
|
-
@controller = nil
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
def each_model
|
148
|
-
models.each do |model|
|
149
|
-
@model = model
|
150
|
-
yield
|
151
|
-
end
|
152
|
-
@model = nil
|
153
|
-
end
|
154
|
-
|
155
|
-
|
156
|
-
def model
|
157
|
-
@model || @controller.model
|
158
|
-
end
|
159
|
-
|
160
|
-
|
161
|
-
def model_name(*options)
|
162
|
-
name = :plural.in?(options) ? model.view_hints.model_name_plural : model.view_hints.model_name
|
163
|
-
name = name.titleize.downcase if :lowercase.in?(options)
|
164
|
-
name = name.camelize if :camel.in?(options)
|
165
|
-
name
|
166
|
-
end
|
167
|
-
|
168
|
-
# escape single quotes and backslashes for use in a single
|
169
|
-
# quoted string
|
170
|
-
def sq_escape(s)
|
171
|
-
s.gsub(/[\\]/, "\\\\\\\\").gsub(/'/, "\\\\'")
|
172
|
-
end
|
173
|
-
|
174
|
-
|
175
|
-
def model_class
|
176
|
-
model.name.underscore.gsub('_', '-').gsub('/', '--')
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
def view_hints
|
181
|
-
model.view_hints
|
182
|
-
end
|
183
|
-
|
184
|
-
|
185
|
-
def through_collection_names(klass=model)
|
186
|
-
klass.reflections.values.select do |refl|
|
187
|
-
refl.macro == :has_many && refl.options[:through]
|
188
|
-
end.map {|x| x.options[:through]}
|
189
|
-
end
|
190
|
-
|
191
|
-
|
192
|
-
def linkable?(*args)
|
193
|
-
options = args.extract_options!
|
194
|
-
options[:subsite] = subsite
|
195
|
-
klass, action = if args.length == 1
|
196
|
-
[model, args.first]
|
197
|
-
else
|
198
|
-
args
|
199
|
-
end
|
200
|
-
Hobo::ModelRouter.linkable?(klass, action, options)
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
def sortable_collection?(collection, model=self.model)
|
205
|
-
# There's no perfect way to detect for this, given that acts_as_list
|
206
|
-
# does not provide any metadata to reflect on, but if the :order
|
207
|
-
# option is the same as the target classes position_column, that's a
|
208
|
-
# pretty safe bet
|
209
|
-
if defined? ActiveRecord::Acts::List::InstanceMethods
|
210
|
-
refl = model.reflections[collection]
|
211
|
-
klass = refl.klass
|
212
|
-
klass < ActiveRecord::Acts::List::InstanceMethods &&
|
213
|
-
klass.new.position_column == refl.options[:order].to_s
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
|
218
|
-
def standard_fields(*args)
|
219
|
-
klass = args.first.is_a?(Class) ? args.shift : model
|
220
|
-
extras = args
|
221
|
-
|
222
|
-
fields = klass.attr_order.*.to_s & klass.content_columns.*.name
|
223
|
-
|
224
|
-
fields -= %w{created_at updated_at created_on updated_on deleted_at} unless extras.include?(:include_timestamps)
|
225
|
-
|
226
|
-
bt = extras.include?(:belongs_to)
|
227
|
-
hm = extras.include?(:has_many)
|
228
|
-
klass.reflections.values.sort_by { |refl| refl.name.to_s }.map do |refl|
|
229
|
-
fields << refl.name.to_s if bt && refl.macro == :belongs_to
|
230
|
-
fields << refl.name.to_s if hm && refl.macro == :has_many && refl.options[:accessible]
|
231
|
-
end
|
232
|
-
|
233
|
-
fields.reject! { |f| model.never_show? f }
|
234
|
-
fields
|
235
|
-
end
|
236
|
-
|
237
|
-
|
238
|
-
def creators
|
239
|
-
defined?(model::Lifecycle) ? model::Lifecycle.publishable_creators : []
|
240
|
-
end
|
241
|
-
|
242
|
-
def transitions
|
243
|
-
defined?(model::Lifecycle) ? model::Lifecycle.publishable_transitions : []
|
244
|
-
end
|
245
|
-
|
246
|
-
def creator_names
|
247
|
-
creators.map { |c| c.name.to_s }
|
248
|
-
end
|
249
|
-
|
250
|
-
def transition_names
|
251
|
-
transitions.map { |t| t.name.to_s }.uniq
|
252
|
-
end
|
253
|
-
|
254
|
-
|
255
|
-
def a_or_an(word)
|
256
|
-
(word =~ /^[aeiou]/i ? "an " : "a ") + word
|
257
|
-
end
|
258
|
-
|
259
|
-
end
|
260
|
-
|
261
|
-
end
|
262
|
-
|
263
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class Hobo::Dryml::DrymlSupportController < ActionController::Base
|
2
|
-
|
3
|
-
def edit_source
|
4
|
-
dryml_editor = ENV['DRYML_EDITOR']
|
5
|
-
if dryml_editor
|
6
|
-
file = File.join(RAILS_ROOT, params[:file])
|
7
|
-
command = dryml_editor.sub(":file", file).sub(":line", params[:line])
|
8
|
-
system(command)
|
9
|
-
end
|
10
|
-
render :nothing => true
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
data/lib/hobo/dryml/parser.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module Hobo::Dryml::Parser
|
2
|
-
|
3
|
-
class Attribute < REXML::Attribute
|
4
|
-
|
5
|
-
def initialize(first, second=nil, parent=nil)
|
6
|
-
super
|
7
|
-
if first.is_a?(String) && second == true
|
8
|
-
@value = true
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def value
|
13
|
-
if has_rhs?
|
14
|
-
super
|
15
|
-
else
|
16
|
-
element.document.default_attribute_value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_string
|
21
|
-
if has_rhs?
|
22
|
-
super
|
23
|
-
else
|
24
|
-
@expanded_name
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def has_rhs?
|
29
|
-
@value != true
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
# Override to supress Text.check call
|
34
|
-
def element=( element )
|
35
|
-
@element = element
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,254 +0,0 @@
|
|
1
|
-
module Hobo::Dryml::Parser
|
2
|
-
|
3
|
-
class BaseParser < REXML::Parsers::BaseParser
|
4
|
-
|
5
|
-
NEW_REX = defined?(REXML::VERSION) && REXML::VERSION =~ /3\.1\.(\d)(?:\.(\d))?/ && $1.to_i*1000 + $2.to_i >= 7002
|
6
|
-
|
7
|
-
DRYML_NAME_STR = "#{NCNAME_STR}(?::(?:#{NCNAME_STR})?)?"
|
8
|
-
DRYML_ATTRIBUTE_PATTERN = if NEW_REX
|
9
|
-
/\s*(#{NAME_STR})(?:\s*=\s*(["'])(.*?)\4)?/um
|
10
|
-
else
|
11
|
-
/\s*(#{NAME_STR})(?:\s*=\s*(["'])(.*?)\2)?/um
|
12
|
-
end
|
13
|
-
DRYML_TAG_MATCH = if NEW_REX
|
14
|
-
/^<((?>#{DRYML_NAME_STR}))\s*((?>\s+#{NAME_STR}(?:\s*=\s*(["']).*?\5)?)*)\s*(\/)?>/um
|
15
|
-
else
|
16
|
-
/^<((?>#{DRYML_NAME_STR}))\s*((?>\s+#{NAME_STR}(?:\s*=\s*(["']).*?\3)?)*)\s*(\/)?>/um
|
17
|
-
end
|
18
|
-
DRYML_CLOSE_MATCH = /^\s*<\/(#{DRYML_NAME_STR})\s*>/um
|
19
|
-
|
20
|
-
# For compatibility with REXML 3.1.7.3
|
21
|
-
IDENTITY = /^([!\*\w\-]+)(\s+#{NCNAME_STR})?(\s+["'](.*?)['"])?(\s+['"](.*?)["'])?/u
|
22
|
-
|
23
|
-
def pull
|
24
|
-
if @closed
|
25
|
-
x, @closed = @closed, nil
|
26
|
-
return [ :end_element, x, false ]
|
27
|
-
end
|
28
|
-
return [ :end_document ] if empty?
|
29
|
-
return @stack.shift if @stack.size > 0
|
30
|
-
#STDERR.puts @source.encoding
|
31
|
-
@source.read if @source.buffer.size<2
|
32
|
-
#STDERR.puts "BUFFER = #{@source.buffer.inspect}"
|
33
|
-
if @document_status == nil
|
34
|
-
#@source.consume( /^\s*/um )
|
35
|
-
word = @source.match( /^((?:\s+)|(?:<[^>]*>))/um ) #word = @source.match(/(<[^>]*)>/um)
|
36
|
-
word = word[1] unless word.nil?
|
37
|
-
#STDERR.puts "WORD = #{word.inspect}"
|
38
|
-
case word
|
39
|
-
when COMMENT_START
|
40
|
-
return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ]
|
41
|
-
when XMLDECL_START
|
42
|
-
#STDERR.puts "XMLDECL"
|
43
|
-
results = @source.match( XMLDECL_PATTERN, true )[1]
|
44
|
-
version = VERSION.match( results )
|
45
|
-
version = version[1] unless version.nil?
|
46
|
-
encoding = ENCODING.match(results)
|
47
|
-
encoding = encoding[1] unless encoding.nil?
|
48
|
-
@source.encoding = encoding
|
49
|
-
standalone = STANDALONE.match(results)
|
50
|
-
standalone = standalone[1] unless standalone.nil?
|
51
|
-
return [ :xmldecl, version, encoding, standalone ]
|
52
|
-
when INSTRUCTION_START
|
53
|
-
return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]
|
54
|
-
when DOCTYPE_START
|
55
|
-
md = @source.match( DOCTYPE_PATTERN, true )
|
56
|
-
#@nsstack.unshift(curr_ns=Set.new)
|
57
|
-
identity = md[1]
|
58
|
-
close = md[2]
|
59
|
-
identity =~ IDENTITY
|
60
|
-
name = $1
|
61
|
-
raise REXML::ParseException.new("DOCTYPE is missing a name") if name.nil?
|
62
|
-
pub_sys = $2.nil? ? nil : $2.strip
|
63
|
-
long_name = $4.nil? ? nil : $4.strip
|
64
|
-
uri = $6.nil? ? nil : $6.strip
|
65
|
-
args = [ :start_doctype, name, pub_sys, long_name, uri ]
|
66
|
-
if close == ">"
|
67
|
-
@document_status = :after_doctype
|
68
|
-
@source.read if @source.buffer.size<2
|
69
|
-
md = @source.match(/^\s*/um, true)
|
70
|
-
@stack << [ :end_doctype ]
|
71
|
-
else
|
72
|
-
@document_status = :in_doctype
|
73
|
-
end
|
74
|
-
return args
|
75
|
-
when /^\s+/
|
76
|
-
else
|
77
|
-
@document_status = :after_doctype
|
78
|
-
@source.read if @source.buffer.size<2
|
79
|
-
md = @source.match(/\s*/um, true)
|
80
|
-
if @source.encoding == "UTF-8"
|
81
|
-
if @source.buffer.respond_to? :force_encoding
|
82
|
-
@source.buffer.force_encoding(Encoding::UTF_8)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
if @document_status == :in_doctype
|
88
|
-
md = @source.match(/\s*(.*?>)/um)
|
89
|
-
case md[1]
|
90
|
-
when SYSTEMENTITY
|
91
|
-
match = @source.match( SYSTEMENTITY, true )[1]
|
92
|
-
return [ :externalentity, match ]
|
93
|
-
|
94
|
-
when ELEMENTDECL_START
|
95
|
-
return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]
|
96
|
-
|
97
|
-
when ENTITY_START
|
98
|
-
match = @source.match( ENTITYDECL, true ).to_a.compact
|
99
|
-
match[0] = :entitydecl
|
100
|
-
ref = false
|
101
|
-
if match[1] == '%'
|
102
|
-
ref = true
|
103
|
-
match.delete_at 1
|
104
|
-
end
|
105
|
-
# Now we have to sort out what kind of entity reference this is
|
106
|
-
if match[2] == 'SYSTEM'
|
107
|
-
# External reference
|
108
|
-
match[3] = match[3][1..-2] # PUBID
|
109
|
-
match.delete_at(4) if match.size > 4 # Chop out NDATA decl
|
110
|
-
# match is [ :entity, name, SYSTEM, pubid(, ndata)? ]
|
111
|
-
elsif match[2] == 'PUBLIC'
|
112
|
-
# External reference
|
113
|
-
match[3] = match[3][1..-2] # PUBID
|
114
|
-
match[4] = match[4][1..-2] # HREF
|
115
|
-
# match is [ :entity, name, PUBLIC, pubid, href ]
|
116
|
-
else
|
117
|
-
match[2] = match[2][1..-2]
|
118
|
-
match.pop if match.size == 4
|
119
|
-
# match is [ :entity, name, value ]
|
120
|
-
end
|
121
|
-
match << '%' if ref
|
122
|
-
return match
|
123
|
-
when ATTLISTDECL_START
|
124
|
-
md = @source.match( ATTLISTDECL_PATTERN, true )
|
125
|
-
raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil?
|
126
|
-
element = md[1]
|
127
|
-
contents = md[0]
|
128
|
-
|
129
|
-
pairs = {}
|
130
|
-
values = md[0].scan( ATTDEF_RE )
|
131
|
-
values.each do |attdef|
|
132
|
-
unless attdef[3] == "#IMPLIED"
|
133
|
-
attdef.compact!
|
134
|
-
val = attdef[3]
|
135
|
-
val = attdef[4] if val == "#FIXED "
|
136
|
-
pairs[attdef[0]] = val
|
137
|
-
if attdef[0] =~ /^xmlns:(.*)/
|
138
|
-
#@nsstack[0] << $1
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
return [ :attlistdecl, element, pairs, contents ]
|
143
|
-
when NOTATIONDECL_START
|
144
|
-
md = nil
|
145
|
-
if @source.match( PUBLIC )
|
146
|
-
md = @source.match( PUBLIC, true )
|
147
|
-
vals = [md[1],md[2],md[4],md[6]]
|
148
|
-
elsif @source.match( SYSTEM )
|
149
|
-
md = @source.match( SYSTEM, true )
|
150
|
-
vals = [md[1],md[2],nil,md[4]]
|
151
|
-
else
|
152
|
-
raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source )
|
153
|
-
end
|
154
|
-
return [ :notationdecl, *vals ]
|
155
|
-
when CDATA_END
|
156
|
-
@document_status = :after_doctype
|
157
|
-
@source.match( CDATA_END, true )
|
158
|
-
return [ :end_doctype ]
|
159
|
-
end
|
160
|
-
end
|
161
|
-
begin
|
162
|
-
if @source.buffer[0] == ?<
|
163
|
-
if @source.buffer[1] == ?/
|
164
|
-
#@nsstack.shift
|
165
|
-
last_tag, line_no = @tags.pop
|
166
|
-
#md = @source.match_to_consume( '>', CLOSE_MATCH)
|
167
|
-
md = @source.match(DRYML_CLOSE_MATCH, true)
|
168
|
-
|
169
|
-
valid_end_tag = last_tag =~ /^#{Regexp.escape(md[1])}(:.*)?$/
|
170
|
-
raise REXML::ParseException.new( "Missing end tag for "+
|
171
|
-
"'#{last_tag}' (line #{line_no}) (got \"#{md[1]}\")",
|
172
|
-
@source) unless valid_end_tag
|
173
|
-
return [ :end_element, last_tag, true ]
|
174
|
-
elsif @source.buffer[1] == ?!
|
175
|
-
md = @source.match(/\A(\s*[^>]*>)/um)
|
176
|
-
#STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
|
177
|
-
raise REXML::ParseException.new("Malformed node", @source) unless md
|
178
|
-
if md[0][2] == ?-
|
179
|
-
md = @source.match( COMMENT_PATTERN, true )
|
180
|
-
|
181
|
-
case md[1]
|
182
|
-
when /--/, /-$/
|
183
|
-
raise REXML::ParseException.new("Malformed comment", @source)
|
184
|
-
end
|
185
|
-
|
186
|
-
return [ :comment, md[1] ] if md
|
187
|
-
else
|
188
|
-
md = @source.match( CDATA_PATTERN, true )
|
189
|
-
return [ :cdata, md[1] ] if md
|
190
|
-
end
|
191
|
-
raise REXML::ParseException.new( "Declarations can only occur "+
|
192
|
-
"in the doctype declaration.", @source)
|
193
|
-
elsif @source.buffer[1] == ??
|
194
|
-
md = @source.match( INSTRUCTION_PATTERN, true )
|
195
|
-
return [ :processing_instruction, md[1], md[2] ] if md
|
196
|
-
raise REXML::ParseException.new( "Bad instruction declaration",
|
197
|
-
@source)
|
198
|
-
else
|
199
|
-
# Get the next tag
|
200
|
-
md = @source.match(DRYML_TAG_MATCH, true)
|
201
|
-
unless md
|
202
|
-
# Check for missing attribute quotes
|
203
|
-
raise REXML::ParseException.new("missing attribute quote", @source) if
|
204
|
-
defined?(MISSING_ATTRIBUTE_QUOTES) && @source.match(MISSING_ATTRIBUTE_QUOTES)
|
205
|
-
raise REXML::ParseException.new("malformed XML: missing tag start", @source)
|
206
|
-
|
207
|
-
end
|
208
|
-
attributes = {}
|
209
|
-
#@nsstack.unshift(curr_ns=Set.new)
|
210
|
-
if md[2].size > 0
|
211
|
-
attrs = md[2].scan(DRYML_ATTRIBUTE_PATTERN)
|
212
|
-
raise REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0
|
213
|
-
attrs.each { |a,b,c,d,e|
|
214
|
-
val = NEW_REX ? e : c
|
215
|
-
if attributes.has_key? a
|
216
|
-
msg = "Duplicate attribute #{a.inspect}"
|
217
|
-
raise REXML::ParseException.new( msg, @source, self)
|
218
|
-
end
|
219
|
-
attributes[a] = val || true
|
220
|
-
}
|
221
|
-
end
|
222
|
-
|
223
|
-
if md[NEW_REX ? 6 : 4]
|
224
|
-
@closed = md[1]
|
225
|
-
#@nsstack.shift
|
226
|
-
else
|
227
|
-
cl = @source.current_line
|
228
|
-
@tags.push( [md[1], cl && cl[2]] )
|
229
|
-
end
|
230
|
-
return [ :start_element, md[1], attributes, md[0],
|
231
|
-
@source.respond_to?(:last_match_offset) && @source.last_match_offset ]
|
232
|
-
end
|
233
|
-
else
|
234
|
-
md = @source.match( TEXT_PATTERN, true )
|
235
|
-
if md[0].length == 0
|
236
|
-
@source.match( /(\s+)/, true )
|
237
|
-
end
|
238
|
-
#STDERR.puts "GOT #{md[1].inspect}" unless md[0].length == 0
|
239
|
-
#return [ :text, "" ] if md[0].length == 0
|
240
|
-
# unnormalized = Text::unnormalize( md[1], self )
|
241
|
-
# return PullEvent.new( :text, md[1], unnormalized )
|
242
|
-
return [ :text, md[1] ]
|
243
|
-
end
|
244
|
-
rescue REXML::ParseException
|
245
|
-
raise
|
246
|
-
rescue Exception, NameError => error
|
247
|
-
raise REXML::ParseException.new( "Exception parsing",
|
248
|
-
@source, self, (error ? error : $!) )
|
249
|
-
end
|
250
|
-
return [ :dummy ]
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
end
|