treat 0.2.5 → 1.0.0

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.
Files changed (242) hide show
  1. data/LICENSE +3 -3
  2. data/README.md +33 -0
  3. data/files/INFO +1 -0
  4. data/lib/treat.rb +40 -105
  5. data/lib/treat/ai.rb +12 -0
  6. data/lib/treat/ai/classifiers/id3.rb +27 -0
  7. data/lib/treat/categories.rb +82 -35
  8. data/lib/treat/categorizable.rb +44 -0
  9. data/lib/treat/classification.rb +61 -0
  10. data/lib/treat/configurable.rb +115 -0
  11. data/lib/treat/data_set.rb +42 -0
  12. data/lib/treat/dependencies.rb +24 -0
  13. data/lib/treat/downloader.rb +87 -0
  14. data/lib/treat/entities.rb +68 -66
  15. data/lib/treat/entities/abilities.rb +10 -0
  16. data/lib/treat/entities/abilities/buildable.rb +327 -0
  17. data/lib/treat/entities/abilities/checkable.rb +31 -0
  18. data/lib/treat/entities/abilities/copyable.rb +45 -0
  19. data/lib/treat/entities/abilities/countable.rb +51 -0
  20. data/lib/treat/entities/abilities/debuggable.rb +83 -0
  21. data/lib/treat/entities/abilities/delegatable.rb +123 -0
  22. data/lib/treat/entities/abilities/doable.rb +62 -0
  23. data/lib/treat/entities/abilities/exportable.rb +11 -0
  24. data/lib/treat/entities/abilities/iterable.rb +115 -0
  25. data/lib/treat/entities/abilities/magical.rb +83 -0
  26. data/lib/treat/entities/abilities/registrable.rb +74 -0
  27. data/lib/treat/entities/abilities/stringable.rb +91 -0
  28. data/lib/treat/entities/entities.rb +104 -0
  29. data/lib/treat/entities/entity.rb +122 -245
  30. data/lib/treat/exception.rb +4 -4
  31. data/lib/treat/extractors.rb +77 -80
  32. data/lib/treat/extractors/keywords/tf_idf.rb +56 -22
  33. data/lib/treat/extractors/language/what_language.rb +50 -45
  34. data/lib/treat/extractors/name_tag/stanford.rb +55 -0
  35. data/lib/treat/extractors/tf_idf/native.rb +87 -0
  36. data/lib/treat/extractors/time/chronic.rb +55 -0
  37. data/lib/treat/extractors/time/nickel.rb +86 -62
  38. data/lib/treat/extractors/time/ruby.rb +53 -0
  39. data/lib/treat/extractors/topic_words/lda.rb +67 -58
  40. data/lib/treat/extractors/topics/reuters.rb +100 -87
  41. data/lib/treat/formatters.rb +39 -35
  42. data/lib/treat/formatters/readers/abw.rb +49 -29
  43. data/lib/treat/formatters/readers/autoselect.rb +37 -33
  44. data/lib/treat/formatters/readers/doc.rb +19 -13
  45. data/lib/treat/formatters/readers/html.rb +52 -30
  46. data/lib/treat/formatters/readers/image.rb +41 -40
  47. data/lib/treat/formatters/readers/odt.rb +59 -45
  48. data/lib/treat/formatters/readers/pdf.rb +28 -25
  49. data/lib/treat/formatters/readers/txt.rb +12 -15
  50. data/lib/treat/formatters/readers/xml.rb +73 -36
  51. data/lib/treat/formatters/serializers/xml.rb +80 -79
  52. data/lib/treat/formatters/serializers/yaml.rb +19 -18
  53. data/lib/treat/formatters/unserializers/autoselect.rb +12 -22
  54. data/lib/treat/formatters/unserializers/xml.rb +94 -99
  55. data/lib/treat/formatters/unserializers/yaml.rb +20 -19
  56. data/lib/treat/formatters/visualizers/dot.rb +132 -132
  57. data/lib/treat/formatters/visualizers/standoff.rb +52 -44
  58. data/lib/treat/formatters/visualizers/tree.rb +26 -29
  59. data/lib/treat/groupable.rb +153 -0
  60. data/lib/treat/helpers/decimal_point_escaper.rb +22 -0
  61. data/lib/treat/inflectors.rb +50 -45
  62. data/lib/treat/inflectors/cardinalizers/linguistics.rb +40 -0
  63. data/lib/treat/inflectors/conjugators/linguistics.rb +55 -0
  64. data/lib/treat/inflectors/declensors/active_support.rb +31 -0
  65. data/lib/treat/inflectors/declensors/english.rb +38 -0
  66. data/lib/treat/inflectors/declensors/english/inflect.rb +288 -0
  67. data/lib/treat/inflectors/declensors/linguistics.rb +49 -0
  68. data/lib/treat/inflectors/ordinalizers/linguistics.rb +17 -0
  69. data/lib/treat/inflectors/stemmers/porter.rb +160 -0
  70. data/lib/treat/inflectors/stemmers/porter_c.rb +24 -0
  71. data/lib/treat/inflectors/stemmers/uea.rb +28 -0
  72. data/lib/treat/installer.rb +308 -0
  73. data/lib/treat/kernel.rb +105 -27
  74. data/lib/treat/languages.rb +122 -88
  75. data/lib/treat/languages/arabic.rb +15 -15
  76. data/lib/treat/languages/chinese.rb +15 -15
  77. data/lib/treat/languages/dutch.rb +15 -15
  78. data/lib/treat/languages/english.rb +61 -62
  79. data/lib/treat/languages/french.rb +19 -19
  80. data/lib/treat/languages/german.rb +20 -20
  81. data/lib/treat/languages/greek.rb +15 -15
  82. data/lib/treat/languages/italian.rb +16 -16
  83. data/lib/treat/languages/polish.rb +15 -15
  84. data/lib/treat/languages/portuguese.rb +15 -15
  85. data/lib/treat/languages/russian.rb +15 -15
  86. data/lib/treat/languages/spanish.rb +16 -16
  87. data/lib/treat/languages/swedish.rb +16 -16
  88. data/lib/treat/lexicalizers.rb +34 -55
  89. data/lib/treat/lexicalizers/categorizers/from_tag.rb +54 -0
  90. data/lib/treat/lexicalizers/sensers/wordnet.rb +57 -0
  91. data/lib/treat/lexicalizers/sensers/wordnet/synset.rb +71 -0
  92. data/lib/treat/lexicalizers/taggers/brill.rb +70 -0
  93. data/lib/treat/lexicalizers/taggers/brill/patch.rb +61 -0
  94. data/lib/treat/lexicalizers/taggers/lingua.rb +90 -0
  95. data/lib/treat/lexicalizers/taggers/stanford.rb +97 -0
  96. data/lib/treat/linguistics.rb +9 -0
  97. data/lib/treat/linguistics/categories.rb +11 -0
  98. data/lib/treat/linguistics/tags.rb +422 -0
  99. data/lib/treat/loaders/linguistics.rb +30 -0
  100. data/lib/treat/loaders/stanford.rb +27 -0
  101. data/lib/treat/object.rb +1 -0
  102. data/lib/treat/processors.rb +37 -44
  103. data/lib/treat/processors/chunkers/autoselect.rb +16 -0
  104. data/lib/treat/processors/chunkers/html.rb +71 -0
  105. data/lib/treat/processors/chunkers/txt.rb +18 -24
  106. data/lib/treat/processors/parsers/enju.rb +253 -208
  107. data/lib/treat/processors/parsers/stanford.rb +130 -131
  108. data/lib/treat/processors/segmenters/punkt.rb +79 -45
  109. data/lib/treat/processors/segmenters/stanford.rb +46 -48
  110. data/lib/treat/processors/segmenters/tactful.rb +43 -36
  111. data/lib/treat/processors/tokenizers/perl.rb +124 -92
  112. data/lib/treat/processors/tokenizers/ptb.rb +81 -0
  113. data/lib/treat/processors/tokenizers/punkt.rb +48 -42
  114. data/lib/treat/processors/tokenizers/stanford.rb +39 -38
  115. data/lib/treat/processors/tokenizers/tactful.rb +64 -55
  116. data/lib/treat/proxies.rb +52 -35
  117. data/lib/treat/retrievers.rb +26 -16
  118. data/lib/treat/retrievers/indexers/ferret.rb +47 -26
  119. data/lib/treat/retrievers/searchers/ferret.rb +69 -50
  120. data/lib/treat/tree.rb +241 -183
  121. data/spec/collection.rb +123 -0
  122. data/spec/document.rb +93 -0
  123. data/spec/entity.rb +408 -0
  124. data/spec/languages.rb +25 -0
  125. data/spec/phrase.rb +146 -0
  126. data/spec/samples/mathematicians/archimedes.abw +34 -0
  127. data/spec/samples/mathematicians/euler.html +21 -0
  128. data/spec/samples/mathematicians/gauss.pdf +0 -0
  129. data/spec/samples/mathematicians/leibniz.txt +13 -0
  130. data/spec/samples/mathematicians/newton.doc +0 -0
  131. data/spec/sandbox.rb +5 -0
  132. data/spec/token.rb +109 -0
  133. data/spec/treat.rb +52 -0
  134. data/spec/tree.rb +117 -0
  135. data/spec/word.rb +110 -0
  136. data/spec/zone.rb +66 -0
  137. data/tmp/INFO +1 -1
  138. metadata +100 -201
  139. data/INSTALL +0 -1
  140. data/README +0 -3
  141. data/TODO +0 -28
  142. data/lib/economist/half_cocked_basel.txt +0 -16
  143. data/lib/economist/hungarys_troubles.txt +0 -46
  144. data/lib/economist/indias_slowdown.txt +0 -15
  145. data/lib/economist/merkozy_rides_again.txt +0 -24
  146. data/lib/economist/prada_is_not_walmart.txt +0 -9
  147. data/lib/economist/to_infinity_and_beyond.txt +0 -15
  148. data/lib/ferret/_11.cfs +0 -0
  149. data/lib/ferret/_14.cfs +0 -0
  150. data/lib/ferret/_p.cfs +0 -0
  151. data/lib/ferret/_s.cfs +0 -0
  152. data/lib/ferret/_v.cfs +0 -0
  153. data/lib/ferret/_y.cfs +0 -0
  154. data/lib/ferret/segments +0 -0
  155. data/lib/ferret/segments_15 +0 -0
  156. data/lib/treat/buildable.rb +0 -157
  157. data/lib/treat/category.rb +0 -33
  158. data/lib/treat/delegatable.rb +0 -116
  159. data/lib/treat/doable.rb +0 -45
  160. data/lib/treat/entities/collection.rb +0 -14
  161. data/lib/treat/entities/document.rb +0 -12
  162. data/lib/treat/entities/phrases.rb +0 -17
  163. data/lib/treat/entities/tokens.rb +0 -61
  164. data/lib/treat/entities/zones.rb +0 -41
  165. data/lib/treat/extractors/coreferences/stanford.rb +0 -69
  166. data/lib/treat/extractors/date/chronic.rb +0 -32
  167. data/lib/treat/extractors/date/ruby.rb +0 -25
  168. data/lib/treat/extractors/keywords/topics_tf_idf.rb +0 -48
  169. data/lib/treat/extractors/language/language_extractor.rb +0 -27
  170. data/lib/treat/extractors/named_entity_tag/stanford.rb +0 -53
  171. data/lib/treat/extractors/roles/naive.rb +0 -73
  172. data/lib/treat/extractors/statistics/frequency_in.rb +0 -16
  173. data/lib/treat/extractors/statistics/position_in.rb +0 -14
  174. data/lib/treat/extractors/statistics/tf_idf.rb +0 -104
  175. data/lib/treat/extractors/statistics/transition_matrix.rb +0 -105
  176. data/lib/treat/extractors/statistics/transition_probability.rb +0 -57
  177. data/lib/treat/extractors/topic_words/lda/data.dat +0 -46
  178. data/lib/treat/extractors/topic_words/lda/wiki.yml +0 -121
  179. data/lib/treat/extractors/topics/reuters/industry.xml +0 -2717
  180. data/lib/treat/extractors/topics/reuters/region.xml +0 -13586
  181. data/lib/treat/extractors/topics/reuters/topics.xml +0 -17977
  182. data/lib/treat/feature.rb +0 -58
  183. data/lib/treat/features.rb +0 -7
  184. data/lib/treat/formatters/visualizers/short_value.rb +0 -29
  185. data/lib/treat/formatters/visualizers/txt.rb +0 -45
  186. data/lib/treat/group.rb +0 -106
  187. data/lib/treat/helpers/linguistics_loader.rb +0 -18
  188. data/lib/treat/inflectors/cardinal_words/linguistics.rb +0 -42
  189. data/lib/treat/inflectors/conjugations/linguistics.rb +0 -36
  190. data/lib/treat/inflectors/declensions/english.rb +0 -319
  191. data/lib/treat/inflectors/declensions/linguistics.rb +0 -42
  192. data/lib/treat/inflectors/ordinal_words/linguistics.rb +0 -20
  193. data/lib/treat/inflectors/stem/porter.rb +0 -162
  194. data/lib/treat/inflectors/stem/porter_c.rb +0 -26
  195. data/lib/treat/inflectors/stem/uea.rb +0 -30
  196. data/lib/treat/install.rb +0 -59
  197. data/lib/treat/languages/tags.rb +0 -377
  198. data/lib/treat/lexicalizers/category/from_tag.rb +0 -49
  199. data/lib/treat/lexicalizers/linkages/naive.rb +0 -63
  200. data/lib/treat/lexicalizers/synsets/wordnet.rb +0 -76
  201. data/lib/treat/lexicalizers/tag/brill.rb +0 -91
  202. data/lib/treat/lexicalizers/tag/lingua.rb +0 -123
  203. data/lib/treat/lexicalizers/tag/stanford.rb +0 -70
  204. data/lib/treat/processors/segmenters/punkt/dutch.yaml +0 -9716
  205. data/lib/treat/processors/segmenters/punkt/english.yaml +0 -10340
  206. data/lib/treat/processors/segmenters/punkt/french.yaml +0 -43159
  207. data/lib/treat/processors/segmenters/punkt/german.yaml +0 -9572
  208. data/lib/treat/processors/segmenters/punkt/greek.yaml +0 -6050
  209. data/lib/treat/processors/segmenters/punkt/italian.yaml +0 -14748
  210. data/lib/treat/processors/segmenters/punkt/polish.yaml +0 -9751
  211. data/lib/treat/processors/segmenters/punkt/portuguese.yaml +0 -13662
  212. data/lib/treat/processors/segmenters/punkt/russian.yaml +0 -4237
  213. data/lib/treat/processors/segmenters/punkt/spanish.yaml +0 -24034
  214. data/lib/treat/processors/segmenters/punkt/swedish.yaml +0 -10001
  215. data/lib/treat/processors/tokenizers/macintyre.rb +0 -77
  216. data/lib/treat/processors/tokenizers/multilingual.rb +0 -30
  217. data/lib/treat/registrable.rb +0 -28
  218. data/lib/treat/sugar.rb +0 -50
  219. data/lib/treat/viewable.rb +0 -29
  220. data/lib/treat/visitable.rb +0 -28
  221. data/test/profile.rb +0 -2
  222. data/test/tc_entity.rb +0 -117
  223. data/test/tc_extractors.rb +0 -73
  224. data/test/tc_formatters.rb +0 -41
  225. data/test/tc_inflectors.rb +0 -34
  226. data/test/tc_lexicalizers.rb +0 -32
  227. data/test/tc_processors.rb +0 -50
  228. data/test/tc_resources.rb +0 -22
  229. data/test/tc_treat.rb +0 -60
  230. data/test/tc_tree.rb +0 -60
  231. data/test/tests.rb +0 -20
  232. data/test/texts.rb +0 -19
  233. data/test/texts/english/half_cocked_basel.txt +0 -16
  234. data/test/texts/english/hose_and_dry.doc +0 -0
  235. data/test/texts/english/hungarys_troubles.abw +0 -70
  236. data/test/texts/english/long.html +0 -24
  237. data/test/texts/english/long.txt +0 -22
  238. data/test/texts/english/medium.txt +0 -5
  239. data/test/texts/english/republican_nomination.pdf +0 -0
  240. data/test/texts/english/saving_the_euro.odt +0 -0
  241. data/test/texts/english/short.txt +0 -3
  242. data/test/texts/english/zero_sum.html +0 -111
