update luadoc scripts
[ardour.git] / tools / fmt-luadoc.php
1 #!/usr/bin/php
2 <?php
3 ## USAGE
4 #
5 ## generate doc/luadoc.json.gz (lua binding doc)
6 # ./waf configure --luadoc ....
7 # ./waf
8 # ./gtk2_ardour/arluadoc > doc/luadoc.json.gz
9 #
10 ## generate doc/ardourapi.json.gz (ardour header doxygen doc)
11 # cd ../../tools/doxy2json
12 # ./ardourdoc.sh
13 # cd -
14 #
15 ## format HTML (using this scripterl)
16 # php tools/fmt-luadoc.php > /tmp/luadoc.html
17 #
18
19 ################################################################################
20 ################################################################################
21
22 $json = gzdecode (file_get_contents (dirname (__FILE__).'/../doc/luadoc.json.gz'));
23 $doc = array ();
24 foreach (json_decode ($json, true) as $b) {
25         if (!isset ($b['type'])) { continue; }
26         $b ['ldec'] = preg_replace ('/ const/', '', preg_replace ('/ const&/', '', $b['decl']));
27         if (isset ($b['ret'])) {
28                 $b['ret'] = preg_replace ('/ const/', '', preg_replace ('/ const&/', '', $b['ret']));
29         }
30         $doc[] = $b;
31 }
32
33 if (count ($doc) == 0) {
34         fwrite (STDERR, "Failed to read luadoc.json\n");
35         exit (1);
36 }
37
38 ################################################################################
39 ## Global result variables
40 ################################################################################
41
42 $classlist = array ();
43 $constlist = array ();
44
45
46 ################################################################################
47 ## Pre-process the data, collect functions, parse arguments, cross reference
48 ################################################################################
49
50
51 ################################################################################
52 # some internal helper functions first
53
54 $funclist = array ();
55 $classes = array ();
56 $consts = array ();
57
58 function my_die ($msg) {
59         fwrite (STDERR, $msg."\n");
60         exit (1);
61 }
62
63 ##function ptr_strip ($ctype) {
64 #       # boost::shared_ptr<std::list<boost::shared_ptr<ARDOUR::Route>> > >
65 #       # -> std::list<ARDOUR::Route>
66 #       $ctype = preg_replace ('/boost::shared_ptr<([^>]*)[ ]*>/', '$1', $ctype);
67 #       return preg_replace ('/boost::shared_ptr<([^>]*)[ ]*>/', '$1', $ctype);
68 #}
69
70 function arg2lua ($argtype, $flags = 0) {
71         global $classes;
72         global $consts;
73
74         # LuaBridge abstracts C++ references
75         $flags |= preg_match ('/&$/', $argtype);
76         $arg = preg_replace ('/&$/', '', $argtype);
77         $arg = preg_replace ('/ $/', '', $arg);
78
79         # filter out basic types
80         $builtin = array ('float', 'double', 'bool', 'std::string', 'int', 'long', 'unsigned long', 'unsigned int', 'unsigned char', 'char', 'void', 'char*', 'unsigned char*', 'void*');
81         if (in_array ($arg, $builtin)) {
82                 return array ($arg => $flags);
83         }
84
85         # check Class declarations first
86         foreach (array_merge ($classes, $consts) as $b) {
87                 if ($b['ldec'] == $arg) {
88                         return array ($b['lua'] => $flags);
89                 }
90         }
91
92         # strip class pointers -- TODO Check C'tor for given class
93         $arg = preg_replace ('/[&*]*$/', '', $argtype);
94         foreach (array_merge ($classes, $consts) as $b) {
95                 if ($b['ldec'] == $arg) {
96                         return array ($b['lua'] => $flags);
97                 }
98         }
99         if ($flags & 2) {
100                 return array ($argtype => ($flags | 4));
101         } else {
102                 return array ('--MISSING (' . $argtype . ')--' => ($flags | 4));
103         }
104 }
105
106 function stripclass ($classname, $name) {
107         $classname .= ':';
108         if (strpos ($name, $classname) !== 0) {
109                 my_die ('invalid class prefix: ' .$classname. ' -- '. $name);
110         }
111         return substr ($name, strlen ($classname));
112 }
113
114 function datatype ($decl) {
115         # TODO handle spaces in type. Works because
116         # we don't yet have templated types (with_space <here >)
117         return substr ($decl, 0, strpos ($decl, ' '));
118 }
119
120 function luafn2class ($lua) {
121         return substr ($lua, 0, strrpos ($lua, ':'));
122 }
123
124 function checkclass ($b) {
125         global $classlist;
126         if (!isset ($classlist[luafn2class ($b['lua'])])) {
127                 my_die ('MISSING CLASS FOR '. print_r ($b['lua'], true));
128         }
129 }
130
131 # parse functions argument list to lua-names
132 function decl2args ($decl) {
133         $start = strrpos ($decl, '(');
134         $end = strrpos ($decl, ')');
135         $args = substr ($decl, $start + 1, $end - $start - 1);
136         $arglist = preg_split ('/, */', $args);
137         $rv = array ();
138         foreach ($arglist as $a) {
139                 if (empty ($a)) { continue; }
140                 $rv[] = arg2lua ($a);
141         }
142         return $rv;
143 }
144
145 function canonical_ctor ($b) {
146         $rv = '';
147         if (preg_match('/[^(]*\(([^)*]*)\*\)(\(.*\))/', $b['decl'], $matches)) {
148                 $lc = luafn2class ($b['lua']);
149                 $cn = str_replace (':', '::', $lc);
150                 $fn = substr ($lc, 1 + strrpos ($lc, ':'));
151                 $rv = $cn . '::'. $fn . $matches[2];
152         }
153         return $rv;
154 }
155
156 function canonical_decl ($b) {
157         $rv = '';
158         $pfx = '';
159         # match clang's declatation format
160         if (preg_match('/[^(]*\(([^)*]*)\*\)\((.*)\)/', $b['decl'], $matches)) {
161                 if (strpos ($b['type'], 'Free Function') !== false) {
162                         $pfx = str_replace (':', '::', luafn2class ($b['lua'])) . '::';
163                 }
164                 $fn = substr ($b['lua'], 1 + strrpos ($b['lua'], ':'));
165                 $rv = $matches[1] . $fn . '(';
166                 $arglist = preg_split ('/, */', $matches[2]);
167                 $first = true;
168                 foreach ($arglist as $a) {
169                         if (!$first) { $rv .= ', '; }; $first = false;
170                         if (empty ($a)) { continue; }
171                         $a = preg_replace ('/([^>]) >/', '$1>', $a);
172                         $a = preg_replace ('/^Cairo::/', '', $a); // special case cairo enums
173                         $a = preg_replace ('/([^ ])&/', '$1 &', $a);
174                         $a = str_replace ('vector', 'std::vector', $a);
175                         $a = str_replace ('std::string', 'string', $a);
176                         $a = str_replace ('string const', 'const string', $a);
177                         $a = str_replace ('string', 'std::string', $a);
178                         $rv .= $a;
179                 }
180                 $rv .= ')';
181         }
182         return $pfx . $rv;
183 }
184
185 ################################################################################
186 # step 1: build class indices
187
188 foreach ($doc as $b) {
189         if (strpos ($b['type'], "[C] ") === 0) {
190                 $classes[] = $b;
191                 $classlist[$b['lua']] = $b;
192                 if (strpos ($b['type'], 'Pointer Class') === false) {
193                         $classdecl[$b['ldec']] = $b;
194                 }
195         }
196 }
197
198 foreach ($classes as $c) {
199         if (strpos ($c['type'], 'Pointer Class') !== false) { continue; }
200         if (isset ($c['parent'])) {
201                 if (isset ($classdecl[$c['parent']])) {
202                         $classlist[$c['lua']]['luaparent'][] = $classdecl[$c['parent']]['lua'];
203                 } else {
204                         my_die ('unknown parent class: ' . print_r ($c, true));
205                 }
206         }
207 }
208
209 # step 2: extract constants/enum
210 foreach ($doc as $b) {
211         switch ($b['type']) {
212         case "Constant/Enum":
213         case "Constant/Enum Member":
214                 if (strpos ($b['ldec'], '::') === false) {
215                         # for extern c enums, use the Lua Namespace
216                         $b['ldec'] = str_replace (':', '::', luafn2class ($b['lua']));
217                 }
218                 $ns = str_replace ('::', ':', $b['ldec']);
219                 $constlist[$ns][] = $b;
220                 # arg2lua lookup
221                 $b['lua'] = $ns;
222                 $consts[] = $b;
223                 break;
224         default:
225                 break;
226         }
227 }
228
229 # step 3: process functions
230 foreach ($doc as $b) {
231         switch ($b['type']) {
232         case "Constructor":
233         case "Weak/Shared Pointer Constructor":
234                 checkclass ($b);
235                 $classlist[luafn2class ($b['lua'])]['ctor'][] = array (
236                         'name' => luafn2class ($b['lua']),
237                         'args' => decl2args ($b['ldec']),
238                         'cand' => canonical_ctor ($b)
239                 );
240                 break;
241         case "Data Member":
242                 checkclass ($b);
243                 $classlist[luafn2class ($b['lua'])]['data'][] = array (
244                         'name' => $b['lua'],
245                         'ret'  => arg2lua (datatype ($b['ldec']))
246                 );
247                 break;
248         case "C Function":
249                 # we required C functions to be in a class namespace
250         case "Ext C Function":
251                 checkclass ($b);
252                 $args = array (array ('--lua--' => 0));
253                 $ret = array ('...' => 0);
254                 $ns = luafn2class ($b['lua']);
255                 $cls = $classlist[$ns];
256                 ## std::Vector std::List types
257                 if (preg_match ('/.*<([^>]*)[ ]*>/', $cls['ldec'], $templ)) {
258                         // XXX -> move to C-source
259                         switch (stripclass($ns, $b['lua'])) {
260                         case 'add':
261                                 #$args = array (array ('LuaTable {'.$templ[1].'}' => 0));
262                                 $args = array (arg2lua ($templ[1], 2));
263                                 $ret = array ('LuaTable' => 0);
264                                 break;
265                         case 'iter':
266                                 $args = array ();
267                                 $ret = array ('LuaIter' => 0);
268                                 break;
269                         case 'table':
270                                 $args = array ();
271                                 $ret = array ('LuaTable' => 0);
272                                 break;
273                         default:
274                                 break;
275                         }
276                 } else if (strpos ($cls['type'], ' Array') !== false) {
277                         $templ = preg_replace ('/[&*]*$/', '', $cls['ldec']);
278                         switch (stripclass($ns, $b['lua'])) {
279                         case 'array':
280                                 $args = array ();
281                                 $ret = array ('LuaMetaTable' => 0);
282                                 break;
283                         case 'get_table':
284                                 $args = array ();
285                                 $ret = array ('LuaTable' => 0);
286                                 break;
287                         case 'set_table':
288                                 $args = array (array ('LuaTable {'.$templ.'}' => 0));
289                                 $ret = array ('void' => 0);
290                                 break;
291                         default:
292                                 break;
293                         }
294                 }
295                 $classlist[luafn2class ($b['lua'])]['func'][] = array (
296                         'bind' => $b,
297                         'name' => $b['lua'],
298                         'args' => $args,
299                         'ret'  => $ret,
300                         'ref'  => true,
301                         'ext'  => true,
302                         'cand' => canonical_decl ($b)
303                 );
304                 break;
305         case "Free Function":
306         case "Free Function RefReturn":
307                 $funclist[luafn2class ($b['lua'])][] = array (
308                         'bind' => $b,
309                         'name' => $b['lua'],
310                         'args' => decl2args ($b['ldec']),
311                         'ret'  => arg2lua ($b['ret']),
312                         'ref'  => (strpos ($b['type'], "RefReturn") !== false),
313                         'cand' => canonical_decl ($b)
314                 );
315                 break;
316         case "Member Function":
317         case "Member Function RefReturn":
318         case "Member Pointer Function":
319         case "Weak/Shared Pointer Function":
320         case "Weak/Shared Pointer Function RefReturn":
321         case "Weak/Shared Null Check":
322         case "Weak/Shared Pointer Cast":
323         case "Static Member Function":
324                 checkclass ($b);
325                 $classlist[luafn2class ($b['lua'])]['func'][] = array (
326                         'bind' => $b,
327                         'name' => $b['lua'],
328                         'args' => decl2args ($b['ldec']),
329                         'ret'  => arg2lua ($b['ret']),
330                         'ref'  => (strpos ($b['type'], "RefReturn") !== false),
331                         'cand' => canonical_decl ($b)
332                 );
333                 break;
334         case "Constant/Enum":
335         case "Constant/Enum Member":
336                 # already handled -> $consts
337                 break;
338         default:
339                 if (strpos ($b['type'], "[C] ") !== 0) {
340                         my_die ('unhandled type: ' . $b['type']);
341                 }
342                 break;
343         }
344 }
345
346
347 # step 4: collect/group/sort
348
349 # step 4a: unify weak/shared Ptr classes
350 foreach ($classlist as $ns => $cl) {
351         if (strpos ($cl['type'], ' Array') !== false) {
352                 $classlist[$ns]['arr'] = true;
353                 continue;
354         }
355         foreach ($classes as $c) {
356                 if ($c['lua'] == $ns) {
357                         if (strpos ($c['type'], 'Pointer Class') !== false) {
358                                 $classlist[$ns]['ptr'] = true;
359                                 $classlist[$ns]['decl'] = 'boost::shared_ptr< '.$c['decl']. ' >, boost::weak_ptr< '.$c['decl']. ' >';
360                                 break;
361                         }
362                 }
363         }
364 }
365
366 # step4b: sanity check
367 foreach ($classlist as $ns => $cl) {
368         if (isset ($classes[$ns]['parent']) && !isset ($classlist[$ns]['luaparent'])) {
369                 my_die ('missing parent class: ' . print_r ($cl, true));
370         }
371 }
372
373 # step 4c: merge free functions into classlist
374 foreach ($funclist as $ns => $fl) {
375         if (isset ($classlist[$ns])) {
376                 my_die ('Free Funcion in existing namespace: '.$ns.' '. print_r ($ns, true));
377         }
378         $classlist[$ns]['func'] = $fl;
379         $classlist[$ns]['free'] = true;
380 }
381
382 # step 4d: order to chaos
383 # no array_multisort() here, sub-types are sorted after merging parents
384 ksort ($classlist);
385
386
387 ################################################################################
388 ################################################################################
389 ################################################################################
390
391
392 #### -- split here --  ####
393
394 # from here on, only $classlist and $constlist arrays are relevant.
395
396 # read function documentation from doxygen
397 $json = gzdecode (file_get_contents (dirname (__FILE__).'/../doc/ardourapi.json.gz'));
398 $api = array ();
399 foreach (json_decode ($json, true) as $a) {
400         if (!isset ($a['decl'])) { continue; }
401         if (empty ($a['decl'])) { continue; }
402         $canon = str_replace (' *', '*', $a['decl']);
403         $api[$canon] = $a;
404 }
405
406 $dox_found = 0;
407 $dox_miss = 0;
408 function doxydoc ($canonical_declaration) {
409         global $api;
410         global $dox_found;
411         global $dox_miss;
412         if (isset ($api[$canonical_declaration])) {
413                 $dox_found++;
414                 return $api[$canonical_declaration]['doc'];
415         }
416         elseif (isset ($api['ARDOUR::'.$canonical_declaration])) {
417                 $dox_found++;
418                 return $api['ARDOUR::'.$canonical_declaration]['doc'];
419         }
420         else {
421                 $dox_miss++;
422                 return '';
423         }
424 }
425
426 ################################################################################
427 # OUTPUT
428 ################################################################################
429
430
431 ################################################################################
432 # Helper functions
433 define ('NL', "\n");
434
435 function ctorname ($name) {
436         return htmlentities (str_replace (':', '.', $name));
437 }
438
439 function shortname ($name) {
440         return htmlentities (substr ($name, strrpos ($name, ':') + 1));
441 }
442
443 function varname ($a) {
444         return array_keys ($a)[0];
445 }
446
447 function name_sort_cb ($a, $b) {
448         return strcmp ($a['name'], $b['name']);
449 }
450
451 function traverse_parent ($ns, &$inherited) {
452         global $classlist;
453         $rv = '';
454         if (isset ($classlist[$ns]['luaparent'])) {
455                 $parents = array_unique ($classlist[$ns]['luaparent']);
456                 asort ($parents);
457                 foreach ($parents as $p) {
458                         if (!empty ($rv)) { $rv .= ', '; }
459                         $rv .= typelink ($p);
460                         $inherited[$p] = $classlist[$p];
461                         traverse_parent ($p, $inherited);
462                 }
463         }
464         return $rv;
465 }
466
467 function typelink ($a, $short = false, $argcls = '', $linkcls = '', $suffix = '') {
468         global $classlist;
469         global $constlist;
470         # all cross-reference links are generated here.
471         # currently anchors on a single page.
472         if (isset($classlist[$a]['free'])) {
473                 return '<a class="'.$linkcls.'" href="#'.htmlentities ($a).'">'.($short ? shortname($a) : ctorname($a)).$suffix.'</a>';
474         } else if (in_array ($a, array_keys ($classlist))) {
475                 return '<a class="'.$linkcls.'" href="#'.htmlentities($a).'">'.($short ? shortname($a) : htmlentities($a)).$suffix.'</a>';
476         } else if (in_array ($a, array_keys ($constlist))) {
477                 return '<a class="'.$linkcls.'" href="#'.ctorname ($a).'">'.($short ? shortname($a) : ctorname($a)).$suffix.'</a>';
478         } else {
479                 return '<span class="'.$argcls.'">'.htmlentities($a).$suffix.'</span>';
480         }
481 }
482
483 function format_args ($args) {
484         $rv = '<span class="functionargs"> (';
485         $first = true;
486         foreach ($args as $a) {
487                 if (!$first) { $rv .= ', '; }; $first = false;
488                 $flags = $a[varname ($a)];
489                 if ($flags & 2) {
490                         $rv .= '<em>LuaTable</em> {'.typelink (varname ($a), true, 'em').'}';
491                 }
492                 elseif ($flags & 1) {
493                         $rv .= typelink (varname ($a), true, 'em', '', '&amp;');
494                 }
495                 else {
496                         $rv .= typelink (varname ($a), true, 'em');
497                 }
498         }
499         $rv .= ')</span>';
500         return $rv;
501 }
502
503 function format_doxyclass ($cl) {
504         $rv = '';
505         if (isset ($cl['decl'])) {
506                 $doc = doxydoc ($cl['decl']);
507                 if (!empty ($doc)) {
508                         $rv.= '<div class="classdox">'.$doc.'</div>'.NL;
509                 }
510         }
511         return $rv;
512 }
513
514 function format_doxydoc ($f) {
515         $rv = '';
516         if (isset ($f['cand'])) {
517                 $doc = doxydoc ($f['cand']);
518                 if (!empty ($doc)) {
519                         $rv.= '<tr><td></td><td class="doc" colspan="2"><div class="dox">'.$doc;
520                         $rv.= '</div></td></tr>'.NL;
521                 } else if (1) { # debug
522                         $rv.= '<tr><td></td><td class="doc" colspan="2"><p>'.htmlentities($f['cand']).'</p>';
523                         $rv.= '</td></tr>'.NL;
524                 }
525         }
526         return $rv;
527 }
528 function format_class_members ($ns, $cl, &$dups) {
529         $rv = '';
530         if (isset ($cl['ctor'])) {
531                 usort ($cl['ctor'], 'name_sort_cb');
532                 $rv.= ' <tr><th colspan="3">Constructor</th></tr>'.NL;
533                 foreach ($cl['ctor'] as $f) {
534                         $rv.= ' <tr><td class="def">&Copf;</td><td class="decl">';
535                         $rv.= '<span class="functionname">'.ctorname ($f['name']).'</span>';
536                         $rv.= format_args ($f['args']);
537                         $rv.= '</td><td class="fill"></td></tr>'.NL;
538                         $rv.= format_doxydoc($f);
539                 }
540         }
541         $nondups = array ();
542         if (isset ($cl['func'])) {
543                 foreach ($cl['func'] as $f) {
544                         if (in_array (stripclass ($ns, $f['name']), $dups)) { continue; }
545                         $nondups[] = $f;
546                 }
547         }
548         if (count ($nondups) > 0) {
549                 usort ($nondups, 'name_sort_cb');
550                 $rv.= ' <tr><th colspan="3">Methods</th></tr>'.NL;
551                 foreach ($nondups as $f) {
552                         $dups[] = stripclass ($ns, $f['name']);
553                         $rv.= ' <tr><td class="def">';
554                         if ($f['ref'] && isset ($f['ext'])) {
555                                 # external C functions
556                                 $rv.= '<em>'.varname ($f['ret']).'</em>';
557                         } elseif ($f['ref'] && varname ($f['ret']) == 'void') {
558                                 # functions with reference args return args
559                                 $rv.= '<em>LuaTable</em>(...)';
560                         } elseif ($f['ref']) {
561                                 $rv.= '<em>LuaTable</em>('.typelink (varname ($f['ret']), true, 'em').', ...)';
562                         } else {
563                                 $rv.= typelink (varname ($f['ret']), true, 'em');
564                         }
565                         $rv.= '</td><td class="decl">';
566                         $rv.= '<span class="functionname"><abbr title="'.htmlentities($f['bind']['decl']).'">'.stripclass ($ns, $f['name']).'</abbr></span>';
567                         $rv.= format_args ($f['args']);
568                         $rv.= '</td><td class="fill"></td></tr>'.NL;
569                         $rv.= format_doxydoc($f);
570                 }
571         }
572         if (isset ($cl['data'])) {
573                 usort ($cl['data'], 'name_sort_cb');
574                 $rv.= ' <tr><th colspan="3">Data Members</th></tr>'.NL;
575                 foreach ($cl['data'] as $f) {
576                         $rv.= ' <tr><td class="def">'.typelink (array_keys ($f['ret'])[0], false, 'em').'</td><td class="decl">';
577                         $rv.= '<span class="functionname">'.stripclass ($ns, $f['name']).'</span>';
578                         $rv.= '</td><td class="fill"></td></tr>'.NL;
579                 }
580         }
581         return $rv;
582 }
583
584
585 ################################################################################
586 # Start Output
587
588 ?><!DOCTYPE html>
589 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
590 <head>
591 <title>Ardour Lua Bindings</title>
592 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
593 <style type="text/css">
594 div.content        { max-width:60em; margin: 1em auto; }
595 h1                 { margin:2em 0 0 0; padding:0em; border-bottom: 1px solid black;}
596 h2.cls             { margin:2em 0 0 0; padding-left:1em; border: 1px dashed #6666ee;}
597 h2.cls abbr        { text-decoration:none; cursor:default;}
598 h3.cls             { margin:1em 0 0 0;}
599 h2.class           { background-color: #aaee66; }
600 h2.enum            { background-color: #aaaaaa; }
601 h2.pointerclass    { background-color: #eeaa66; }
602 h2.array           { background-color: #66aaee; }
603 h2.opaque          { background-color: #6666aa; }
604 p.cdecl            { text-align: right; float:right; font-size:90%; margin:0; padding: 0 0 0 1em;}
605 ul.classindex      { columns: 2; -webkit-columns: 2; -moz-columns: 2; }
606 div.clear          { clear:both; }
607 p.classinfo        { margin: .25em 0;}
608 div.classdox       { padding: .1em 1em;}
609 div.classdox p     { margin: .5em 0 .5em .6em;}
610 div.classdox p     { margin: .5em 0 .5em .6em;}
611 div.classdox       { padding: .1em 1em;}
612 div.classdox p     { margin: .5em 0 .5em .6em;}
613 table.classmembers { width: 100%; }
614 table.classmembers th      { text-align:left; border-bottom:1px solid black; padding-top:1em; }
615 table.classmembers td.def  { text-align:right; padding-right:.5em;  white-space: nowrap;}
616 table.classmembers td.decl { text-align:left; padding-left:.5em; white-space: nowrap; }
617 table.classmembers td.doc  { text-align:left; padding-left:.6em; line-height: 1.2em; font-size:80%;}
618 table.classmembers td.doc div.dox {background-color:#ddd; padding: .1em 1em;}
619 table.classmembers td.doc p { margin: .5em 0; }
620 table.classmembers td.doc p.para-brief { font-size:120%; }
621 table.classmembers td.doc p.para-returns { font-size:120%; }
622 table.classmembers td.doc dl { font-size:120%; line-height: 1.3em; }
623 table.classmembers td.doc dt { font-style: italic; }
624 table.classmembers td.fill { width: 99%;}
625 table.classmembers span.em { font-style: italic;}
626 span.functionname abbr     { text-decoration:none; cursor:default;}
627 div.header         {text-align:center;}
628 div.header h1      {margin:0;}
629 div.header p       {margin:.25em;}
630 </style>
631 </head>
632 <body>
633 <div class="header">
634 <h1>Ardour Lua Bindings</h1>
635 <p>
636 <a href="#h_classes">Class Documentation</a>
637 &nbsp;|&nbsp;
638 <a href="#h_enum">Enum/Constants</a>
639 &nbsp;|&nbsp;
640 <a href="#h_index">Index</a>
641 </p>
642 </div>
643 <div class="content">
644
645 <h1 id="h_intro">Overview</h1>
646 <p>
647 The top-level entry point are <?=typelink('ARDOUR:Session')?> and <?=typelink('ArdourUI:Editor')?>.
648 Most other Classes are used indirectly starting with a Session function. e.g. Session:get_routes().
649 </p>
650 <p>
651 A few classes are dedicated to certain script types, e.g. Lua DSP processors have exclusive access to
652 <?=typelink('ARDOUR:DSP')?> and <?=typelink('ARDOUR:ChanMapping')?>. Action Hooks Scripts to
653 <?=typelink('LuaSignal:Set')?> etc.
654 </p>
655 <p>
656 Detailed documentation (parameter names, method description) is not yet available. Please stay tuned.
657 </p>
658 <h2>Short introduction to Ardour classes</h2>
659 <p>
660 Ardour's structure is object oriented. The main object is the Session. A Session contains Audio Tracks, Midi Tracks and Busses.
661 Audio and Midi tracks are derived from a more general "Track" Object,  which in turn is derived from a "Route" (aka Bus).
662 (We say "An Audio Track <em>is-a</em> Track <em>is-a</em> Route").
663 Tracks contain specifics. For Example a track <em>has-a</em> diskstream (for file i/o).
664 </p>
665 <p>
666 Operations are performed on objects. One gets a reference to an object and then calls a method.
667 e.g   obj = Session:route_by_name("Audio")   obj:set_name("Guitar")
668 </p>
669 <p>
670 Object lifetimes are managed by the Session. Most Objects cannot be directly created, but one asks the Session to create or destroy them. This is mainly due to realtime constrains:
671 you cannot simply remove a track that is currently processing audio. There are various <em>factory</em> methods for object creation or removal.
672 </p>
673
674 <?php
675 echo '<h1 id="h_classes">Class Documentation</h1>'.NL;
676
677 foreach ($classlist as $ns => $cl) {
678         $dups = array ();
679         $tbl =  format_class_members ($ns, $cl, $dups);
680
681         # format class title
682         if (empty ($tbl)) {
683                 echo '<h2 id="'.htmlentities ($ns).'" class="cls opaque"><abbr title="Opaque Object">&empty;</abbr>&nbsp;'.htmlentities ($ns).'</h2>'.NL;
684         }
685         else if (isset ($classlist[$ns]['free'])) {
686                 echo '<h2 id="'.htmlentities ($ns).'" class="cls freeclass"><abbr title="Namespace">&Nopf;</abbr>&nbsp;'.ctorname($ns).'</h2>'.NL;
687         }
688         else if (isset ($classlist[$ns]['arr'])) {
689                 echo '<h2 id="'.htmlentities ($ns).'" class="cls array"><abbr title="C Array">&ctdot;</abbr>&nbsp;'.htmlentities ($ns).'</h2>'.NL;
690         }
691         else if (isset ($classlist[$ns]['ptr'])) {
692                 echo '<h2 id="'.htmlentities ($ns).'" class="cls pointerclass"><abbr title="Pointer Class">&Rarr;</abbr>&nbsp;'. htmlentities ($ns).'</h2>'.NL;
693         } else {
694                 echo '<h2 id="'.htmlentities ($ns).'" class="cls class"><abbr title="Class">&comp;</abbr>&nbsp;'.htmlentities ($ns).'</h2>'.NL;
695         }
696         if (isset ($cl['decl'])) {
697                 echo '<p class="cdecl"><em>C&#8225;</em>: '.htmlentities ($cl['decl']).'</p>'.NL;
698         }
699
700         # print class inheritance
701         $inherited = array ();
702         $isa = traverse_parent ($ns, $inherited);
703         if (!empty ($isa)) {
704                 echo ' <p class="classinfo">is-a: '.$isa.'</p>'.NL;
705         }
706         echo '<div class="clear"></div>'.NL;
707
708         echo format_doxyclass ($cl);
709
710         # member documentation
711         if (empty ($tbl)) {
712                 echo '<p class="classinfo">This class object is only used indirectly as return-value and function-parameter. It provides no methods by itself.</p>'.NL;
713         } else {
714                 echo '<table class="classmembers">'.NL;
715                 echo $tbl;
716                 echo ' </table>'.NL;
717         }
718
719         # traverse parent classes (inherited members)
720         foreach ($inherited as $pns => $pcl) {
721                 $tbl = format_class_members ($pns, $pcl, $dups);
722                 if (!empty ($tbl)) {
723                         echo '<h3 class="cls">Inherited from '.$pns.'</h3>'.NL;
724                         echo '<table class="classmembers">'.NL;
725                         echo $tbl;
726                         echo '</table>'.NL;
727                 }
728         }
729 }
730
731 echo '<h1 id="h_enum">Enum/Constants</h1>'.NL;
732 foreach ($constlist as $ns => $cs) {
733         echo '<h2 id="'.ctorname ($ns).'" class="cls enum"><abbr title="Enum">&isin;</abbr>&nbsp;'.ctorname ($ns).'</h2>'.NL;
734         echo '<ul class="enum">'.NL;
735         foreach ($cs as $c) {
736                 echo '<li class="const">'.ctorname ($c['lua']).'</li>'.NL;
737         }
738         echo '</ul>'.NL;
739 }
740
741 echo '<h1 id="h_index" >Class Index</h1>'.NL;
742 echo '<ul class="classindex">'.NL;
743 foreach ($classlist as $ns => $cl) {
744         echo '<li>'.typelink($ns).'</li>'.NL;
745 }
746 echo '</ul>'.NL;
747
748 fwrite (STDERR, "Found $dox_found annotations. missing: $dox_miss\n");
749 ?>
750 </div>
751 </body>
752 </html>