purple_shoes 0.0.101

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 (215) hide show
  1. data/README.md +56 -0
  2. data/VERSION +1 -0
  3. data/bin/pshoes +23 -0
  4. data/bin/pshoes.bat +2 -0
  5. data/lib/plugins/video.rb +88 -0
  6. data/lib/purple_shoes.rb +51 -0
  7. data/lib/shoes/anim.rb +47 -0
  8. data/lib/shoes/app.rb +688 -0
  9. data/lib/shoes/basic.rb +254 -0
  10. data/lib/shoes/colors.rb +149 -0
  11. data/lib/shoes/download.rb +26 -0
  12. data/lib/shoes/help.rb +473 -0
  13. data/lib/shoes/helper_methods.rb +295 -0
  14. data/lib/shoes/main.rb +96 -0
  15. data/lib/shoes/manual.rb +6 -0
  16. data/lib/shoes/ruby.rb +61 -0
  17. data/lib/shoes/slot.rb +104 -0
  18. data/lib/shoes/style.rb +41 -0
  19. data/lib/shoes/text.rb +46 -0
  20. data/lib/shoes/url.rb +14 -0
  21. data/lib/shoes/widget.rb +23 -0
  22. data/samples/class-book.yaml +387 -0
  23. data/samples/cy.png +0 -0
  24. data/samples/loogink.png +0 -0
  25. data/samples/potato_chopping/1258_s001.gif +0 -0
  26. data/samples/potato_chopping/1258_s002.gif +0 -0
  27. data/samples/potato_chopping/1258_s003.gif +0 -0
  28. data/samples/potato_chopping/1258_s004.gif +0 -0
  29. data/samples/potato_chopping/1258_s005.gif +0 -0
  30. data/samples/potato_chopping/1258_s006.gif +0 -0
  31. data/samples/potato_chopping/1258_s007.gif +0 -0
  32. data/samples/potato_chopping/1258_s008.gif +0 -0
  33. data/samples/potato_chopping/1258_s009.gif +0 -0
  34. data/samples/potato_chopping/1258_s010.gif +0 -0
  35. data/samples/potato_chopping/1258_s011.gif +0 -0
  36. data/samples/potato_chopping/1258_s012.gif +0 -0
  37. data/samples/potato_chopping/1258_s013.gif +0 -0
  38. data/samples/potato_chopping/1258_s014.gif +0 -0
  39. data/samples/potato_chopping/1258_s015.gif +0 -0
  40. data/samples/potato_chopping/1258_s016.gif +0 -0
  41. data/samples/potato_chopping/1258_s017.gif +0 -0
  42. data/samples/potato_chopping/1258_s018.gif +0 -0
  43. data/samples/potato_chopping/1258_s019.gif +0 -0
  44. data/samples/potato_chopping/1258_s020.gif +0 -0
  45. data/samples/potato_chopping/1258_s021.gif +0 -0
  46. data/samples/potato_chopping/1258_s022.gif +0 -0
  47. data/samples/potato_chopping/1258_s023.gif +0 -0
  48. data/samples/potato_chopping/1258_s024.gif +0 -0
  49. data/samples/potato_chopping/1258_s025.gif +0 -0
  50. data/samples/potato_chopping/1258_s026.gif +0 -0
  51. data/samples/potato_chopping/1258_s027.gif +0 -0
  52. data/samples/potato_chopping/1258_s028.gif +0 -0
  53. data/samples/potato_chopping/1258_s029.gif +0 -0
  54. data/samples/potato_chopping/1258_s030.gif +0 -0
  55. data/samples/potato_chopping/1258_s031.gif +0 -0
  56. data/samples/potato_chopping/1258_s032.gif +0 -0
  57. data/samples/potato_chopping/1258_s033.gif +0 -0
  58. data/samples/potato_chopping/1258_s034.gif +0 -0
  59. data/samples/potato_chopping/1258_s035.gif +0 -0
  60. data/samples/potato_chopping/1258_s036.gif +0 -0
  61. data/samples/potato_chopping/1258_s037.gif +0 -0
  62. data/samples/potato_chopping/1258_s038.gif +0 -0
  63. data/samples/potato_chopping/1258_s039.gif +0 -0
  64. data/samples/potato_chopping/1258_s040.gif +0 -0
  65. data/samples/potato_chopping/1258_s041.gif +0 -0
  66. data/samples/potato_chopping/1258_s042.gif +0 -0
  67. data/samples/potato_chopping/1258_s043.gif +0 -0
  68. data/samples/potato_chopping/1258_s044.gif +0 -0
  69. data/samples/potato_chopping/1258_s045.gif +0 -0
  70. data/samples/potato_chopping/1258_s046.gif +0 -0
  71. data/samples/potato_chopping/1258_s047.gif +0 -0
  72. data/samples/potato_chopping/1258_s048.gif +0 -0
  73. data/samples/potato_chopping/1258_s049.gif +0 -0
  74. data/samples/potato_chopping/1258_s050.gif +0 -0
  75. data/samples/potato_chopping/1258_s051.gif +0 -0
  76. data/samples/potato_chopping/1258_s052.gif +0 -0
  77. data/samples/potato_chopping/1258_s053.gif +0 -0
  78. data/samples/potato_chopping/1258_s054.gif +0 -0
  79. data/samples/potato_chopping/1258_s055.gif +0 -0
  80. data/samples/potato_chopping/1258_s056.gif +0 -0
  81. data/samples/potato_chopping/1258_s057.gif +0 -0
  82. data/samples/potato_chopping/1258_s058.gif +0 -0
  83. data/samples/potato_chopping/1258_s059.gif +0 -0
  84. data/samples/sample1.rb +30 -0
  85. data/samples/sample10.rb +11 -0
  86. data/samples/sample11.rb +12 -0
  87. data/samples/sample12.rb +22 -0
  88. data/samples/sample13.rb +15 -0
  89. data/samples/sample14.rb +75 -0
  90. data/samples/sample15.rb +20 -0
  91. data/samples/sample16.rb +12 -0
  92. data/samples/sample17.rb +12 -0
  93. data/samples/sample18.rb +24 -0
  94. data/samples/sample19.rb +39 -0
  95. data/samples/sample2.rb +16 -0
  96. data/samples/sample20.rb +26 -0
  97. data/samples/sample21.rb +7 -0
  98. data/samples/sample22.rb +13 -0
  99. data/samples/sample23.rb +10 -0
  100. data/samples/sample24.rb +22 -0
  101. data/samples/sample25.rb +22 -0
  102. data/samples/sample27.rb +19 -0
  103. data/samples/sample28.rb +64 -0
  104. data/samples/sample29.rb +12 -0
  105. data/samples/sample3.rb +10 -0
  106. data/samples/sample30.rb +30 -0
  107. data/samples/sample31.rb +24 -0
  108. data/samples/sample34.rb +29 -0
  109. data/samples/sample35.rb +33 -0
  110. data/samples/sample36.rb +48 -0
  111. data/samples/sample37.rb +10 -0
  112. data/samples/sample38.rb +14 -0
  113. data/samples/sample4.rb +9 -0
  114. data/samples/sample40.rb +19 -0
  115. data/samples/sample42.rb +15 -0
  116. data/samples/sample43.rb +26 -0
  117. data/samples/sample44.rb +57 -0
  118. data/samples/sample45.rb +12 -0
  119. data/samples/sample46.rb +35 -0
  120. data/samples/sample47.rb +20 -0
  121. data/samples/sample48.rb +33 -0
  122. data/samples/sample49.rb +33 -0
  123. data/samples/sample5.rb +8 -0
  124. data/samples/sample50.rb +326 -0
  125. data/samples/sample58.rb +19 -0
  126. data/samples/sample6.rb +11 -0
  127. data/samples/sample7.rb +5 -0
  128. data/samples/sample8.rb +9 -0
  129. data/samples/sample9.rb +12 -0
  130. data/samples/sample99.rb +4 -0
  131. data/samples/sounds/102719__sarge4267__explosion.mp3 +0 -0
  132. data/samples/sounds/145622__andybrannan__train-fog-horn-long-wyomming.aiff +0 -0
  133. data/samples/sounds/46492__phreaksaccount__shields1.ogg +0 -0
  134. data/samples/sounds/61847__simon-rue__boink-v3.wav +0 -0
  135. data/snapshots/sample1.png +0 -0
  136. data/snapshots/sample10.png +0 -0
  137. data/snapshots/sample11.png +0 -0
  138. data/snapshots/sample12.png +0 -0
  139. data/snapshots/sample13.png +0 -0
  140. data/snapshots/sample14.png +0 -0
  141. data/snapshots/sample15.png +0 -0
  142. data/snapshots/sample16.png +0 -0
  143. data/snapshots/sample17.png +0 -0
  144. data/snapshots/sample18.png +0 -0
  145. data/snapshots/sample19.png +0 -0
  146. data/snapshots/sample2.png +0 -0
  147. data/snapshots/sample20.png +0 -0
  148. data/snapshots/sample21.png +0 -0
  149. data/snapshots/sample22.png +0 -0
  150. data/snapshots/sample23.png +0 -0
  151. data/snapshots/sample24.png +0 -0
  152. data/snapshots/sample25.png +0 -0
  153. data/snapshots/sample27.png +0 -0
  154. data/snapshots/sample28.png +0 -0
  155. data/snapshots/sample29.png +0 -0
  156. data/snapshots/sample3-osx.png +0 -0
  157. data/snapshots/sample3.png +0 -0
  158. data/snapshots/sample30.png +0 -0
  159. data/snapshots/sample31.png +0 -0
  160. data/snapshots/sample33.png +0 -0
  161. data/snapshots/sample34.png +0 -0
  162. data/snapshots/sample35.png +0 -0
  163. data/snapshots/sample36.png +0 -0
  164. data/snapshots/sample37.png +0 -0
  165. data/snapshots/sample38.png +0 -0
  166. data/snapshots/sample4.png +0 -0
  167. data/snapshots/sample40.png +0 -0
  168. data/snapshots/sample42.png +0 -0
  169. data/snapshots/sample43.png +0 -0
  170. data/snapshots/sample44-linux.png +0 -0
  171. data/snapshots/sample44.png +0 -0
  172. data/snapshots/sample45.png +0 -0
  173. data/snapshots/sample46.png +0 -0
  174. data/snapshots/sample47.png +0 -0
  175. data/snapshots/sample48.png +0 -0
  176. data/snapshots/sample49.png +0 -0
  177. data/snapshots/sample5.png +0 -0
  178. data/snapshots/sample50.png +0 -0
  179. data/snapshots/sample58.png +0 -0
  180. data/snapshots/sample6.png +0 -0
  181. data/snapshots/sample7.png +0 -0
  182. data/snapshots/sample8.png +0 -0
  183. data/snapshots/sample9.png +0 -0
  184. data/snapshots/sample99.png +0 -0
  185. data/static/code_highlighter.js +188 -0
  186. data/static/code_highlighter_ruby.js +26 -0
  187. data/static/man-editor-notepad.png +0 -0
  188. data/static/man-editor-osx.png +0 -0
  189. data/static/man-ele-background.png +0 -0
  190. data/static/man-ele-border.png +0 -0
  191. data/static/man-ele-button.png +0 -0
  192. data/static/man-ele-check.png +0 -0
  193. data/static/man-ele-editbox.png +0 -0
  194. data/static/man-ele-editline.png +0 -0
  195. data/static/man-ele-image.png +0 -0
  196. data/static/man-ele-listbox.png +0 -0
  197. data/static/man-ele-progress.png +0 -0
  198. data/static/man-ele-radio.png +0 -0
  199. data/static/man-ele-shape.png +0 -0
  200. data/static/man-ele-textblock.png +0 -0
  201. data/static/man-ele-video.png +0 -0
  202. data/static/man-shot1.png +0 -0
  203. data/static/manual-en.txt +3969 -0
  204. data/static/manual-ja.txt +3882 -0
  205. data/static/manual.css +184 -0
  206. data/static/purple_shoes-icon.png +0 -0
  207. data/static/rshoes-icon.png +0 -0
  208. data/static/shoes-manual-apps.png +0 -0
  209. data/static/sound_jars/jl1.0.1.jar +0 -0
  210. data/static/sound_jars/jogg-0.0.7.jar +0 -0
  211. data/static/sound_jars/jorbis-0.0.15.jar +0 -0
  212. data/static/sound_jars/mp3spi1.9.5.jar +0 -0
  213. data/static/sound_jars/tritonus_share.jar +0 -0
  214. data/static/sound_jars/vorbisspi1.0.3.jar +0 -0
  215. metadata +271 -0