@@ -1,112 +1,107 @@
1
- module Treat
2
- module Formatters
3
- module Unserializers
4
- # Recreates the entity tree corresponding to
5
- # a serialized XML file.
6
- class XML
7
- require 'nokogiri'
8
- # Unserialize an entity stored in XML format.
9
- #
10
- # Options: none.
11
- def self.unserialize(document, options = {})
12
- # Read in the XML file.
13
- xml = File.read(document.file)
14
- xml.gsub!('<treat>', '')
15
- xml.gsub!('</treat>', '')
16
- xml_reader = Nokogiri::XML::Reader.from_memory(xml)
17
- current_element = nil
18
- previous_depth = 0
1
+ # Recreates the entity tree corresponding to
2
+ # a serialized XML file.
3
+ module Treat::Formatters::Unserializers::XML
19
4
 
20
- # Read the XML file entity by entity.
21
- while xml_reader.read
22
- # The depth in the XML tree.
23
- current_depth = xml_reader.depth
24
- # If we are at the end of the children stack, pop up.
25
- if previous_depth > current_depth && current_depth != 0
26
- current_element = current_element.parent
27
- end
28
- # If an end element has been reached,
29
- # change the depth and pop up on next
30
- # iteration.
31
- if xml_reader.node_type ==
32
- Nokogiri::XML::Reader::TYPE_END_ELEMENT
33
- previous_depth = current_depth
34
- next
35
- end
5
+ require 'nokogiri'
6
+
7
+ # Unserialize an entity stored in XML format.
8
+ #
9
+ # Options: none.
10
+ def self.unserialize(document, options = {})
11
+ # Read in the XML file.
12
+ xml = File.read(document.file)
13
+ xml.gsub!('<treat>', '')
14
+ xml.gsub!('</treat>', '')
15
+ xml_reader = Nokogiri::XML::Reader.from_memory(xml)
16
+ current_element = nil
17
+ previous_depth = 0
36
18
 
