hobo 1.0.3 → 1.1.0.pre0
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/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
|