@@ -0,0 +1,254 @@
1
+ class Shoes
2
+ class Basic
3
+ include Mod
4
+ def initialize args
5
+ @initials = args
6
+ args.each do |k, v|
7
+ instance_variable_set "@#{k}", v
8
+ end
9
+
10
+ (@app.order << self) unless @noorder
11
+ (@app.cslot.contents << self) unless @nocontrol
12
+
13
+ @parent = @app.cslot
14
+
15
+ Basic.class_eval do
16
+ attr_accessor *args.keys
17
+ end
18
+
19
+ if @real
20
+ if @real.is_a? Swt::Image
21
+ @width = @full_width if @width.zero?
22
+ @height = @full_height if @height.zero?
23
+ elsif @real.is_a? Symbol
24
+ # do nothing
25
+ else
26
+ @width, @height = @real.getSize.x, @real.getSize.y
27
+ end
28
+ end
29
+
30
+ set_margin
31
+ @width += (@margin_left + @margin_right)
32
+ @height += (@margin_top + @margin_bottom)
33
+
34
+ [:app, :real].each{|k| args.delete k}
35
+ @args = args
36
+ @dps = []
37
+ end
38
+
39
+ attr_reader :args, :initials
40
+ attr_accessor :parent, :pl, :ln, :dps
41
+
42
+ def hided
43
+ @app.hided or @hided
44
+ end
45
+
46
+ def move x, y
47
+ @app.cslot.contents -= [self]
48
+ move3 x, y
49
+ self
50
+ end
51
+
52
+ def move2 x, y
53
+ move3 x, y
54
+ end
55
+
56
+ def move3 x, y
57
+ unless @app.cs.isDisposed
58
+ @app.cs.redraw @left, @top, @width, @height, false
59
+ @app.cs.redraw x, y, @width, @height, false
60
+ end
61
+ @left, @top = x, y
62
+ end
63
+
64
+ def positioning x, y, max
65
+ if parent.is_a?(Flow) and x + @width <= parent.left + parent.width
66
+ move3 x + parent.margin_left, max.top + parent.margin_top
67
+ max = self if max.height < @height
68
+ else
69
+ move3 parent.left + parent.margin_left, max.top + max.height + parent.margin_top
70
+ max = self
71
+ end
72
+ max
73
+ end
74
+
75
+ def clear
76
+ @app.cs.removePaintListener pl if pl
77
+ @app.cs.removeListener Swt::SWT::MouseDown, ln if ln
78
+ @app.cs.removeListener Swt::SWT::MouseUp, ln if ln
79
+ @real.dispose unless @real.is_a? Symbol
80
+ @dps.each{|dp| dp.dispose if dp}
81
+ @dps.clear
82
+ @parent.contents -= [self]
83
+ @app.mscs -= [self]
84
+ hide
85
+ end
86
+
87
+ def show
88
+ @hided = true
89
+ toggle
90
+ end
91
+
92
+ def hide
93
+ @hided = false
94
+ toggle
95
+ end
96
+
97
+ def toggle
98
+ @hided = !@hided
99
+ @app.cs.redraw @left, @top, @width, @height, false unless @app.cs.isDisposed
100
+ self
101
+ end
102
+
103
+ def fix_size
104
+ flag = false
105
+ set_margin
106
+ case self
107
+ when EditBox, Button
108
+ if 0 < @initials[:width] and @initials[:width] <= 1.0
109
+ @width = @parent.width * @initials[:width] - @margin_left - @margin_right
110
+ flag = true
111
+ end
112
+ if 0 < @initials[:height] and @initials[:height] <= 1.0
113
+ @height = @parent.height * @initials[:height] - @margin_top - @margin_bottom
114
+ flag = true
115
+ end
116
+ when EditLine, ListBox
117
+ if 0 < @initials[:width] and @initials[:width] <= 1.0
118
+ @width = @parent.width * @initials[:width] - @margin_left - @margin_right
119
+ @height = 20
120
+ flag = true
121
+ end
122
+ else
123
+ end
124
+ if flag
125
+ @real.setSize @width, @height
126
+ move @left, @top
127
+ end
128
+ end
129
+ end
130
+
131
+ class Image < Basic; end
132
+
133
+ class Pattern < Basic
134
+ def positioning x, y, max
135
+ self.width = self.height = 0
136
+ super
137
+ end
138
+ def move2 x, y
139
+ @left, @top, @width, @height = parent.left, parent.top, parent.width, parent.height
140
+ @width = @args[:width] unless @args[:width].zero?
141
+ @height = @args[:height] unless @args[:height].zero?
142
+ unless @real
143
+ m = self.class.to_s.downcase[7..-1]
144
+ args = eval "{#{@args.keys.map{|k| "#{k}: @#{k}"}.join(', ')}}"
145
+ args = [@pattern, args.merge({create_real: true, nocontrol: true})]
146
+ pt = @app.send(m, *args)
147
+ @real = pt.real
148
+ end
149
+ end
150
+ end
151
+ class Background < Pattern; end
152
+ class Border < Pattern; end
153
+
154
+ class ShapeBase < Basic; end
155
+ class Rect < ShapeBase; end
156
+ class Oval < ShapeBase; end
157
+ class Line < ShapeBase; end
158
+ class Star < ShapeBase; end
159
+ class Shape < ShapeBase
160
+ def move_to x, y
161
+ real.moveTo x + left, y + top
162
+ end
163
+ def line_to x, y
164
+ real.lineTo x + left, y + top
165
+ end
166
+ def quad_to cx, cy, x, y
167
+ real.quadTo cx + left, cy + top, x + left, y + top
168
+ end
169
+ end
170
+
171
+ class TextBlock < Basic
172
+ def initialize args
173
+ @links = []
174
+ super
175
+ end
176
+ attr_reader :links
177
+ def text
178
+ @args[:markup]
179
+ end
180
+ def text= s
181
+ style markup: s
182
+ end
183
+ def positioning x, y, max
184
+ self.text = @args[:markup]
185
+ super.tap{|s| s.height += (@margin_top + @margin_bottom) if s == self}
186
+ end
187
+ def move x, y
188
+ self.text = @args[:markup]
189
+ super
190
+ end
191
+ def clear
192
+ @links.each &:clear
193
+ @links.clear
194
+ super
195
+ end
196
+ end
197
+ class Banner < TextBlock; end
198
+ class Title < TextBlock; end
199
+ class Subtitle < TextBlock; end
200
+ class Tagline < TextBlock; end
201
+ class Caption < TextBlock; end
202
+ class Para < TextBlock; end
203
+ class Inscription < TextBlock; end
204
+
205
+ class Native < Basic
206
+ def text
207
+ @real.getText
208
+ end
209
+ def text=(s)
210
+ @real.setText s.to_s
211
+ end
212
+ def move x, y
213
+ @real.setLocation x, y
214
+ super
215
+ end
216
+ def move2 x, y
217
+ @real.setLocation x, y
218
+ super
219
+ end
220
+ def clear
221
+ @real.dispose
222
+ @parent.contents -= [self]
223
+ end
224
+ def toggle
225
+ @hided = !@hided
226
+ @real.setVisible !@hided unless @real.isDisposed
227
+ self
228
+ end
229
+ end
230
+
231
+ class Button < Native; end
232
+ class ToggleButton < Button
233
+ def checked?
234
+ real.getSelection
235
+ end
236
+ def checked=(tof)
237
+ real.setSelection tof
238
+ block.call if tof
239
+ end
240
+ end
241
+ class Radio < ToggleButton; end
242
+
243
+ class EditLine < Native; end
244
+ class EditBox < Native; end
245
+ class ListBox < Native; end
246
+ class Progress < Native
247
+ def fraction
248
+ @real.isDisposed ? 0 : real.getSelection / 100.0
249
+ end
250
+ def fraction= n
251
+ real.setSelection n * 100 unless @real.isDisposed
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,149 @@
1
+ class Shoes
2
+ colors = [
3
+ [:aliceblue, 240, 248, 255],
4
+ [:antiquewhite, 250, 235, 215],
5
+ [:aqua, 0, 255, 255],
6
+ [:aquamarine, 127, 255, 212],
7
+ [:azure, 240, 255, 255],
8
+ [:beige, 245, 245, 220],
9
+ [:bisque, 255, 228, 196],
10
+ [:black, 0, 0, 0],
11
+ [:blanchedalmond, 255, 235, 205],
12
+ [:blue, 0, 0, 255],
13
+ [:blueviolet, 138, 43, 226],
14
+ [:brown, 165, 42, 42],
15
+ [:burlywood, 222, 184, 135],
16
+ [:cadetblue, 95, 158, 160],
17
+ [:chartreuse, 127, 255, 0],
18
+ [:chocolate, 210, 105, 30],
19
+ [:coral, 255, 127, 80],
20
+ [:cornflowerblue, 100, 149, 237],
21
+ [:cornsilk, 255, 248, 220],
22
+ [:crimson, 220, 20, 60],
23
+ [:cyan, 0, 255, 255],
24
+ [:darkblue, 0, 0, 139],
25
+ [:darkcyan, 0, 139, 139],
26
+ [:darkgoldenrod, 184, 134, 11],
27
+ [:darkgray, 169, 169, 169],
28
+ [:darkgreen, 0, 100, 0],
29
+ [:darkkhaki, 189, 183, 107],
30
+ [:darkmagenta, 139, 0, 139],
31
+ [:darkolivegreen, 85, 107, 47],
32
+ [:darkorange, 255, 140, 0],
33
+ [:darkorchid, 153, 50, 204],
34
+ [:darkred, 139, 0, 0],
35
+ [:darksalmon, 233, 150, 122],
36
+ [:darkseagreen, 143, 188, 143],
37
+ [:darkslateblue, 72, 61, 139],
38
+ [:darkslategray, 47, 79, 79],
39
+ [:darkturquoise, 0, 206, 209],
40
+ [:darkviolet, 148, 0, 211],
41
+ [:deeppink, 255, 20, 147],
42
+ [:deepskyblue, 0, 191, 255],
43
+ [:dimgray, 105, 105, 105],
44
+ [:dodgerblue, 30, 144, 255],
45
+ [:firebrick, 178, 34, 34],
46
+ [:floralwhite, 255, 250, 240],
47
+ [:forestgreen, 34, 139, 34],
48
+ [:fuchsia, 255, 0, 255],
49
+ [:gainsboro, 220, 220, 220],
50
+ [:ghostwhite, 248, 248, 255],
51
+ [:gold, 255, 215, 0],
52
+ [:goldenrod, 218, 165, 32],
53
+ [:gray, 128, 128, 128],
54
+ [:green, 0, 128, 0],
55
+ [:greenyellow, 173, 255, 47],
56
+ [:honeydew, 240, 255, 240],
57
+ [:hotpink, 255, 105, 180],
58
+ [:indianred, 205, 92, 92],
59
+ [:indigo, 75, 0, 130],
60
+ [:ivory, 255, 255, 240],
61
+ [:khaki, 240, 230, 140],
62
+ [:lavender, 230, 230, 250],
63
+ [:lavenderblush, 255, 240, 245],
64
+ [:lawngreen, 124, 252, 0],
65
+ [:lemonchiffon, 255, 250, 205],
66
+ [:lightblue, 173, 216, 230],
67
+ [:lightcoral, 240, 128, 128],
68
+ [:lightcyan, 224, 255, 255],
69
+ [:lightgoldenrodyellow, 250, 250, 210],
70
+ [:lightgreen, 144, 238, 144],
71
+ [:lightgrey, 211, 211, 211],
72
+ [:lightpink, 255, 182, 193],
73
+ [:lightsalmon, 255, 160, 122],
74
+ [:lightseagreen, 32, 178, 170],
75
+ [:lightskyblue, 135, 206, 250],
76
+ [:lightslategray, 119, 136, 153],
77
+ [:lightsteelblue, 176, 196, 222],
78
+ [:lightyellow, 255, 255, 224],
79
+ [:lime, 0, 255, 0],
80
+ [:limegreen, 50, 205, 50],
81
+ [:linen, 250, 240, 230],
82
+ [:magenta, 255, 0, 255],
83
+ [:maroon, 128, 0, 0],
84
+ [:mediumaquamarine, 102, 205, 170],
85
+ [:mediumblue, 0, 0, 205],
86
+ [:mediumorchid, 186, 85, 211],
87
+ [:mediumpurple, 147, 112, 219],
88
+ [:mediumseagreen, 60, 179, 113],
89
+ [:mediumslateblue, 123, 104, 238],
90
+ [:mediumspringgreen, 0, 250, 154],
91
+ [:mediumturquoise, 72, 209, 204],
92
+ [:mediumvioletred, 199, 21, 133],
93
+ [:midnightblue, 25, 25, 112],
94
+ [:mintcream, 245, 255, 250],
95
+ [:mistyrose, 255, 228, 225],
96
+ [:moccasin, 255, 228, 181],
97
+ [:navajowhite, 255, 222, 173],
98
+ [:navy, 0, 0, 128],
99
+ [:oldlace, 253, 245, 230],
100
+ [:olive, 128, 128, 0],
101
+ [:olivedrab, 107, 142, 35],
102
+ [:orange, 255, 165, 0],
103
+ [:orangered, 255, 69, 0],
104
+ [:orchid, 218, 112, 214],
105
+ [:palegoldenrod, 238, 232, 170],
106
+ [:palegreen, 152, 251, 152],
107
+ [:paleturquoise, 175, 238, 238],
108
+ [:palevioletred, 219, 112, 147],
109
+ [:papayawhip, 255, 239, 213],
110
+ [:peachpuff, 255, 218, 185],
111
+ [:peru, 205, 133, 63],
112
+ [:pink, 255, 192, 203],
113
+ [:plum, 221, 160, 221],
114
+ [:powderblue, 176, 224, 230],
115
+ [:purple, 128, 0, 128],
116
+ [:red, 255, 0, 0],
117
+ [:rosybrown, 188, 143, 143],
118
+ [:royalblue, 65, 105, 225],
119
+ [:saddlebrown, 139, 69, 19],
120
+ [:salmon, 250, 128, 114],
121
+ [:sandybrown, 244, 164, 96],
122
+ [:seagreen, 46, 139, 87],
123
+ [:seashell, 255, 245, 238],
124
+ [:sienna, 160, 82, 45],
125
+ [:silver, 192, 192, 192],
126
+ [:skyblue, 135, 206, 235],
127
+ [:slateblue, 106, 90, 205],
128
+ [:slategray, 112, 128, 144],
129
+ [:snow, 255, 250, 250],
130
+ [:springgreen, 0, 255, 127],
131
+ [:steelblue, 70, 130, 180],
132
+ [:tan, 210, 180, 140],
133
+ [:teal, 0, 128, 128],
134
+ [:thistle, 216, 191, 216],
135
+ [:tomato, 255, 99, 71],
136
+ [:turquoise, 64, 224, 208],
137
+ [:violet, 238, 130, 238],
138
+ [:wheat, 245, 222, 179],
139
+ [:white, 255, 255, 255],
140
+ [:whitesmoke, 245, 245, 245],
141
+ [:yellow, 255, 255, 0],
142
+ [:yellowgreen, 154, 205, 50],
143
+ ]
144
+
145
+ App.class_eval do
146
+ colors.each{|c, r, g, b| define_method(c){[r, g, b]}}
147
+ end
148
+ colors.each{|c, r, g, b| COLORS[c] = [r, g, b]}
149
+ end
@@ -0,0 +1,26 @@
1
+ class Shoes
2
+ class Download
3
+ def initialize name, args, &blk
4
+ require 'open-uri'
5
+ Thread.new do
6
+ open name,
7
+ content_length_proc: lambda{|len| @content_length, @started = len, true},
8
+ progress_proc: lambda{|size| @progress = size} do |sio|
9
+ open(args[:save], 'wb'){|fw| fw.print sio.read} if args[:save]
10
+ #blk[sio] if blk
11
+ @finished = true
12
+ end
13
+ end
14
+ end
15
+
16
+ attr_reader :progress, :content_length
17
+
18
+ def started?
19
+ @started
20
+ end
21
+
22
+ def finished?
23
+ @finished
24
+ end
25
+ end
26
+ end
data/lib/shoes/help.rb ADDED
@@ -0,0 +1,473 @@
1
+ require 'hpricot'
2
+ require 'nkf'
3
+
4
+ class Manual < Shoes
5
+ url '/', :index
6
+ url '/manual/(\d+)', :index
7
+ #url '/mk_search_page', :mk_search_page
8
+
9
+ include Hpricot
10
+ #include HH::Markup
11
+
12
+ def index pnum = 0
13
+ font LANG == 'ja' ? 'MS UI Gothic' : 'Arial'
14
+ #style Link, underline: false, weight: 'bold'
15
+ #style LinkHover, stroke: '#06E'
16
+ self.scroll_top = 0
17
+ TOC.clear; TOC_LIST.clear
18
+ table_of_contents.each{|toc| TOC << toc}
19
+ pnum == '999' ? mk_search_page : manual( *get_title_and_desc(pnum.to_i) )
20
+ end
21
+
22
+ def get_title_and_desc pnum
23
+ chapter, section = PNUMS[pnum]
24
+ return nil unless chapter
25
+ if section
26
+ [pnum, DOCS[chapter][1][:sections][section][1][:title],
27
+ DOCS[chapter][1][:sections][section][1][:description],
28
+ DOCS[chapter][1][:sections][section][1][:methods]]
29
+ else
30
+ [pnum, DOCS[chapter][0], DOCS[chapter][1][:description], []]
31
+ end
32
+ end
33
+
34
+ def table_of_contents
35
+ PNUMS.map.with_index do |e, pnum|
36
+ chapter, section = e
37
+ title = section ? DOCS[chapter][1][:sections][section][1][:title] : DOCS[chapter][0]
38
+ title = title.sub('The', '').split(' ').first
39
+ TOC_LIST << [title, section]
40
+ section ? [' ', link(title){visit "/manual/#{pnum}"}, "\n"] : [link(fg(title, magenta)){visit "/manual/#{pnum}"}, "\n"]
41
+ end.flatten
42
+ end
43
+
44
+ def manual pnum, docs_title, docs_description, docs_methods
45
+ flow do
46
+ show_header docs_title
47
+ show_toc
48
+ paras = mk_paras docs_description
49
+ flow width: 0.8, margin: [10, 0, 20, 0] do
50
+ show_page paras, true
51
+ show_methods docs_methods
52
+ para link('top'){visit "/manual/0"}, " ",
53
+ link('prev'){visit "/manual/#{(pnum-1)%PEND}"}, " ",
54
+ link('next'){visit "/manual/#{(pnum+1)%PEND}"}, " ",
55
+ link('end'){visit "/manual/#{PEND-1}"}
56
+ end
57
+ end
58
+ end
59
+
60
+ def show_header docs_title
61
+ background tr_color("#ddd")..white, angle: 90
62
+ background black..magenta, height: 90
63
+ para fg("The Purple Shoes Manual #{VERSION}", gray), left: 120, top: 10
64
+ title fg(docs_title, white), left: 120, top: 30, font: 'Coolvetica'
65
+ image File.join(DIR, '../static/purple_shoes-icon.png'), left: 5, top: -12, width: 110, height: 110, nocontrol: true
66
+ end
67
+
68
+ def show_toc
69
+ stack(height: 120){}
70
+ flow width: 0.2, margin_left: 10 do
71
+ flow(margin_right: 20) do
72
+ background black.push(0.7), curve: 5
73
+ inscription "Not findng it?\n", 'Try ', link(fg 'Search', white){visit '/manual/999'}, '!', align: 'center', stroke: lightgrey
74
+ end
75
+ stack(height: 10){}
76
+ para *TOC
77
+ para link(fg 'to_html', green){html_manual}
78
+ end
79
+ end
80
+
81
+ def show_methods docs_methods, term = nil
82
+ docs_methods.each do |m, d|
83
+ flow do
84
+ background rgb(60, 60, 60), curve: 5
85
+ n = m.index("\u00BB")
86
+ if n
87
+ para ' ', fg(strong(m[0...n]), white), fg(strong(m[n..-1]), rgb(160, 160, 160))
88
+ else
89
+ para ' ', fg(strong(m), white)
90
+ end
91
+ end
92
+ para NL
93
+ show_page mk_paras(d.gsub('&', '\u0026')), false, term
94
+ end
95
+ end
96
+
97
+ def show_page paras, intro = false, term = nil
98
+ paras.each_with_index do |text, i|
99
+ if text =~ CODE_RE
100
+ text.gsub CODE_RE do |lines|
101
+ lines = lines.split NL
102
+ n = lines[1] =~ /\#\!ruby/ ? 2 : 1
103
+ _code = lines[n...-1].join(NL+' ')
104
+ flow do
105
+ background rgb(190, 190, 190), curve: 5
106
+ inscription link(fg('Run this', magenta)){eval mk_executable(_code), TOPLEVEL_BINDING}, ' ', align: 'right'
107
+ if _code.include? 'te-su-to'
108
+ para fg(code(' ' + _code), maroon), NL, margin: [-10, 10, 0, 20]
109
+ else
110
+ #para code(highlight(' ' + _code, nil)), NL, margin: [-10, 10, 0, 20]
111
+ para fg(code(' ' + _code), blueviolet), NL, margin: [-10, 10, 0, 20]
112
+ end
113
+ end
114
+ para NL
115
+ end
116
+ next
117
+ end
118
+
119
+ if text =~ /\A \* (.+)/m
120
+ $1.split(/^ \* /).each do |txt|
121
+ image File.join(DIR, '../static/purple_shoes-icon.png'), width: 20, height: 20
122
+ flow(width: 510){show_paragraph txt, intro, i, term}
123
+ end
124
+ else
125
+ show_paragraph text, intro, i, term
126
+ para NL
127
+ end
128
+ end
129
+ end
130
+
131
+ def show_paragraph txt, intro, i, term = nil
132
+ txt = txt.gsub("\n", ' ').gsub(/`(.+?)`/m){fg code($1), rgb(255, 30, 0)}.
133
+ gsub(/\^(.+?)\^/m, '\1').gsub(/'''(.+?)'''/m){strong($1)}.gsub(/''(.+?)''/m){em($1)}.
134
+ gsub(/\[\[BR\]\]/i, "\n")
135
+ txts = txt.split(/(\[\[\S+?\]\])/m).map{|s| s.split(/(\[\[\S+? .+?\]\])/m)}.flatten
136
+ case txts[0]
137
+ when /\A==== (.+) ====/; caption *marker($1, term), size: 24
138
+ when /\A=== (.+) ===/; tagline *marker($1, term), size: 12, weight: 'bold'
139
+ when /\A== (.+) ==/; subtitle *marker($1, term)
140
+ when /\A= (.+) =/; title *marker($1, term)
141
+ when /\A\{COLORS\}/; flow{color_page}
142
+ when /\A\{SAMPLES\}/; flow{sample_page}
143
+ else
144
+ para *mk_links(txts, term).flatten, NL, (intro and i.zero?) ? {size: 16} : ''
145
+ txt.gsub IMAGE_RE do
146
+ para NL
147
+ image File.join(DIR, "../static/#{$3}"), eval("{#{$2 or "margin_left: 50"}}")
148
+ end
149
+ end
150
+ end
151
+
152
+ def mk_links txts, term = nil
153
+ txts.map{|txt| txt.gsub(IMAGE_RE, '')}.
154
+ map{|txt| txt =~ /\[\[(\S+?)\]\]/m ? (t = $1.split('.'); link(ins *marker(t.last, term)){visit "/manual/#{find_pnum t.first}"}) : txt}.
155
+ map{|txt| txt =~ /\[\[(\S+?) (.+?)\]\]/m ? (url = $1; link(ins *marker($2, term)){visit url =~ /^http/ ? url : "/manual/#{find_pnum url}"}) :
156
+ (txt.is_a?(String) ? marker(txt, term) : txt)}
157
+ end
158
+
159
+ def mk_paras str
160
+ str.split("\n\n") - ['']
161
+ end
162
+
163
+ def mk_executable code
164
+ if code =~ /\# Not yet available/
165
+ "Shoes.app{para 'Sorry, not yet available...'}"
166
+ else
167
+ code
168
+ end
169
+ end
170
+
171
+ def color_page
172
+ COLORS.each do |color, v|
173
+ r, g, b = v
174
+ c = v.dark? ? white : black
175
+ flow width: 0.33 do
176
+ background send(color)
177
+ para fg(strong(color), c), align: 'center'
178
+ para fg("rgb(#{r}, #{g}, #{b})", c), align: 'center'
179
+ end
180
+ end
181
+ para NL
182
+ end
183
+
184
+ def sample_page
185
+ mk_sample_names.each do |file|
186
+ stack width: 80 do
187
+ inscription file[0...-3]
188
+ img = image File.join(DIR, "../snapshots/#{file[0..-3]}png"), width: 50, height: 50
189
+ img.click{Dir.chdir(File.join DIR, '../samples'){instance_eval(IO.read(file),file,0)}}
190
+ para NL
191
+ end
192
+ end
193
+ end
194
+
195
+ def mk_sample_names
196
+ Dir[File.join(DIR, '../samples/sample*.rb')].map do |file|
197
+ orig_name = File.basename file
198
+ dummy_name = orig_name.sub(/sample(.*)\.rb/){
199
+ first, second = $1.split('-')
200
+ "%02d%s%s" % [first.to_i, ('-' if second), second]
201
+ }
202
+ [dummy_name, orig_name]
203
+ end.sort.map &:last
204
+ end
205
+
206
+ def find_pnum page
207
+ TOC_LIST.each_with_index do |e, i|
208
+ title, section = e
209
+ return i if title == page
210
+ end
211
+ end
212
+
213
+ def self.load_docs path
214
+ str = IO.read(path).force_encoding("UTF-8")
215
+ (str.split(/^= (.+?) =/)[1..-1]/2).map do |k, v|
216
+ sparts = v.split(/^== (.+?) ==/)
217
+ sections = (sparts[1..-1]/2).map do |k2, v2|
218
+ meth = v2.split(/^=== (.+?) ===/)
219
+ k2t = k2[/^(?:The )?([\-\w]+)/, 1]
220
+ meth_plain = meth[0].gsub(IMAGE_RE, '')
221
+ h = {title: k2, section: k, description: meth[0], methods: (meth[1..-1]/2)}
222
+ [k2t, h]
223
+ end
224
+ h = {description: sparts[0], sections: sections, class: "toc" + k.downcase.gsub(/\W+/, '')}
225
+ [k, h]
226
+ end
227
+ end
228
+
229
+ def self.mk_page_numbers docs
230
+ pnum = []
231
+ docs.length.times do |i|
232
+ pnum << [i, nil]
233
+ docs[i][1][:sections].length.times do |j|
234
+ pnum << [i, j]
235
+ end
236
+ end
237
+ pnum
238
+ end
239
+
240
+ def html_manual
241
+ dir = ask_save_folder
242
+ return unless dir
243
+ FileUtils.mkdir_p File.join(dir, 'static')
244
+ FileUtils.mkdir_p File.join(dir, 'snapshots')
245
+ %w[rshoes-icon.png purple_shoes-icon.png shoes-manual-apps.png manual.css code_highlighter.js code_highlighter_ruby.js].
246
+ each{|x| FileUtils.cp "#{DIR}/../static/#{x}", "#{dir}/static"}
247
+ Dir[File.join DIR, '../static/man-*.png'].each{|x| FileUtils.cp x, "#{dir}/static"}
248
+ Dir[File.join DIR, '../snapshots/sample*.png'].each{|x| FileUtils.cp x, "#{dir}/snapshots"}
249
+
250
+ TOC_LIST.length.times do |n|
251
+ num, title, desc, methods = get_title_and_desc n
252
+ open File.join(dir, "#{TOC_LIST[n][0]}.html"), 'w' do |f|
253
+ f.puts mk_html(title, desc, methods, TOC_LIST[n+1], get_title_and_desc(n+1), mk_sidebar_list(num))
254
+ end
255
+ end
256
+ end
257
+
258
+ def mk_html title, desc, methods, next_file, next_title, menu
259
+ man = self
260
+ Hpricot do
261
+ xhtml_transitional do
262
+ head do
263
+ meta :"http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8"
264
+ title "The Purple Shoes Manual // #{title}"
265
+ script type: "text/javascript", src: "static/code_highlighter.js"
266
+ script type: "text/javascript", src: "static/code_highlighter_ruby.js"
267
+ style type: "text/css" do
268
+ text "@import 'static/manual.css';"
269
+ end
270
+ end
271
+ body do
272
+ div.main! do
273
+ div.manual! do
274
+ h2 "The Purple Shoes Manual #{VERSION}"
275
+ h1 title
276
+
277
+ paras = man.mk_paras desc
278
+ div.intro{text man.manual_p(paras.shift)}
279
+
280
+ html_paragraph = proc do
281
+ paras.each do |str|
282
+ if str =~ CODE_RE
283
+ pre{code.rb $1.gsub(/^\s*?\n/, '')}
284
+ else
285
+ cmd, str = case str
286
+ when /\A==== (.+) ====/; [:h4, $1]
287
+ when /\A=== (.+) ===/; [:h3, $1]
288
+ when /\A== (.+) ==/; [:h2, $1]
289
+ when /\A= (.+) =/; [:h1, $1]
290
+ when /\A\{COLORS\}/
291
+ COLORS.each do |color, v|
292
+ f = v.dark? ? "white" : "black"
293
+ div.color(style: "background: #{color}; color: #{f}"){h3 color.to_s; p("rgb(%d, %d, %d)" % v)}
294
+ end
295
+ when /\A\{SAMPLES\}/
296
+ man.mk_sample_names.each do |name|
297
+ name = name[0...-3]
298
+ div.sample do
299
+ h3 name
300
+ text '<a href="snapshots/%s.png"><img src="snapshots/%s.png" alt="%s" border=0 width=50 height=50></a>' % [name, name, name]
301
+ end
302
+ end
303
+ when /\A \* (.+)/m
304
+ ul{$1.split(/^ \* /).each{|x| li{self << man.manual_p(x)}}}
305
+ else
306
+ [:p, str]
307
+ end
308
+ send(cmd){self << man.manual_p(str)} if cmd.is_a?(Symbol)
309
+ end
310
+ end
311
+ end
312
+
313
+ html_paragraph.call
314
+
315
+ methods.each do |m, d|
316
+ n = m.index("\u00BB")
317
+ n ? (sig, val = m[0...n-1], m[n-1..-1]) : (sig, val = m, nil)
318
+ aname = sig[/^[^(=]+=?/].gsub(/\s/, '').downcase
319
+ a name: aname
320
+ div.divmethod do
321
+ a sig, href: "##{aname}"
322
+ text val if val
323
+ end
324
+ div.desc do
325
+ paras = man.mk_paras d
326
+ html_paragraph.call
327
+ end
328
+ end
329
+
330
+ p.next{text "Next: "; a next_title[1], href: "#{next_file[0]}.html"} if next_title
331
+ end
332
+ div.sidebar do
333
+ img src: "static/purple_shoes-icon.png"
334
+ ul do
335
+ li{a.prime "HELP", href: "./"}
336
+ menu.each do |m|
337
+ li do
338
+ unless m.is_a?(Array)
339
+ a m, href: "#{m}.html"
340
+ else
341
+ ul.sub do
342
+ m.each do |sm|
343
+ li{a sm, href: "#{sm}.html"}
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end.to_html
355
+ end
356
+
357
+ def mk_sidebar_list num
358
+ toc = []
359
+ [0..3, 4..9, 10..16, 17..32, 33..37].each do |r|
360
+ toc.push TOC_LIST[r.first][0]
361
+ toc.push(TOC_LIST[r.first+1..r.last].to_a.map &:first) if r.include?(num)
362
+ end
363
+ toc
364
+ end
365
+
366
+ def manual_p str
367
+ str.gsub(/\n+\s*/, " ").
368
+ gsub(/&/, '&amp;').gsub(/>/, '&gt;').gsub(/>/, '&lt;').gsub(/"/, '&quot;').
369
+ gsub(/`(.+?)`/m, '<code>\1</code>').gsub(/\[\[BR\]\]/i, "<br />\n").
370
+ gsub(/\^(.+?)\^/m, '\1').
371
+ gsub(/'''(.+?)'''/m, '<strong>\1</strong>').gsub(/''(.+?)''/m, '<em>\1</em>').
372
+ gsub(/\[\[((http|https):\/\/\S+?)\]\]/m, '<a href="\1" target="_new">\1</a>').
373
+ gsub(/\[\[((http|https):\/\/\S+?) (.+?)\]\]/m, '<a href="\1" target="_new">\3</a>').
374
+ gsub(/\[\[(\S+?)\]\]/m) do
375
+ ms, mn = $1.split(".", 2)
376
+ if mn
377
+ '<a href="' + ms + '.html#' + mn + '">' + mn + '</a>'
378
+ else
379
+ '<a href="' + ms + '.html">' + ms + '</a>'
380
+ end
381
+ end.
382
+ gsub(/\[\[(\S+?) (.+?)\]\]/m, '<a href="\1.html">\2</a>').
383
+ gsub(/\!(\{[^}\n]+\})?([^!\n]+\.\w+)\!/) do
384
+ '<img src="' + "static/#$2" + '" />'
385
+ end
386
+ end
387
+
388
+ def mk_search_page
389
+ flow do
390
+ show_header 'Search'
391
+ show_toc
392
+ pnum, docs_title, docs_description, docs_methods = get_title_and_desc(25)
393
+ paras = mk_paras docs_description
394
+
395
+ flow width: 0.8, margin: [10, 0, 20, 0] do
396
+ el = edit_line width: 300
397
+ button 'search' do
398
+ term = el.text.strip
399
+ unless term.empty?
400
+ descs, methods = search term
401
+ @f.clear{show_search_result term, descs, methods}
402
+ aflush
403
+ end
404
+ end
405
+ stack(height: 20){}
406
+ @f = flow{}
407
+ end
408
+ end
409
+ end
410
+
411
+ def search term
412
+ descs, methods = [], []
413
+ PNUMS.each_with_index do |(chapter, section), pnum|
414
+ pnum, docs_title, docs_description, docs_methods = get_title_and_desc(pnum)
415
+ paras = mk_paras(docs_description)
416
+ descs << [chapter, section, docs_title, paras] if paras.map{|txt| txt.gsub(CODE_RE, '').gsub(IMAGE_RE, '')}.join(' ').index(term)
417
+ docs_methods.each do |docs_method|
418
+ m, d = docs_method
419
+ methods << [chapter, section, docs_title, docs_method] if m.index(term) or d.gsub(CODE_RE, '').gsub(IMAGE_RE, '').index(term)
420
+ end
421
+ end
422
+ return descs, methods
423
+ end
424
+
425
+ def show_search_result term, descs, methods
426
+ return subtitle 'Not Found' if descs.empty? and methods.empty?
427
+ methods.each do |(chapter, section, docs_title, docs_method)|
428
+ flow margin: [10, 10, 0, 5] do
429
+ background rgb(200, 200, 200), curve: 5
430
+ para "#{DOCS[chapter][0]}: #{docs_title.sub('The', '').split(' ').first}: ",
431
+ link(docs_method[0]){@f.clear{title docs_title; show_methods [docs_method], term}; aflush}, NL
432
+ end
433
+ stack(height: 2){}
434
+ end
435
+ descs.each do |(chapter, section, docs_title, paras)|
436
+ flow margin_left: 10 do
437
+ if section
438
+ background gray, curve: 5
439
+ tagline link(fg(docs_title, white)){@f.clear{title docs_title; show_page paras, true, term}; aflush}, width: 320
440
+ inscription "Sub-Section under #{DOCS[chapter][0]}", stroke: lightgrey, width: 180
441
+ else
442
+ background black.push(0.8), curve: 5
443
+ subtitle link(fg(docs_title, white)){@f.clear{title docs_title; show_page paras, true, term}; aflush}, width: 320
444
+ inscription 'Section Header', stroke: lightgrey, width: 100
445
+ end
446
+ end
447
+ stack(height: 2){}
448
+ end
449
+ para NL
450
+ end
451
+
452
+ def marker txt, term
453
+ if term && txt
454
+ tmp = txt.split(term).map{|s| [s, bg(term, yellow)]}.flatten
455
+ txt =~ /#{term}$/ ? tmp : tmp[0...-1]
456
+ else
457
+ [txt]
458
+ end
459
+ end
460
+
461
+ IMAGE_RE = /\!(\{([^}\n]+)\})?([^!\n]+\.\w+)\!/
462
+ CODE_RE = /\{{3}(?:\s*\#![^\n]+)?(.+?)\}{3}/m
463
+ NL = "\n"
464
+ LANG = $lang.downcase[0, 2]
465
+ DOCS = load_docs($lang =~ /\.txt$/ ? $lang : File.join(DIR, "../static/manual-#{LANG}.txt"))
466
+ PNUMS = mk_page_numbers DOCS
467
+ PEND = PNUMS.length
468
+ TOC, TOC_LIST = [], []
469
+ COLORS = Shoes::COLORS
470
+ VERSION = SHOES_VERSION
471
+ end
472
+
473
+ Shoes.app title: 'The Purple Shoes Manual', width: 720, height: 640