37
- id = nil; value = ''
38
- attributes = {}
39
- dependencies = []
40
- unless xml_reader.attributes.size == 0
41
- xml_reader.attributes.each_pair do |k,v|
42
- if k == 'id'
43
- id = v.to_i
44
- elsif k == 'dependencies'
45
- a = v.split('--')
46
- a.each do |b|
47
- c = b.split(';')
48
- c.each do |dep|
49
- vals = []
50
- dep.split(',').each do |name_val|
51
- name_val = name_val[0..-2] if name_val[-1] == '}'
52
- d = name_val.split(':')[1]
53
- vals << d.strip if d
54
- end
55
-
56
- target, type, directed, direction = *vals
57
- dependencies << [
58
- target.to_i,
59
- type,
60
- (directed == 'true' ? true : false),
61
- direction.to_i
62
- ]
63
- end
64
- end
65
- elsif k == 'value'
66
- value = v
67
- else
68
- attributes[k.intern] = v
69
- end
70
- end
71
- end
19
+ # Read the XML file entity by entity.
20
+ while xml_reader.read
21
+ # The depth in the XML tree.
22
+ current_depth = xml_reader.depth
23
+ # If we are at the end of the children stack, pop up.
24
+ if previous_depth > current_depth && current_depth != 0
25
+ current_element = current_element.parent
26
+ end
27
+ # If an end element has been reached,
28
+ # change the depth and pop up on next
29
+ # iteration.
30
+ if xml_reader.node_type ==
31
+ Nokogiri::XML::Reader::TYPE_END_ELEMENT
32
+ previous_depth = current_depth
33
+ next
34
+ end
72
35
 
