xbrlware-ruby19 1.1.2.19
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +4 -0
- data/Rakefile +2 -0
- data/lib/xbrlware-ruby19/cgi_patch.rb +58 -0
- data/lib/xbrlware-ruby19/constants.rb +29 -0
- data/lib/xbrlware-ruby19/context.rb +193 -0
- data/lib/xbrlware-ruby19/date_util.rb +45 -0
- data/lib/xbrlware-ruby19/float_patch.rb +26 -0
- data/lib/xbrlware-ruby19/hash_util.rb +175 -0
- data/lib/xbrlware-ruby19/instance.rb +475 -0
- data/lib/xbrlware-ruby19/item.rb +123 -0
- data/lib/xbrlware-ruby19/linkbase/calculation_linkbase.rb +181 -0
- data/lib/xbrlware-ruby19/linkbase/definition_linkbase.rb +226 -0
- data/lib/xbrlware-ruby19/linkbase/label_linkbase.rb +132 -0
- data/lib/xbrlware-ruby19/linkbase/linkbase.rb +193 -0
- data/lib/xbrlware-ruby19/linkbase/presentation_linkbase.rb +204 -0
- data/lib/xbrlware-ruby19/meta_util.rb +50 -0
- data/lib/xbrlware-ruby19/ns_aware.rb +5 -0
- data/lib/xbrlware-ruby19/taxonomies/ifrs_taxonomy_20090401.rb +8278 -0
- data/lib/xbrlware-ruby19/taxonomies/us_gaap_taxonomy_20090131.rb +40365 -0
- data/lib/xbrlware-ruby19/taxonomy.rb +143 -0
- data/lib/xbrlware-ruby19/unit.rb +43 -0
- data/lib/xbrlware-ruby19/util.rb +86 -0
- data/lib/xbrlware-ruby19/version.rb +22 -0
- data/lib/xbrlware-ruby19/xml_parser.rb +142 -0
- data/lib/xbrlware-ruby19.rb +73 -0
- data/xbrlware-ruby19.gemspec +27 -0
- metadata +109 -0
@@ -0,0 +1,193 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Author:: xbrlware@bitstat.com
|
4
|
+
#
|
5
|
+
# Copyright:: 2009, 2010 bitstat (http://www.bitstat.com). All Rights Reserved.
|
6
|
+
#
|
7
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
module Xbrlware
|
21
|
+
module Linkbase
|
22
|
+
|
23
|
+
class Linkbase
|
24
|
+
# Creates a Linkbase.
|
25
|
+
#
|
26
|
+
# linkbase_path::
|
27
|
+
# XBRL Linkbase source. Tries to load and parse linkbase from path.
|
28
|
+
#
|
29
|
+
def initialize(linkbase_path)
|
30
|
+
m=Benchmark.measure do
|
31
|
+
begin
|
32
|
+
@linkbase_content = XmlParser.xml_in(linkbase_path, {'ForceContent' => true})
|
33
|
+
rescue Exception
|
34
|
+
$LOG.warn "File ["+linkbase_path+"] is not well formed. Starting reparsing after removing new lines."
|
35
|
+
@linkbase_content = XmlParser.xml_in(File.open(linkbase_path).read.gsub("\n", ""), {'ForceContent' => true})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
bm("Parsing [" + linkbase_path + "] took", m)
|
39
|
+
|
40
|
+
#Populate role map
|
41
|
+
role_map()
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def role_map
|
46
|
+
@role_map={}
|
47
|
+
@linkbase_content["roleRef"].each do |role_ref|
|
48
|
+
href = role_ref["xlink:href"]
|
49
|
+
unless href.index("#").nil?
|
50
|
+
@role_map[role_ref["roleURI"]]= href[href.index("#")+1, href.length]
|
51
|
+
else
|
52
|
+
@role_map[role_ref["roleURI"]]=href
|
53
|
+
end
|
54
|
+
end unless @linkbase_content["roleRef"].nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
public
|
58
|
+
|
59
|
+
def inspect
|
60
|
+
self.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.wireup_relationship(map, parent, child) # :nodoc:
|
64
|
+
|
65
|
+
if child.is_a?(Array)
|
66
|
+
child.each do |c|
|
67
|
+
wireup_relationship(map, parent, c)
|
68
|
+
end
|
69
|
+
return
|
70
|
+
end
|
71
|
+
|
72
|
+
child.parent=parent
|
73
|
+
parent.children.add(child)
|
74
|
+
return unless map.has_key?(child)
|
75
|
+
|
76
|
+
# map contains different instance (that equals to child) as key.
|
77
|
+
# Delete the key, reinsert the proper instance as key
|
78
|
+
children_of_child=map[child]
|
79
|
+
#map.delete(child)
|
80
|
+
map[child]=children_of_child
|
81
|
+
wireup_relationship(map, child, map[child])
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.build_relationship(map) # :nodoc:
|
85
|
+
map.each do |key, value|
|
86
|
+
wireup_relationship(map, key, value)
|
87
|
+
end
|
88
|
+
root_elements=map.keys.select { |key| key.parent.nil?}
|
89
|
+
root_elements.each {|root_element| sort_by_order(root_element)}
|
90
|
+
return root_elements
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.sort_by_order(element) # :nodoc:
|
94
|
+
return if element.children.nil?
|
95
|
+
element.children=element.children.sort_by {|e| (e.respond_to?(:order) && e.order) || "0"}
|
96
|
+
element.children.each do |child|
|
97
|
+
sort_by_order(child)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class Link
|
102
|
+
|
103
|
+
attr_reader :link_type, :title, :role, :href, :arcs
|
104
|
+
|
105
|
+
def initialize(link_type, title, role, href, arcs=nil)
|
106
|
+
@link_type=link_type
|
107
|
+
@role = role
|
108
|
+
@href = href
|
109
|
+
|
110
|
+
@title=title unless title.nil?
|
111
|
+
@title=role.split("/")[-1] if title.nil?
|
112
|
+
@title=@title.split(/(?=[A-Z])/).join(' ')
|
113
|
+
@title.gsub!(/_/, " ")
|
114
|
+
@title.gsub!(/[ ]+/, " ")
|
115
|
+
|
116
|
+
@arcs = arcs
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
def print_arc_hierarchy(verbose_flag="q", arcs=@arcs, indent=0)
|
121
|
+
arcs.each do |arc|
|
122
|
+
str=" " * indent + arc.item_name + "("+(arc.label if arc.respond_to?(:label)).to_s+")"
|
123
|
+
if verbose_flag=="v"
|
124
|
+
str +=" label [" +(arc.label if arc.respond_to?(:label)).to_s+"], role ["+arc.role.to_s+"]"
|
125
|
+
end
|
126
|
+
str += " order ["+arc.order.to_s+"]"
|
127
|
+
puts str
|
128
|
+
print_arc_hierarchy(verbose_flag, arc.children, indent+1) if arc.children
|
129
|
+
end unless arcs.nil?
|
130
|
+
end
|
131
|
+
|
132
|
+
public
|
133
|
+
def inspect
|
134
|
+
self.to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
def print(verbose_flag="q")
|
138
|
+
puts " title ["+title+"] role ["+role+"]"
|
139
|
+
print_arc_hierarchy(verbose_flag)
|
140
|
+
return self.to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
class Arc
|
144
|
+
attr_reader :item_id, :item_name, :role, :label, :href, :order, :priority
|
145
|
+
attr_accessor :items, :children, :parent
|
146
|
+
|
147
|
+
def initialize(item_id, href, role=nil, order=nil, priority=nil, label=nil)
|
148
|
+
@item_id=item_id
|
149
|
+
@item_name = @item_id[0, (@item_id.rindex("_")==nil ? @item_id.size: @item_id.rindex("_"))]
|
150
|
+
@href=href
|
151
|
+
@role=role
|
152
|
+
@order=order.to_i
|
153
|
+
@priority=priority.to_i
|
154
|
+
if label.nil?
|
155
|
+
if href.nil?
|
156
|
+
dash_index=item_id.index("_")
|
157
|
+
dash_index=dash_index.nil? ? 0 :(dash_index+1)
|
158
|
+
label=item_id[dash_index, item_id.length]
|
159
|
+
else
|
160
|
+
label=href[href.index("#")+1, href.length] unless href.index("#").nil?
|
161
|
+
label=href if href.index("#").nil?
|
162
|
+
unless label.index("_").nil?
|
163
|
+
dash_index=label.index("_")
|
164
|
+
label=label[dash_index+1, label.length]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
@label=label
|
169
|
+
@children=Set.new()
|
170
|
+
end
|
171
|
+
|
172
|
+
def has_children?
|
173
|
+
@children.size>0
|
174
|
+
end
|
175
|
+
|
176
|
+
def eql?(o)
|
177
|
+
o.is_a?(Arc) && @item_id == o.item_id
|
178
|
+
end
|
179
|
+
|
180
|
+
def hash
|
181
|
+
@item_id.hash
|
182
|
+
end
|
183
|
+
|
184
|
+
def inspect
|
185
|
+
self.to_s
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Author:: xbrlware@bitstat.com
|
4
|
+
#
|
5
|
+
# Copyright:: 2009, 2010 bitstat (http://www.bitstat.com). All Rights Reserved.
|
6
|
+
#
|
7
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
module Xbrlware
|
21
|
+
module Linkbase
|
22
|
+
class PresentationLinkbase < Linkbase
|
23
|
+
|
24
|
+
# Creates a PresentationLinkbase.
|
25
|
+
#
|
26
|
+
# linkbase_path::
|
27
|
+
# XBRL Presentation Linkbase source. Tries to load and parse presentation linkbase from path.
|
28
|
+
#
|
29
|
+
# instance::
|
30
|
+
# Instance object
|
31
|
+
#
|
32
|
+
# def_linkbase::
|
33
|
+
# DefinitionLinkbase object
|
34
|
+
#
|
35
|
+
# label_linkbase::
|
36
|
+
# optional parameter, LabelLinkbase object
|
37
|
+
def initialize(linkbase_path, instance, def_linkbase, label_linkbase=nil)
|
38
|
+
super linkbase_path
|
39
|
+
@instance=instance
|
40
|
+
@def_linkbase=def_linkbase
|
41
|
+
@label_linkbase=label_linkbase
|
42
|
+
@pre_content_optimized=nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def presentation(role=nil)
|
46
|
+
presentations=[]
|
47
|
+
|
48
|
+
if @pre_content_optimized.nil?
|
49
|
+
pre_content=@linkbase_content["presentationLink"]
|
50
|
+
|
51
|
+
@pre_content_optimized = []
|
52
|
+
pre_content.each_with_index do |pre, index|
|
53
|
+
next if pre["loc"].nil? || pre["presentationArc"].nil?
|
54
|
+
pre["loc"].map! do |e|
|
55
|
+
e["xlink:label"]="#{e['xlink:label']}_#{index}"
|
56
|
+
e
|
57
|
+
end
|
58
|
+
|
59
|
+
pre["presentationArc"].map! do |e|
|
60
|
+
e["xlink:from"]="#{e['xlink:from']}_#{index}"
|
61
|
+
e["xlink:to"]="#{e['xlink:to']}_#{index}"
|
62
|
+
e
|
63
|
+
end
|
64
|
+
selected=@pre_content_optimized.select {|pre_existing| pre_existing["xlink:role"]==pre["xlink:role"]}[0]
|
65
|
+
if selected.nil?
|
66
|
+
@pre_content_optimized << pre
|
67
|
+
else
|
68
|
+
pre["loc"].each do |current|
|
69
|
+
matched_loc=nil
|
70
|
+
selected["loc"].each do |existing|
|
71
|
+
if existing["xlink:href"]==current["xlink:href"]
|
72
|
+
matched_loc=current
|
73
|
+
pre["presentationArc"].each do |arc|
|
74
|
+
arc["xlink:from"] = existing["xlink:label"] if current["xlink:label"]==arc["xlink:from"]
|
75
|
+
arc["xlink:to"] = existing["xlink:label"] if current["xlink:label"]==arc["xlink:to"]
|
76
|
+
end
|
77
|
+
break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
selected["loc"] << current if matched_loc.nil?
|
81
|
+
end
|
82
|
+
selected["presentationArc"] += pre["presentationArc"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@pre_content_optimized.each do |pre|
|
88
|
+
next unless pre["xlink:role"]==role unless role.nil?
|
89
|
+
|
90
|
+
if pre["presentationArc"].nil?
|
91
|
+
presentations << Presentation.new(@instance.entity_details, pre["xlink:title"], pre["xlink:role"], @role_map[pre["xlink:role"]])
|
92
|
+
else
|
93
|
+
definition=nil
|
94
|
+
definition=@def_linkbase.definition(pre["xlink:role"]) unless @def_linkbase.nil?
|
95
|
+
|
96
|
+
dimensions=[]
|
97
|
+
dimensions = definition.dimension_domain_map.keys unless definition.nil?
|
98
|
+
|
99
|
+
contexts_and_arcs=arcs(pre, dimensions)
|
100
|
+
presentations << Presentation.new(@instance.entity_details, pre["xlink:title"], pre["xlink:role"], @role_map[pre["xlink:role"]], contexts_and_arcs["contexts"], contexts_and_arcs["arcs"], definition, @instance, dimensions)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
return presentations[0] unless role.nil?
|
104
|
+
presentations
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def fetch_label(label_name, pref_label)
|
109
|
+
pref_label="http://www.xbrl.org/2003/role/label" if pref_label.nil?
|
110
|
+
label_obj=@label_linkbase.label(label_name, pref_label)
|
111
|
+
label = label_obj.value unless label_obj.nil?
|
112
|
+
return label
|
113
|
+
end
|
114
|
+
|
115
|
+
def arcs(pre, dimensions=[])
|
116
|
+
locators={}
|
117
|
+
pre["loc"].each do |loc|
|
118
|
+
href = loc["xlink:href"]
|
119
|
+
unless href.index("#").nil?
|
120
|
+
locators[loc["xlink:label"]]= href[href.index("#")+1, href.length]
|
121
|
+
else
|
122
|
+
locators[loc["xlink:label"]]=href
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
arc_map={}
|
127
|
+
|
128
|
+
contexts = Set.new()
|
129
|
+
|
130
|
+
pre["presentationArc"].each do |arc|
|
131
|
+
from_label, to_label = nil, nil
|
132
|
+
unless @label_linkbase.nil?
|
133
|
+
to_label = fetch_label(locators[arc["xlink:to"]], arc["preferredLabel"])
|
134
|
+
from_label = fetch_label(locators[arc["xlink:from"]], arc["preferredLabel"])
|
135
|
+
end
|
136
|
+
|
137
|
+
to = Presentation::PresentationArc.new(arc["xlink:to"], locators[arc["xlink:to"]], arc["xlink:arcrole"], arc["order"], arc["priority"], arc["use"], to_label)
|
138
|
+
from = Presentation::PresentationArc.new(arc["xlink:from"], locators[arc["xlink:from"]], role=nil, order=nil, priority=nil, use=nil, label=from_label)
|
139
|
+
|
140
|
+
to_item_name = locators[arc["xlink:to"]].gsub(/.*_/, "")
|
141
|
+
from_item_name = locators[arc["xlink:from"]].gsub(/.*_/, "")
|
142
|
+
|
143
|
+
to_item_map=item_map(@instance.item(to_item_name), dimensions)
|
144
|
+
to.items=to_item_map.values
|
145
|
+
contexts.merge(to_item_map.keys)
|
146
|
+
|
147
|
+
from_item_map=item_map(@instance.item(from_item_name), dimensions)
|
148
|
+
from.items=from_item_map.values
|
149
|
+
contexts.merge(from_item_map.keys)
|
150
|
+
|
151
|
+
if arc_map.has_key?(from)
|
152
|
+
arc_map[from] << to
|
153
|
+
else
|
154
|
+
arc_map[from]=[to]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
return {"contexts" => contexts, "arcs" => Linkbase.build_relationship(arc_map)}
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
private
|
162
|
+
def item_map(items, dimensions=[])
|
163
|
+
item_map={}
|
164
|
+
items.each do |item|
|
165
|
+
if dimensions.size>0
|
166
|
+
dims=item.context.dimensions
|
167
|
+
item_map[item.context]=item if (dimensions-dims).size != dimensions.size && (not item.value.nil?)
|
168
|
+
else
|
169
|
+
item_map[item.context]=item unless item.context.has_explicit_dimensions? || item.value.nil?
|
170
|
+
end
|
171
|
+
end unless items.nil?
|
172
|
+
item_map
|
173
|
+
end
|
174
|
+
|
175
|
+
public
|
176
|
+
class Presentation < Linkbase::Link
|
177
|
+
|
178
|
+
attr_reader :contexts, :definition, :instance, :dimensions, :entity_details
|
179
|
+
|
180
|
+
def initialize(entity_details, title, role, href=nil, contexts=nil, arcs=nil, definition=nil, instance=nil, dimensions=[])
|
181
|
+
super("Presentation", title, role, href, arcs)
|
182
|
+
@entity_details=entity_details
|
183
|
+
@contexts=contexts
|
184
|
+
@definition=definition
|
185
|
+
@instance=instance
|
186
|
+
@dimensions=dimensions
|
187
|
+
end
|
188
|
+
|
189
|
+
def has_dimensions?
|
190
|
+
return @dimensions.size>0
|
191
|
+
end
|
192
|
+
|
193
|
+
class PresentationArc < Linkbase::Link::Arc
|
194
|
+
attr_reader :use
|
195
|
+
|
196
|
+
def initialize(item_id, href, role=nil, order=nil, priority=nil, use=nil, label=nil)
|
197
|
+
super item_id, href, role, order, priority, label
|
198
|
+
@use=use
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Author:: xbrlware@bitstat.com
|
4
|
+
#
|
5
|
+
# Copyright:: 2009, 2010 bitstat (http://www.bitstat.com). All Rights Reserved.
|
6
|
+
#
|
7
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
16
|
+
# implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
module Xbrlware
|
21
|
+
module MetaUtil # :nodoc:
|
22
|
+
def self.introduce_instance_var(o, i_var_name, i_var_value)
|
23
|
+
o.instance_variable_set("@#{i_var_name}", i_var_value)
|
24
|
+
o.instance_eval %{
|
25
|
+
def #{i_var_name}
|
26
|
+
self.instance_variable_get("@#{i_var_name}")
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.introduce_instance_writer(o, method_name, i_var_name)
|
32
|
+
o.instance_eval %{
|
33
|
+
def #{method_name}=(value)
|
34
|
+
self.instance_variable_set("@#{i_var_name}", value)
|
35
|
+
end
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.introduce_instance_alias(o, alias_name, actual_name)
|
40
|
+
o.instance_eval %{
|
41
|
+
alias :#{alias_name} :#{actual_name}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.eval_on_instance(o, method_block)
|
46
|
+
p "#{o.class}"
|
47
|
+
o.instance_eval method_block
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|