old quark gui: openOS is not osx only
[supercollider.git] / SCClassLibrary / deprecated / Helper / classHelper.sc
blob9423e9d28731c94818329ab0af9d9ca8442adaee
1 /*
2 // Helper, ClassHelper, UGenHelper, TopicHelper
3 // (In this file: ClassHelper)
4 // ________________________________
5 //
6 // Classes to auto generate help files following style guides.
7 // See Helper source for more comments
8 // started on 04/11/07 - andreavalle
9 */
12 ClassHelper {
14         var <>class, <>path ;
15         classvar doctype, head, preface, examples, parents ;
17         *new { arg class, path ;
18                 this.deprecated;
19                 ^super.new.initClassHelper( class, path )
20         }
22         initClassHelper { arg aClass, aPath ;
23                 var superclasses ;
24                 parents  = "" ;
25                 // here only for the special case of Object
26                 superclasses = if ( aClass == Object, { nil }, { aClass.superclasses.reverse }) ;
27                 superclasses.do({arg item ; parents = parents+item+":" }) ;
28                 class = aClass ;
29                 path = aPath ;
30                 if ( path.isNil, {
31                         GUI.current.dialog.savePanel({ arg newPath ;
32                                  path = newPath ; {this.makeHelp}.defer })
33                         }, { this.makeHelp }) ;
34         }
36         createText {
37                 // <head> tag
38                 head = "
39 <head>
40 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">
41 <meta http-equiv=\"Content-Style-Type\" content=\"text/css\">
42 <title>SuperCollider Help -"++class.name.asString++"</title>
43 <meta name=\"Generator\" content=\"Cocoa HTML Writer\">
44 <meta name=\"CocoaVersion\" content=\"824.42\">
45 <style type=\"text/css\">
46 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
47 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
48 p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
49 p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
50 p.p5 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
51 p.p6 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica}
52 p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
53 p.p8 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
54 p.p9 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #d40000}
55 p.p10 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco}
56 p.p11 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
57 p.p12 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica; min-height: 17.0px}
58 p.p13 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica; min-height: 14.0px}
59 p.p14 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #d40000}
60 p.p15 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
61 span.s1 {font: 18.0px Helvetica}
62 span.s2 {color: #1200c4}
63 span.s3 {color: #1200c4}
64 span.s4 {color: #000000}
65 span.s5 {color: #1200c4}
66 span.s6 {color: #d40000}
67 span.s7 {font: 12.0px Helvetica; color: #000000}
68 span.s8 {color: #1200c4}
69 span.s9 {color: #1200c4}
70 span.Apple-tab-span {white-space:pre}
71 </style>
72 </head>
73 " ;
74                 preface = "
75 <p class=\"p1\"><span class=\"s1\"><b>SomeClass<span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span></b></span><b>explanation of what SomeClass is and/or does</b><span class=\"s1\"><b><span class=\"Apple-tab-span\">      </span></b></span></p>
76 <p class=\"p2\"><br></p>
77 <p class=\"p1\"><b>Inherits from: </b><b>Parents</b></p>
78 <p class=\"p3\"><br></p>
79 <p class=\"p1\">More detailed prose description of SomeClass.</p>
80 <p class=\"p2\"><br></p>
81 <p class=\"p1\"><b>See also:</b> <a href=\"../Core/Object.html\"><span class=\"s2\">Object</span></a> [some other help files]</p>
82 <p class=\"p2\"><br></p>
83 <p class=\"p4\"><b>Some Important Issues Regarding SomeClass (optional)</b></p>
84 <p class=\"p2\"><br></p>
85 <p class=\"p1\">Explanation of the issues. For more information see <a href=\"../Core/Nil.html\"><span class=\"s3\">Nil</span></a> and [some other help files].</p>
86 <p class=\"p2\"><br></p>
87 "                       .replace("SomeClass", class.name.asString)
88                         .replace("Parents", parents[..parents.size-2]) ;
89                         doctype = "
90 <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">
91 " ;
92                 examples = "
93 <p class=\"p11\"><b>Examples</b></p>
94 <p class=\"p3\"><br></p>
95 <p class=\"p14\">// what this example does</p>
96 <p class=\"p15\">e = <span class=\"s9\">SomeClass</span>.new;</p>
97 <p class=\"p15\">e.instanceMethod(someObject);</p>
98 <p class=\"p15\">e.cleanUp;</p>
99 <p class=\"p3\"><br></p>
100 <p class=\"p15\">...</p>
101 "                       .replace("SomeClass", class.name.asString) ; // g is default SwingOSC server, hence e
102         }
104         makeHelp {
105                 var title = class.name.asString ;
106                 var classMethodBlock = this.createClassMethodBlock ;
107                 var getterSetter = this.createGetterSetterBlock ;
108                 var instanceMethodBlock = this.createInstanceMethodBlock ;
109                 var doc, content ;
110                 this.createText ;
111                 // here we put together all the stuff
112                 content = doctype +
113                                  "<hmtl>\n"+
114                                  head+
115                                  "<body>\n"+
116                                  preface+
117                                  classMethodBlock +
118                                  getterSetter +
119                                  instanceMethodBlock +
120                                  examples+
121                                  "</body>"+
122                                  "</html>" ;
123                 // when a path is provided, the file is written there
124                 File.new(path, "w")
125                                 .write(content)
126                                 .close ;
127                 // and reopen thru class.openHelpFile
128                 // open works if the path is a place where SC looks for Help files
129                 class.openHelpFile
130         }
134         createClassMethodBlock {
135                 var classMethods = "
136 <p class=\"p4\"><b>Creation / Class Methods</b></p>
137 <p class=\"p5\"><br></p>
138 " ;
139                 var methods = class.class.methods.collect(_.name) ;
140                 var methodBlock = "" ;
141                 methods.do({ arg m ;
142                         methodBlock = methodBlock+
143                         this.createMethod([m,
144                                 class.class.findMethod(m).argNames,
145                                  class.class.findMethod(m).argumentString
146                                 ]) ;
147                  }) ;
148                 ^(classMethods+methodBlock) ;
149         }
152         // replicated
153         createInstanceMethodBlock {
154                 var instanceMethods = "<p class=\"p11\"><b>Doing Some Task (optional)</b></p>
155 <p class=\"p12\"><br></p>
156 <p class=\"p6\">A short bit of prose explaining something about the task.</p>
157 <p class=\"p7\"><span class=\"Apple-tab-span\"> </span></p>
158 " ;
159                 var methods = class.methods.collect(_.name) ;
160                 var methodBlock = "" ;
161                 methods.do({ arg m ;
162                         methodBlock = methodBlock+
163                         this.createMethod([m,
164                                                 class.findMethod(m).argNames,
165                                                 class.findMethod(m).argumentString],
166                                                 true) ;
167                  }) ;
168                 ^(instanceMethods+methodBlock) ;
169         }
171 // this generates the (class/instance) method block
173         createMethod { arg methodArr, instance = false ;
174                 var methodBlock, argsBlock, defaultValue ;
175                 var name = methodArr[0].asString ;
176                 var example = "
177 <p class=\"p7\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span></p>
178 <p class=\"p9\"><span class=\"s4\"><span class=\"Apple-tab-span\">      </span><span class=\"Apple-tab-span\">  </span></span>// inline example</p>
179 <p class=\"p10\"><span class=\"Apple-tab-span\">        </span><span class=\"Apple-tab-span\">  </span>g = <span class=\"s5\">SomeClass</span>.new;</p>
180 <p class=\"p10\"><span class=\"Apple-tab-span\">        </span><span class=\"Apple-tab-span\">  </span>g.doSomething; <span class=\"s6\">// explanation</span></p>
181 <p class=\"p10\"><span class=\"Apple-tab-span\">        </span><span class=\"Apple-tab-span\">  </span>g.cleanUpMethod;</p>
182 <p class=\"p5\"><br></p>
183 "               .replace("SomeClass", class.name).replace("new", name) ;
184                 methodBlock = "
185 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span>*new(arg1, arg2)</b></p>
186 <p class=\"p7\"><b><span class=\"Apple-tab-span\">      </span></b></p>
187 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span><span class=\"Apple-tab-span\">  </span></b>Short prose description of method.</p>
188 " ;
189                 if      ( methodArr[1].class != SymbolArray, { ^""} ) ; // this creates the name line
190                 if (methodArr[1].size >1, {
191                         name = name+"(" ;
192                         methodArr[1][1..].do({ arg anArg ; name = name++anArg.asString++", " ;
193                         }) ;
194                         name = name[..name.size-3]++")" ; // just to skip comma
195                         }) ;
196                 if (instance == false, { name = "*"++name }) ; // class or instance?
197                 // this adds args
198                 methodBlock = methodBlock.replace("*new(arg1, arg2)", name) ;
199                 argsBlock = "
200 <p class=\"p8\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span><b>arg1 </b>- Explanation of arg1. Default value is argDefault. Other information.</p>
201 " ;
202                 // OK, the following is tricky
203                 methodArr[1][1..].do({ arg anArg, index ;
204                         defaultValue = methodArr[2].split($,)[index+1].split($=) ;
205                         defaultValue = if (defaultValue.size == 1, { "nil" }, {
206                                 defaultValue[1] }) ;
207                         methodBlock = methodBlock+argsBlock
208                                 .replace("arg1", anArg)
209                                 .replace( "argDefault", defaultValue) ;
210                 }) ;
211                 ^methodBlock +
212                         example +
213                         "<p class=\"p5\"><br></p>\n"
214         }
217         createGetterSetterBlock {
218                 var getterSetter ;
219                 var getterSetterBlock = "
220 <p class=\"p11\"><b>Accessing Instance and Class Variables</b></p>
221 <p class=\"p7\"><span class=\"Apple-tab-span\"> </span></p>
222 " ;
223                 var methods = class.methods
224                         .collect(_.name)
225                         .reject({ arg item ;
226                                 class.findMethod(item).argNames.class == SymbolArray}) ;
227                 var getter = methods.reject({ arg item ; item.asString.includes($_) }) ;
228                 var setter = methods.reject({ arg item ; item.asString.includes($_).not }) ;
229                 var names = methods.collect({ arg item ; item.asString.split($_)[0] }) ;
230                 var methodBlock = "" ;
231                 var defaultValue = "nil" ;
232                 if (names.notNil, { names = names.asSet.asArray } ) ;
234                 class.classVarNames.do({ arg clvar ;
235                                 getterSetterBlock = getterSetterBlock +
237 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span>someVar</b></p>
238 ".replace("someVar", clvar.asString)+
240 <p class=\"p7\"><b><span class=\"Apple-tab-span\">      </span></b><span class=\"Apple-tab-span\">      </span></p>
241 <p class=\"p6\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span>Explanation including the type of <b>someVar </b>and a link to its help file.</p>
242 <p class=\"p6\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span>Default value is defaultValue.</p>
243 <p class=\"p7\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span></p>
244 "               .replace("someVar", clvar.asString)
245                         });
247                 names.do({ arg m ;
248                         case
249                                 { getter.includes(m.asSymbol) and: setter.includes((m++"_").asSymbol) }
250                                         {
251                                         defaultValue = class.findMethod(m.asSymbol).argumentString ;
252                                         getterSetter =
254 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span>someVar_(arg1)</b></p>
255 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span>someVar</b></p>
257                                         }
258                                 { getter.includes(m.asSymbol) and: setter.includes((m++"_").asSymbol).not }
259                                         {
260                                         defaultValue = class.findMethod(m.asSymbol).argumentString ;
261                                         getterSetter =
263 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span>someVar</b></p>
265                                         }
266                                 { getter.includes(m.asSymbol).not and: setter.includes((m++"_").asSymbol) }
267                                         {
268                                         defaultValue = class.findMethod((m++"_").asSymbol).argumentString ;                                     getterSetter =
270 <p class=\"p6\"><b><span class=\"Apple-tab-span\">      </span>someVar_(arg1)</b></p>
272                                         } ;
273                         if ( defaultValue.isNil, { defaultValue = "nil" }) ;
274                         methodBlock = methodBlock+
275                                                 getterSetter.replace("someVar", m.asString) +
277 <p class=\"p7\"><b><span class=\"Apple-tab-span\">      </span></b><span class=\"Apple-tab-span\">      </span></p>
278 <p class=\"p6\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span>Explanation including the type of <b>someVar </b>and a link to its help file.</p>
279 <p class=\"p6\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span>Default value is defaultValue.</p>
280 <p class=\"p7\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span></p>
281 "               .replace("someVar", m.asString)
282                 .replace("defaultValue", defaultValue)
283                  }) ;
284                 ^(getterSetterBlock+methodBlock+
286 <p class=\"p7\"><span class=\"Apple-tab-span\"> </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span><span class=\"Apple-tab-span\">  </span></p>
288                 ) ;
289         }