73
- current_value = ''
74
- type = xml_reader.name.intern
36
+ id = nil; value = ''
37
+ attributes = {}
38
+ dependencies = []
39
+ unless xml_reader.attributes.size == 0
40
+ xml_reader.attributes.each_pair do |k,v|
41
+ if k == 'id'
42
+ id = v.to_i
43
+ elsif k == 'dependencies'
44
+ a = v.split('--')
45
+ a.each do |b|
46
+ c = b.split(';')
47
+ c.each do |dep|
48
+ vals = []
49
+ dep.split(',').each do |name_val|
50
+ name_val = name_val[0..-2] if name_val[-1] == '}'
51
+ d = name_val.split(':')[1]
52
+ vals << d.strip if d
53
+ end
75
54
 
76
- if Treat::Entities.list.include?(type)
77
- if !current_element
78
- current_element = self.revive(type, current_value, id)
79
- else
80
- current_element = current_element <<
81
- self.revive(type, current_value, id)
82
- end
83
- current_element.features = attributes
84
- current_element.features = attributes
85
- dependencies.each do |dependency|
86
- target, type, directed, direction = *dependency
87
- current_element.link(target, type, directed, direction)
88
- end
89
- else
90
- current_value = xml_reader.value ?
91
- xml_reader.value.strip : ''
92
- if current_value && current_value != ''
93
- current_element.value = current_value
94
- current_element.register_token(current_element)
55
+ target, type, directed, direction = *vals
56
+ dependencies << [
57
+ target.to_i,
58
+ type,
59
+ (directed == 'true' ? true : false),
60
+ direction.to_i
61
+ ]
95
62
  end
