sqlpostgres 1.2.4

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 (207) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +22 -0
  3. data/LICENSE.md +23 -0
  4. data/README.rdoc +59 -0
  5. data/Rakefile +32 -0
  6. data/VERSION +1 -0
  7. data/doc/BUGS +2 -0
  8. data/doc/examples/README +6 -0
  9. data/doc/examples/connection.rb +16 -0
  10. data/doc/examples/connection_auto.rb +22 -0
  11. data/doc/examples/connection_ctor.rb +18 -0
  12. data/doc/examples/connection_default.rb +15 -0
  13. data/doc/examples/connection_exec.rb +18 -0
  14. data/doc/examples/connection_manual.rb +12 -0
  15. data/doc/examples/connection_wrapped_new.rb +13 -0
  16. data/doc/examples/connection_wrapped_open.rb +13 -0
  17. data/doc/examples/cursor.rb +38 -0
  18. data/doc/examples/include_module.rb +9 -0
  19. data/doc/examples/include_module2.rb +12 -0
  20. data/doc/examples/insert.rb +30 -0
  21. data/doc/examples/insert2.rb +36 -0
  22. data/doc/examples/insert_bytea.rb +16 -0
  23. data/doc/examples/insert_bytea_array.rb +17 -0
  24. data/doc/examples/insert_default_values.rb +16 -0
  25. data/doc/examples/insert_insert.rb +16 -0
  26. data/doc/examples/insert_insert_default.rb +16 -0
  27. data/doc/examples/insert_insert_select.rb +20 -0
  28. data/doc/examples/insert_select.rb +20 -0
  29. data/doc/examples/interval.rb +17 -0
  30. data/doc/examples/savepoint.rb +38 -0
  31. data/doc/examples/select.rb +33 -0
  32. data/doc/examples/select2.rb +36 -0
  33. data/doc/examples/select_cross_join.rb +18 -0
  34. data/doc/examples/select_distinct.rb +18 -0
  35. data/doc/examples/select_distinct_on +19 -0
  36. data/doc/examples/select_for_update.rb +18 -0
  37. data/doc/examples/select_from.rb +17 -0
  38. data/doc/examples/select_from_subselect.rb +20 -0
  39. data/doc/examples/select_group_by.rb +19 -0
  40. data/doc/examples/select_having.rb +20 -0
  41. data/doc/examples/select_join_on.rb +18 -0
  42. data/doc/examples/select_join_using.rb +18 -0
  43. data/doc/examples/select_limit.rb +19 -0
  44. data/doc/examples/select_natural_join.rb +18 -0
  45. data/doc/examples/select_offset.rb +19 -0
  46. data/doc/examples/select_order_by.rb +20 -0
  47. data/doc/examples/select_select.rb +30 -0
  48. data/doc/examples/select_select_alias.rb +30 -0
  49. data/doc/examples/select_select_expression.rb +31 -0
  50. data/doc/examples/select_select_literal.rb +24 -0
  51. data/doc/examples/select_union.rb +21 -0
  52. data/doc/examples/select_where_array.rb +18 -0
  53. data/doc/examples/select_where_in.rb +18 -0
  54. data/doc/examples/select_where_string.rb +18 -0
  55. data/doc/examples/simple.rb +34 -0
  56. data/doc/examples/transaction.rb +30 -0
  57. data/doc/examples/transaction_abort.rb +30 -0
  58. data/doc/examples/transaction_commit.rb +34 -0
  59. data/doc/examples/translate_substitute_values.rb +17 -0
  60. data/doc/examples/update.rb +32 -0
  61. data/doc/examples/update2.rb +44 -0
  62. data/doc/examples/update_only.rb +17 -0
  63. data/doc/examples/update_set.rb +17 -0
  64. data/doc/examples/update_set_array.rb +16 -0
  65. data/doc/examples/update_set_bytea.rb +16 -0
  66. data/doc/examples/update_set_expression.rb +16 -0
  67. data/doc/examples/update_set_subselect.rb +20 -0
  68. data/doc/examples/update_where.rb +17 -0
  69. data/doc/examples/use_prefix.rb +8 -0
  70. data/doc/examples/use_prefix2.rb +11 -0
  71. data/doc/index.html +31 -0
  72. data/doc/insertexamples.rb +9 -0
  73. data/doc/makemanual +4 -0
  74. data/doc/makerdoc +5 -0
  75. data/doc/manual.dbk +622 -0
  76. data/lib/sqlpostgres/Connection.rb +198 -0
  77. data/lib/sqlpostgres/Cursor.rb +157 -0
  78. data/lib/sqlpostgres/Delete.rb +67 -0
  79. data/lib/sqlpostgres/Exceptions.rb +15 -0
  80. data/lib/sqlpostgres/Insert.rb +279 -0
  81. data/lib/sqlpostgres/NullConnection.rb +22 -0
  82. data/lib/sqlpostgres/PgBit.rb +73 -0
  83. data/lib/sqlpostgres/PgBox.rb +37 -0
  84. data/lib/sqlpostgres/PgCidr.rb +21 -0
  85. data/lib/sqlpostgres/PgCircle.rb +75 -0
  86. data/lib/sqlpostgres/PgInet.rb +21 -0
  87. data/lib/sqlpostgres/PgInterval.rb +208 -0
  88. data/lib/sqlpostgres/PgLineSegment.rb +37 -0
  89. data/lib/sqlpostgres/PgMacAddr.rb +21 -0
  90. data/lib/sqlpostgres/PgPath.rb +64 -0
  91. data/lib/sqlpostgres/PgPoint.rb +65 -0
  92. data/lib/sqlpostgres/PgPolygon.rb +56 -0
  93. data/lib/sqlpostgres/PgTime.rb +77 -0
  94. data/lib/sqlpostgres/PgTimeWithTimeZone.rb +98 -0
  95. data/lib/sqlpostgres/PgTimestamp.rb +93 -0
  96. data/lib/sqlpostgres/PgTwoPoints.rb +54 -0
  97. data/lib/sqlpostgres/PgType.rb +34 -0
  98. data/lib/sqlpostgres/PgWrapper.rb +41 -0
  99. data/lib/sqlpostgres/Savepoint.rb +98 -0
  100. data/lib/sqlpostgres/Select.rb +855 -0
  101. data/lib/sqlpostgres/Transaction.rb +120 -0
  102. data/lib/sqlpostgres/Translate.rb +436 -0
  103. data/lib/sqlpostgres/Update.rb +188 -0
  104. data/lib/sqlpostgres.rb +67 -0
  105. data/test/Assert.rb +72 -0
  106. data/test/Connection.test.rb +246 -0
  107. data/test/Cursor.test.rb +190 -0
  108. data/test/Delete.test.rb +68 -0
  109. data/test/Insert.test.rb +123 -0
  110. data/test/MockPGconn.rb +62 -0
  111. data/test/NullConnection.test.rb +32 -0
  112. data/test/PgBit.test.rb +98 -0
  113. data/test/PgBox.test.rb +108 -0
  114. data/test/PgCidr.test.rb +61 -0
  115. data/test/PgCircle.test.rb +107 -0
  116. data/test/PgInet.test.rb +61 -0
  117. data/test/PgInterval.test.rb +180 -0
  118. data/test/PgLineSegment.test.rb +108 -0
  119. data/test/PgMacAddr.test.rb +61 -0
  120. data/test/PgPath.test.rb +106 -0
  121. data/test/PgPoint.test.rb +100 -0
  122. data/test/PgPolygon.test.rb +95 -0
  123. data/test/PgTime.test.rb +120 -0
  124. data/test/PgTimeWithTimeZone.test.rb +117 -0
  125. data/test/PgTimestamp.test.rb +134 -0
  126. data/test/RandomThings.rb +25 -0
  127. data/test/Savepoint.test.rb +286 -0
  128. data/test/Select.test.rb +930 -0
  129. data/test/Test.rb +62 -0
  130. data/test/TestConfig.rb +21 -0
  131. data/test/TestSetup.rb +13 -0
  132. data/test/TestUtil.rb +92 -0
  133. data/test/Transaction.test.rb +275 -0
  134. data/test/Translate.test.rb +354 -0
  135. data/test/Update.test.rb +227 -0
  136. data/test/roundtrip.test.rb +565 -0
  137. data/test/test +34 -0
  138. data/tools/exampleinserter/ExampleInserter.rb +177 -0
  139. data/tools/rdoc/ChangeLog +796 -0
  140. data/tools/rdoc/EXAMPLE.rb +48 -0
  141. data/tools/rdoc/MANIFEST +58 -0
  142. data/tools/rdoc/Makefile +27 -0
  143. data/tools/rdoc/NEW_FEATURES +226 -0
  144. data/tools/rdoc/README +390 -0
  145. data/tools/rdoc/ToDo +6 -0
  146. data/tools/rdoc/contrib/Index +6 -0
  147. data/tools/rdoc/contrib/xslfo/ChangeLog +181 -0
  148. data/tools/rdoc/contrib/xslfo/README +106 -0
  149. data/tools/rdoc/contrib/xslfo/TODO +10 -0
  150. data/tools/rdoc/contrib/xslfo/convert.xsl +151 -0
  151. data/tools/rdoc/contrib/xslfo/demo/README +21 -0
  152. data/tools/rdoc/contrib/xslfo/demo/rdocfo +99 -0
  153. data/tools/rdoc/contrib/xslfo/fcm.xsl +54 -0
  154. data/tools/rdoc/contrib/xslfo/files.xsl +62 -0
  155. data/tools/rdoc/contrib/xslfo/labeled-lists.xsl +66 -0
  156. data/tools/rdoc/contrib/xslfo/lists.xsl +44 -0
  157. data/tools/rdoc/contrib/xslfo/modules.xsl +152 -0
  158. data/tools/rdoc/contrib/xslfo/rdoc.xsl +75 -0
  159. data/tools/rdoc/contrib/xslfo/source.xsl +66 -0
  160. data/tools/rdoc/contrib/xslfo/styles.xsl +69 -0
  161. data/tools/rdoc/contrib/xslfo/tables.xsl +67 -0
  162. data/tools/rdoc/contrib/xslfo/utils.xsl +21 -0
  163. data/tools/rdoc/debian/changelog +33 -0
  164. data/tools/rdoc/debian/compat +1 -0
  165. data/tools/rdoc/debian/control +20 -0
  166. data/tools/rdoc/debian/copyright +10 -0
  167. data/tools/rdoc/debian/dirs +2 -0
  168. data/tools/rdoc/debian/docs +2 -0
  169. data/tools/rdoc/debian/rdoc.1 +252 -0
  170. data/tools/rdoc/debian/rdoc.manpages +1 -0
  171. data/tools/rdoc/debian/rdoc.pod +149 -0
  172. data/tools/rdoc/debian/rules +9 -0
  173. data/tools/rdoc/dot/dot.rb +255 -0
  174. data/tools/rdoc/etc/rdoc.dtd +203 -0
  175. data/tools/rdoc/install.rb +137 -0
  176. data/tools/rdoc/markup/install.rb +43 -0
  177. data/tools/rdoc/markup/sample/sample.rb +42 -0
  178. data/tools/rdoc/markup/simple_markup/fragments.rb +323 -0
  179. data/tools/rdoc/markup/simple_markup/inline.rb +348 -0
  180. data/tools/rdoc/markup/simple_markup/lines.rb +147 -0
  181. data/tools/rdoc/markup/simple_markup/preprocess.rb +68 -0
  182. data/tools/rdoc/markup/simple_markup/to_html.rb +281 -0
  183. data/tools/rdoc/markup/simple_markup.rb +474 -0
  184. data/tools/rdoc/markup/test/AllTests.rb +2 -0
  185. data/tools/rdoc/markup/test/TestInline.rb +151 -0
  186. data/tools/rdoc/markup/test/TestParse.rb +411 -0
  187. data/tools/rdoc/rdoc/code_objects.rb +536 -0
  188. data/tools/rdoc/rdoc/diagram.rb +331 -0
  189. data/tools/rdoc/rdoc/generators/chm_generator.rb +112 -0
  190. data/tools/rdoc/rdoc/generators/html_generator.rb +1268 -0
  191. data/tools/rdoc/rdoc/generators/template/chm/chm.rb +86 -0
  192. data/tools/rdoc/rdoc/generators/template/html/html.rb +705 -0
  193. data/tools/rdoc/rdoc/generators/template/html/kilmer.rb +377 -0
  194. data/tools/rdoc/rdoc/generators/template/xml/rdf.rb +110 -0
  195. data/tools/rdoc/rdoc/generators/template/xml/xml.rb +110 -0
  196. data/tools/rdoc/rdoc/generators/xml_generator.rb +130 -0
  197. data/tools/rdoc/rdoc/options.rb +451 -0
  198. data/tools/rdoc/rdoc/parsers/parse_c.rb +287 -0
  199. data/tools/rdoc/rdoc/parsers/parse_f95.rb +118 -0
  200. data/tools/rdoc/rdoc/parsers/parse_rb.rb +2311 -0
  201. data/tools/rdoc/rdoc/parsers/parse_simple.rb +37 -0
  202. data/tools/rdoc/rdoc/parsers/parserfactory.rb +75 -0
  203. data/tools/rdoc/rdoc/rdoc.rb +219 -0
  204. data/tools/rdoc/rdoc/template.rb +234 -0
  205. data/tools/rdoc/rdoc/tokenstream.rb +25 -0
  206. data/tools/rdoc/rdoc.rb +9 -0
  207. metadata +291 -0