96
63
  end
97
-
98
- previous_depth = current_depth
64
+ elsif k == 'value'
65
+ value = v
66
+ else
67
+ attributes[k.intern] = v
99
68
  end
100
- document << current_element
101
- document
102
69
  end
70
+ end
103
71
 
104
- def self.revive(type, value, id)
105
- klass = Treat::Entities.const_get(cc(type))
106
- klass.new(value, id)
107
- end
72
+ current_value = ''
73
+ type = xml_reader.name.intern
108
74
 
75
+ if Treat::Entities.list.include?(type)
76
+ if !current_element
77
+ current_element = self.revive(type, current_value, id)
78
+ else
79
+ current_element = current_element <<
80
+ self.revive(type, current_value, id)
81
+ end
82
+ current_element.features = attributes
83
+ current_element.features = attributes
84
+ dependencies.each do |dependency|
85
+ target, type, directed, direction = *dependency
86
+ current_element.link(target, type, directed, direction)
87
+ end
88
+ else
89
+ current_value = xml_reader.value ?
90
+ xml_reader.value.strip : ''
91
+ if current_value && current_value != ''
92
+ current_element.value = current_value
93
+ end
109
94
  end
95
+
96
+ previous_depth = current_depth
110
97
  end
98
+ document << current_element
99
+ document
111
100
  end
112
- end
101
+
102
+ def self.revive(type, value, id)
103
+ klass = Treat::Entities.const_get(cc(type))
104
+ klass.new(value, id)
105
+ end
106
+
107
+ end
@@ -1,21 +1,22 @@
1
- module Treat
2
- module Formatters
3
- module Unserializers
4
- # This class is a wrapper for the Psych YAML
5
- # parser; it unserializes YAML files.
6
- class YAML
7
- # Require the Psych YAML parser.
8
- require 'psych'
9
- # Require date to revive DateTime.
10
- require 'date'
11
- # Unserialize a YAML file.
12
- #
13
- # Options: none.
14
- def self.unserialize(document, options = {})
15
- document << ::Psych.load(File.read(document.file))
16
- document
17
- end
18
- end
19
- end
1
+ # This class is a wrapper for the Psych YAML
2
+ # parser; it unserializes YAML files.
3
+ class Treat::Formatters::Unserializers::YAML
4
+
5
+ silence_warnings do
6
+ # Require the Psych YAML parser.
7
+ require 'psych'
20
8
  end
9
+
10
+ # Require date to revive DateTime.
11
+ require 'date'
12
+
13
+ # Unserialize a YAML file.
14
+ #
15
+ # Options: none.
16
+ def self.unserialize(document, options = {})
17
+ document << ::Psych.load(
18
+ File.read(document.file))
19
+ document
20
+ end
21
+
21
22
  end