@@ -0,0 +1,331 @@
1
+ # A wonderful hack by to draw package diagrams using the dot package.
2
+ # Originally written by Jah, team Enticla.
3
+ #
4
+ # You must have the V1.7 or later in your path
5
+ # http://www.research.att.com/sw/tools/graphviz/
6
+
7
+ require "dot/dot"
8
+ require 'rdoc/options'
9
+
10
+ module RDoc
11
+
12
+ # Draw a set of diagrams representing the modules and classes in the
13
+ # system. We draw one diagram for each file, and one for each toplevel
14
+ # class or module. This means there will be overlap. However, it also
15
+ # means that you'll get better context for objects.
16
+ #
17
+ # To use, simply
18
+ #
19
+ # d = Diagram.new(info) # pass in collection of top level infos
20
+ # d.draw
21
+ #
22
+ # The results will be written to the +dot+ subdirectory. The process
23
+ # also sets the +diagram+ attribute in each object it graphs to
24
+ # the name of the file containing the image. This can be used
25
+ # by output generators to insert images.
26
+
27
+ class Diagram
28
+
29
+ FONT = "Arial"
30
+
31
+ DOT_PATH = "dot"
32
+
33
+ # Pass in the set of top level objects. The method also creates
34
+ # the subdirectory to hold the images
35
+
36
+ def initialize(info, options)
37
+ @info = info
38
+ @options = options
39
+ @counter = 0
40
+ File.makedirs(DOT_PATH)
41
+ end
42
+
43
+ # Draw the diagrams. We traverse the files, drawing a diagram for
44
+ # each. We also traverse each top-level class and module in that
45
+ # file drawing a diagram for these too.
46
+
47
+ def draw
48
+ unless @options.quiet
49
+ $stderr.print "Diagrams: "
50
+ $stderr.flush
51
+ end
52
+
53
+ @info.each_with_index do |i, file_count|
54
+ @done_modules = {}
55
+ @local_names = find_names(i)
56
+ @global_names = []
57
+ @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel',
58
+ 'label' => i.file_absolute_name,
59
+ 'fontname' => FONT,
60
+ 'fontsize' => '8',
61
+ 'bgcolor' => 'lightcyan1',
62
+ 'compound' => 'true')
63
+
64
+ # it's a little hack %) i'm too lazy to create a separate class
65
+ # for default node
66
+ graph << DOT::DOTNode.new('name' => 'node',
67
+ 'fontname' => FONT,
68
+ 'color' => 'black',
69
+ 'fontsize' => 8)
70
+
71
+ i.modules.each do |mod|
72
+ draw_module(mod, graph, true, i.file_relative_name)
73
+ end
74
+ add_classes(i, graph, i.file_relative_name)
75
+
76
+ i.diagram = convert_to_png("f_#{file_count}", graph, i.name)
77
+
78
+ # now go through and document each top level class and
79
+ # module independently
80
+ i.modules.each_with_index do |mod, count|
81
+ @done_modules = {}
82
+ @local_names = find_names(mod)
83
+ @global_names = []
84
+
85
+ @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel',
86
+ 'label' => i.full_name,
87
+ 'fontname' => FONT,
88
+ 'fontsize' => '8',
89
+ 'bgcolor' => 'lightcyan1',
90
+ 'compound' => 'true')
91
+
92
+ graph << DOT::DOTNode.new('name' => 'node',
93
+ 'fontname' => FONT,
94
+ 'color' => 'black',
95
+ 'fontsize' => 8)
96
+ draw_module(mod, graph, true)
97
+ mod.diagram = convert_to_png("m_#{file_count}_#{count}",
98
+ graph,
99
+ "Module: #{mod.name}")
100
+ end
101
+ end
102
+ $stderr.puts unless @options.quiet
103
+ end
104
+
105
+ #######
106
+ private
107
+ #######
108
+
109
+ def find_names(mod)
110
+ return [mod.full_name] + mod.classes.collect{|cl| cl.full_name} +
111
+ mod.modules.collect{|m| find_names(m)}.flatten
112
+ end
113
+
114
+ def find_full_name(name,mod)
115
+ full_name = name.dup
116
+ return full_name if @local_names.include?(full_name)
117
+ mod_path = mod.full_name.split('::')[0..-2]
118
+ until mod_path.empty?
119
+ full_name = mod_path.pop + '::' + full_name
120
+ return full_name if @local_names.include?(full_name)
121
+ end
122
+ return name
123
+ end
124
+
125
+ def draw_module(mod, graph, toplevel = false, file = nil)
126
+ return if @done_modules[mod.full_name] and not toplevel
127
+
128
+ @counter += 1
129
+ url = mod.http_url("classes")
130
+ m = DOT::DOTSubgraph.new('name' => "cluster_#{mod.full_name.gsub( /:/,'_' )}",
131
+ 'label' => mod.name,
132
+ 'fontname' => FONT,
133
+ 'color' => 'blue',
134
+ 'style' => 'filled',
135
+ 'URL' => %{"#{url}"},
136
+ 'fillcolor' => toplevel ? 'palegreen1' : 'palegreen3')
137
+
138
+ @done_modules[mod.full_name] = m
139
+ add_classes(mod, m, file)
140
+ graph << m
141
+
142
+ unless mod.includes.empty?
143
+ mod.includes.each do |m|
144
+ m_full_name = find_full_name(m.name, mod)
145
+ if @local_names.include?(m_full_name)
146
+ @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
147
+ 'to' => "#{mod.full_name.gsub( /:/,'_' )}",
148
+ 'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}",
149
+ 'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}")
150
+ else
151
+ unless @global_names.include?(m_full_name)
152
+ path = m_full_name.split("::")
153
+ url = File.join('classes', *path) + ".html"
154
+ @global_graph << DOT::DOTNode.new('name' => "#{m_full_name.gsub( /:/,'_' )}",
155
+ 'shape' => 'box',
156
+ 'label' => "#{m_full_name}",
157
+ 'URL' => %{"#{url}"})
158
+ @global_names << m_full_name
159
+ end
160
+ @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
161
+ 'to' => "#{mod.full_name.gsub( /:/,'_' )}",
162
+ 'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}")
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def add_classes(container, graph, file = nil )
169
+
170
+ use_fileboxes = Options.instance.fileboxes
171
+
172
+ files = {}
173
+
174
+ # create dummy node (needed if empty and for module includes)
175
+ if container.full_name
176
+ graph << DOT::DOTNode.new('name' => "#{container.full_name.gsub( /:/,'_' )}",
177
+ 'label' => "",
178
+ 'width' => (container.classes.empty? and
179
+ container.modules.empty?) ?
180
+ '0.75' : '0.01',
181
+ 'height' => '0.01',
182
+ 'shape' => 'plaintext')
183
+ end
184
+ container.classes.each_with_index do |cl, cl_index|
185
+ last_file = cl.in_files[-1].file_relative_name
186
+
187
+ if use_fileboxes && !files.include?(last_file)
188
+ @counter += 1
189
+ files[last_file] =
190
+ DOT::DOTSubgraph.new('name' => "cluster_#{@counter}",
191
+ 'label' => "#{last_file}",
192
+ 'fontname' => FONT,
193
+ 'color'=>
194
+ last_file == file ? 'red' : 'black')
195
+ end
196
+
197
+ next if cl.name == 'Object' || cl.name[0,2] == "<<"
198
+
199
+ url = cl.http_url("classes")
200
+
201
+ label = cl.name.dup
202
+ if use_fileboxes && cl.in_files.length > 1
203
+ label << '\n[' +
204
+ cl.in_files.collect {|i|
205
+ i.file_relative_name
206
+ }.sort.join( '\n' ) +
207
+ ']'
208
+ end
209
+
210
+ attrs = {
211
+ 'name' => "#{cl.full_name.gsub( /:/, '_' )}",
212
+ 'fontcolor' => 'black',
213
+ 'style'=>'filled',
214
+ 'color'=>'palegoldenrod',
215
+ 'label' => label,
216
+ 'shape' => 'ellipse',
217
+ 'URL' => %{"#{url}"}
218
+ }
219
+
220
+ c = DOT::DOTNode.new(attrs)
221
+
222
+ if use_fileboxes
223
+ files[last_file].push c
224
+ else
225
+ graph << c
226
+ end
227
+ end
228
+
229
+ if use_fileboxes
230
+ files.each_value do |val|
231
+ graph << val
232
+ end
233
+ end
234
+
235
+ unless container.classes.empty?
236
+ container.classes.each_with_index do |cl, cl_index|
237
+ cl.includes.each do |m|
238
+ m_full_name = find_full_name(m.name, cl)
239
+ if @local_names.include?(m_full_name)
240
+ @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
241
+ 'to' => "#{cl.full_name.gsub( /:/,'_' )}",
242
+ 'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}")
243
+ else
244
+ unless @global_names.include?(m_full_name)
245
+ path = m_full_name.split("::")
246
+ url = File.join('classes', *path) + ".html"
247
+ @global_graph << DOT::DOTNode.new('name' => "#{m_full_name.gsub( /:/,'_' )}",
248
+ 'shape' => 'box',
249
+ 'label' => "#{m_full_name}",
250
+ 'URL' => %{"#{url}"})
251
+ @global_names << m_full_name
252
+ end
253
+ @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}",
254
+ 'to' => "#{cl.full_name.gsub( /:/, '_')}")
255
+ end
256
+ end
257
+
258
+ sclass = cl.superclass
259
+ next if sclass.nil? || sclass == 'Object'
260
+ sclass_full_name = find_full_name(sclass,cl)
261
+ unless @local_names.include?(sclass_full_name) or @global_names.include?(sclass_full_name)
262
+ path = sclass_full_name.split("::")
263
+ url = File.join('classes', *path) + ".html"
264
+ @global_graph << DOT::DOTNode.new(
265
+ 'name' => "#{sclass_full_name.gsub( /:/, '_' )}",
266
+ 'label' => sclass_full_name,
267
+ 'URL' => %{"#{url}"})
268
+ @global_names << sclass_full_name
269
+ end
270
+ @global_graph << DOT::DOTEdge.new('from' => "#{sclass_full_name.gsub( /:/,'_' )}",
271
+ 'to' => "#{cl.full_name.gsub( /:/, '_')}")
272
+ end
273
+ end
274
+
275
+ container.modules.each do |submod|
276
+ draw_module(submod, graph)
277
+ end
278
+
279
+ end
280
+
281
+ def convert_to_png(file_base, graph, name)
282
+ op_type = Options.instance.image_format
283
+ dotfile = File.join(DOT_PATH, file_base)
284
+ src = dotfile + ".dot"
285
+ dot = dotfile + "." + op_type
286
+
287
+ unless @options.quiet
288
+ $stderr.print "."
289
+ $stderr.flush
290
+ end
291
+
292
+ File.open(src, 'w+' ) do |f|
293
+ f << graph.to_s << "\n"
294
+ end
295
+
296
+ system "dot -T#{op_type} #{src} -o #{dot}"
297
+
298
+ # Now construct the imagemap wrapper around
299
+ # that png
300
+
301
+ return wrap_in_image_map(src, dot, name)
302
+ end
303
+
304
+ # Extract the client-side image map from dot, and use it
305
+ # to generate the imagemap proper. Return the whole
306
+ # <map>..<img> combination, suitable for inclusion on
307
+ # the page
308
+
309
+ def wrap_in_image_map(src, dot, name)
310
+ res = %{<map name="map">\n}
311
+ dot_map = `dot -Tismap #{src}`
312
+ dot_map.each do |area|
313
+ unless area =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) ([\/\w.]+)\s*(.*)/
314
+ $stderr.puts "Unexpected output from dot:\n#{area}"
315
+ return nil
316
+ end
317
+
318
+ blx = $1; bly = $2
319
+ trx = $3; try = $4
320
+ url = $5; area_name = $6
321
+ res << %{ <area shape="RECT" coords="#{blx},#{try},#{trx},#{bly}" }
322
+ res << %{ href="#{url}" alt="#{area_name}">\n}
323
+ end
324
+ res << "</map>\n"
325
+ # map_file = src.sub(/.dot/, '.map')
326
+ # system("dot -Timap #{src} -o #{map_file}")
327
+ res << %{<img src="#{dot}" usemap="#map" border=0 alt="#{name}">}
328
+ return res
329
+ end
330
+ end
331
+ end
@@ -0,0 +1,112 @@
1
+ require 'rdoc/generators/html_generator'
2
+
3
+ module Generators
4
+
5
+ class CHMGenerator < HTMLGenerator
6
+
7
+ HHC_PATH = "c:\\Program Files\\HTML Help Workshop\\hhc.exe"
8
+
9
+ # Standard generator factory
10
+ def CHMGenerator.for(options)
11
+ CHMGenerator.new(options)
12
+ end
13
+
14
+
15
+ def initialize(*args)
16
+ super
17
+ @op_name = @options.op_name || "rdoc"
18
+ check_for_html_help_workshop
19
+ end
20
+
21
+ def check_for_html_help_workshop
22
+ stat = File.stat(HHC_PATH)
23
+ rescue
24
+ $stderr <<
25
+ "\n.chm output generation requires that Microsoft's Html Help\n" <<
26
+ "Workshop is installed. RDoc looks for it in:\n\n " <<
27
+ HHC_PATH <<
28
+ "\n\nYou can download a copy for free from:\n\n" <<
29
+ " http://msdn.microsoft.com/library/default.asp?" <<
30
+ "url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp\n\n"
31
+
32
+ exit 99
33
+ end
34
+
35
+ # Generate the html as normal, then wrap it
36
+ # in a help project
37
+ def generate(info)
38
+ super
39
+ @project_name = @op_name + ".hhp"
40
+ create_help_project
41
+ end
42
+
43
+ # The project contains the project file, a table of contents
44
+ # and an index
45
+ def create_help_project
46
+ create_project_file
47
+ create_contents_and_index
48
+ compile_project
49
+ end
50
+
51
+ # The project file links together all the various
52
+ # files that go to make up the help.
53
+
54
+ def create_project_file
55
+ template = TemplatePage.new(RDoc::Page::HPP_FILE)
56
+ values = { "title" => @options.title, "opname" => @op_name }
57
+ files = []
58
+ @files.each do |f|
59
+ files << { "html_file_name" => f.path }
60
+ end
61
+
62
+ values['all_html_files'] = files
63
+
64
+ File.open(@project_name, "w") do |f|
65
+ template.write_html_on(f, values)
66
+ end
67
+ end
68
+
69
+ # The contents is a list of all files and modules.
70
+ # For each we include as sub-entries the list
71
+ # of methods they contain. As we build the contents
72
+ # we also build an index file
73
+
74
+ def create_contents_and_index
75
+ contents = []
76
+ index = []
77
+
78
+ (@files+@classes).sort.each do |entry|
79
+ content_entry = { "c_name" => entry.name, "ref" => entry.path }
80
+ index << { "name" => entry.name, "aref" => entry.path }
81
+
82
+ internals = []
83
+
84
+ methods = entry.build_method_summary_list(entry.path)
85
+
86
+ content_entry["methods"] = methods unless methods.empty?
87
+ contents << content_entry
88
+ index.concat methods
89
+ end
90
+
91
+ values = { "contents" => contents }
92
+ template = TemplatePage.new(RDoc::Page::CONTENTS)
93
+ File.open("contents.hhc", "w") do |f|
94
+ template.write_html_on(f, values)
95
+ end
96
+
97
+ values = { "index" => index }
98
+ template = TemplatePage.new(RDoc::Page::CHM_INDEX)
99
+ File.open("index.hhk", "w") do |f|
100
+ template.write_html_on(f, values)
101
+ end
102
+ end
103
+
104
+ # Invoke the windows help compiler to compiler the project
105
+ def compile_project
106
+ system("\"#{HHC_PATH}\" #@project_name")
107
+ end
108
+
109
+ end
110
+
111
+
112
+ end