@@ -1,141 +1,141 @@
1
- module Treat
2
- module Formatters
3
- module Visualizers
4
- class Dot
5
- require 'date'
6
- DefaultOptions = {
7
- :colors => {},
8
- :features => :all,
9
- :file => nil,
10
- :remove_types => [],
11
- :remove_features => [],
12
- :colors => nil,
13
- :first => true # For internal purposes only.
14
- }
15
- # Create the top-most graph structure
16
- # and delegate the creation of the graph
17
- # nodes to to_dot.
18
- def self.visualize(entity, options = {})
19
- options = DefaultOptions.merge(options)
20
- string = "graph {"
21
- string << self.to_dot(entity, options)
22
- string << "\n}"
23
- if options[:file]
24
- File.open(options[:file], 'w') { |f| f.write(string) }
25
- end
26
- string
27
- end
28
- # dot -Tpdf test4.dot > test4.pdf
29
- def self.to_dot(entity, options)
30
- # Filter out specified types.
31
- match_types = lambda do |t1, t2s|
32
- f = false
33
- t2s.each { |t2| f = true if Treat::Entities.match_types[t1][t2] }
34
- f
35
- end
36
- return '' if match_types.call(entity.type, options[:remove_types])
37
- # Id
38
- string = ''
39
- label = ''
40
- sv = entity.short_value.inspect[1..-2]
41
- string = "\n#{entity.id} ["
42
- label = "#{entity.type.to_s.capitalize}\\n\\\"#{sv}\\\""
43
- label.gsub!(' [...]', " [...] \\n")
44
- # Features
45
- if entity.has_features?
46
- unless options[:features] == :none
47
- label << "\\n"
48
- entity.features.each do |feature, value|
49
- next if options[:remove_features].include?(feature)
50
- if options[:features] == :all ||
51
- options[:features].include?(feature)
52
- if value.is_a?(Treat::Entities::Entity)
53
- label << "\\n#{feature}: \\\"*#{value.id}\\\""
54
- elsif value.is_a?(Struct)
55
- label << "\\n#{feature}: \\n\{ "
56
- value.members.each do |member|
57
- v = value.send(member)
58
- v = v.to_s if v.is_a?(DateTime)
59
- v = "*#{v.id}" if v.is_a?(Treat::Entities::Entity)
60
- v = v ? v.inspect : ' -- '
61
- v.gsub!('[', '\[')
62
- v.gsub!('{', '\}')
63
- v.gsub!(']', '\]')
64
- v.gsub!('}', '\}')
65
- v.gsub!('"', '\"')
66
- label << "#{member}: #{v},\\n"
67
- end
68
- label = label[0..-4] unless label[-2] == '{'
69
- label << "\},"
70
- elsif value.is_a?(Hash)
71
- label << "\\n#{feature}: \\n\{ "
72
- value.each do |k,v|
73
- v = v ? v.inspect : ' -- '
74
- v.gsub!('[', '\[')
75
- v.gsub!('{', '\}')
76
- v.gsub!(']', '\]')
77
- v.gsub!('}', '\}')
78
- v.gsub!('"', '\"')
79
- label << "#{k}: #{v},\\n"
80
- end
81
- label = label[0..-4] unless label[-2] == '{'
82
- label << "\},"
83
- elsif value.is_a?(Array)
84
- label << "\\n#{feature}: \\n\[ "
85
- value.each do |e|
86
- e = "*#{e.id}" if e.is_a?(Treat::Entities::Entity)
87
- label << "#{e},\\n"
88
- end
89
- label = label[0..-4] unless label[-2] == '['
90
- label << " \]"
91
- else
92
- label << "\\n#{feature}: \\\"#{value}\\\""
93
- end
94
- end
1
+ class Treat::Formatters::Visualizers::DOT
2
+
3
+ require 'date'
4
+ DefaultOptions = {
5
+ :colors => {},
6
+ :features => :all,
7
+ :file => nil,
8
+ :remove_types => [],
9
+ :remove_features => [],
10
+ :colors => nil,
11
+ :first => true # For internal purposes only.
12
+ }
13
+ # Create the top-most graph structure
14
+ # and delegate the creation of the graph
15
+ # nodes to to_dot.
16
+ def self.visualize(entity, options = {})
17
+ options = DefaultOptions.merge(options)
18
+ string = "graph {"
19
+ string << self.to_dot(entity, options)
20
+ string << "\n}"
21
+ if options[:file]
22
+ File.open(options[:file], 'w') { |f| f.write(string) }
23
+ end
24
+ string
25
+ end
26
+ # dot -Tpdf test4.dot > test4.pdf
27
+ def self.to_dot(entity, options)
28
+ # Filter out specified types.
29
+ match_types = lambda do |t1, t2s|
30
+ f = false
31
+ t2s.each { |t2| f = true if Treat::Entities.match_types[t1][t2] }
32
+ f
33
+ end
34
+ return '' if match_types.call(entity.type, options[:remove_types])
35
+ # Id
36
+ string = ''
37
+ label = ''
38
+ sv = entity.short_value.inspect[1..-2]
39
+ string = "\n#{entity.id} ["
40
+ label = "#{entity.type.to_s.capitalize}\\n\\\"#{sv}\\\""
41
+ label.gsub!(' [...]', " [...] \\n")
42
+ # Features
43
+ if entity.has_features?
44
+ unless options[:features] == :none
45
+ label << "\\n"
46
+ entity.features.each do |feature, value|
47
+ next if options[:remove_features].include?(feature)
48
+ if options[:features] == :all ||
49
+ options[:features].include?(feature)
50
+ if value.is_a?(Treat::Entities::Entity)
51
+ label << "\\n#{feature}: \\\"*#{value.id}\\\""
52
+ elsif value.is_a?(Struct)
53
+ label << "\\n#{feature}: \\n\{ "
54
+ value.members.each do |member|
55
+ v = value.send(member)
56
+ v = v.to_s if v.is_a?(DateTime)
57
+ v = "*#{v.id}" if v.is_a?(Treat::Entities::Entity)
58
+ v = v ? v.inspect : ' -- '
59
+ v = escape(v)
60
+ label << "#{member}: #{v},\\n"
95
61
  end
96
- end
97
- end
98
- color = nil
99
- if options[:colors]
100
- options[:colors].each do |col, lambda|
101
- color = col.to_s if lambda.call(entity)
102
- break if color
103
- end
104
- end
105
- label = label[0..-2] if label[-1] == ','
106
- string << "label=\"#{label}\",color=\"#{color.to_s}\"]"
107
- string.gsub!('\\\\""]', '\\""]')
108
- string.gsub('\"\""]', '\""]')
109
- # Parent-child relationships.
110
- if entity.has_parent?
111
- unless options[:first] == true
112
- string << "\n#{entity.parent.id} -- #{entity.id};"
113
- end
114
- end
115
- # Dependencies.
116
- if entity.has_dependencies?
117
- entity.dependencies.each do |dependency|
118
- dir = ''
119
- if dependency.directed == true
120
- dir = dependency.direction == 1 ? 'forward' : 'back'
121
- dir = ",dir=#{dir}"
122
- else
123
- dir = ",dir=both"
62
+ label = label[0..-4] unless label[-2] == '{'
63
+ label << "\},"
64
+ elsif value.is_a?(Hash)
65
+ label << "\\n#{feature}: \\n\{ "
66
+ value.each do |k,v|
67
+ v = v ? v.inspect : ' -- '
68
+ v = escape(v)
69
+ label << "#{k}: #{v},\\n"
124
70
  end
125
- string << "\n#{entity.id} -- #{dependency.target}"
126
- string << "[label=#{dependency.type}#{dir}]"
127
- end
128
- end
129
- # Recurse.
130
- options[:first] = false
131
- if entity.has_children?
132
- entity.each do |child|
133
- string << self.to_dot(child, options)
71
+ label = label[0..-4] unless label[-2] == '{'
72
+ label << "\},"
73
+ elsif value.is_a?(Array)
74
+ label << "\\n#{feature}: \\n\[ "
75
+ value.each do |e|
76
+ if e.is_a?(Treat::Entities::Entity)
77
+ v = escape("*#{e.id}")
78
+ else
79
+ v = escape(e.inspect)
80
+ end
81
+ label << "#{v},\\n"
82
+ end
83
+ label = label[0..-4] unless label[-2] == '['
84
+ label << " \]"
85
+ else
86
+ label << "\\n#{feature}: \\\"#{value}\\\""
134
87
  end
135
88
  end
136
- string
137
89
  end
138
90
  end
139
91
  end
92
+ color = nil
93
+ if options[:colors]
94
+ options[:colors].each do |col, lambda|
95
+ color = col.to_s if lambda.call(entity)
96
+ break if color
97
+ end
98
+ end
99
+ label = label[0..-2] if label[-1] == ','
100
+ string << "label=\"#{label}\",color=\"#{color.to_s}\"]"
101
+ string.gsub!('\\\\""]', '\\""]')
102
+ string.gsub('\"\""]', '\""]')
103
+ # Parent-child relationships.
104
+ if entity.has_parent?
105
+ unless options[:first] == true
106
+ string << "\n#{entity.parent.id} -- #{entity.id};"
107
+ end
108
+ end
109
+ # Dependencies.
110
+ if entity.has_dependencies?
111
+ entity.dependencies.each do |dependency|
112
+ dir = ''
113
+ if dependency.directed == true
114
+ dir = dependency.direction == 1 ? 'forward' : 'back'
115
+ dir = ",dir=#{dir}"
116
+ else
117
+ dir = ",dir=both"
118
+ end
119
+ string << "\n#{entity.id} -- #{dependency.target}"
120
+ string << "[label=#{dependency.type}#{dir}]"
121
+ end
122
+ end
123
+ # Recurse.
124
+ options[:first] = false
125
+ if entity.has_children?
126
+ entity.each do |child|
127
+ string << self.to_dot(child, options)
128
+ end
129
+ end
130
+ string
131
+ end
132
+
133
+ def self.escape(v)
134
+ v.gsub('[', '\[')
135
+ .gsub('{', '\}')
136
+ .gsub(']', '\]')
137
+ .gsub('}', '\}')
138
+ .gsub('"', '\"')
140
139
  end
140
+
141
141
  end