From c5263183965ad07c593a2a5f00303aaed555d853 Mon Sep 17 00:00:00 2001 From: Rob Hoes Date: Tue, 25 May 2010 14:26:27 +0100 Subject: [PATCH] Integrate API docs with OCamlDoc web interface Signed-off-by: Rob Hoes --- ocaml/doc/apidoc.html | 3 - ocaml/doc/apidoc.js | 235 ++++++++---------------------------------- ocaml/doc/index.html | 32 ++---- ocaml/doc/jsapi.ml | 2 +- ocaml/doc/main.js | 37 ------- ocaml/doc/ocamldoc.js | 68 +++--------- ocaml/doc/style.css | 24 +++++ 7 files changed, 90 insertions(+), 311 deletions(-) diff --git a/ocaml/doc/apidoc.html b/ocaml/doc/apidoc.html index ed800777..c3ea31c1 100644 --- a/ocaml/doc/apidoc.html +++ b/ocaml/doc/apidoc.html @@ -6,13 +6,10 @@ - diff --git a/ocaml/doc/apidoc.js b/ocaml/doc/apidoc.js index d111b9de..73473bd3 100644 --- a/ocaml/doc/apidoc.js +++ b/ocaml/doc/apidoc.js @@ -15,7 +15,6 @@ // global variables var cls = getQuerystring('c'); -var rel = getQuerystring('r'); function qualifier(q) { @@ -25,33 +24,6 @@ function qualifier(q) return 'read/write'; } -function make_enum(t) -{ - n = t[1]; - obj = document.getElementById('enums'); - i = obj.children.length + 1; - obj.style.display = '' - - if (document.getElementById('enum_' + n) == null) { - html = '
'; - html += ''; - html += '
' + n + '
'; - html += '
'; - - obj.innerHTML += html; - } -} - function transform_type(t) { switch (t) { @@ -69,8 +41,7 @@ function transform_type(t) case "Record": return t[1] + ' record'; case "Enum": - make_enum(t); - return '' + t[1] + ''; + return t[1]; case "Set": return transform_type(t[1]) + ' set'; case "Map": @@ -96,62 +67,34 @@ function transform_default(t) return t[1] + ' record'; return t[1]; case "VSet": - return '{' + map(function(v){return transform_default(v)}, t[1]) + '}'; + return '{' + t[1].map(function(v){return transform_default(v)}) + '}'; case "VMap": - return '{' + map(function(v){return transform_default(v[0]) + ' \u2192 ' + transform_default(v[1])}, t[1]) + '}'; + return '{' + t[1].map(function(v){return transform_default(v[0]) + ' \u2192 ' + transform_default(v[1])}) + '}'; } return 'Unknown[' + t + ']'; } -function current_lifecycle_stage(s) -{ - if (s.length == 0) - return 'Prototype'; - else { - last_transition = s[s.length-1][0]; - switch (last_transition) { - case 'Deprecated': - return 'Deprecated'; - break; - case 'Removed': - return 'Removed'; - break; - case 'Published': - case 'Changed': - case 'Extended': - default: - return ''; - break; - } - } -} - -function get_release_name(s) -{ - return s; -} - function make_field(fld, n) { - name = fld.full_name.join('_'); + name = fld.field_name; html = ""; html = '
'; html += ''; - html += '
' + current_lifecycle_stage(fld.lifecycle) + '
'; html += '
' + transform_type(fld.ty) + ' ' + name + ' [' + qualifier(fld.qualifier) + ']
'; - html += ''; @@ -166,44 +109,46 @@ function make_message(msg, n) html += '
'; html += ''; - html += '
' + current_lifecycle_stage(msg.msg_lifecycle) + '
'; html += '
' + (msg.msg_result != undefined ? transform_type(msg.msg_result[0]) : 'void') + ' ' + name + ' (' + - map(function(p){return transform_type(p.param_type)}, msg.msg_params).join(', ') + + msg.msg_params.map(function(p){return transform_type(p.param_type)}).join(', ') + ')
'; html += '
' + msg.msg_doc + '
'; - html += ''; return html; @@ -211,40 +156,19 @@ function make_message(msg, n) function class_doc() { - contents = clsdoc.contents; - fields = fold(function(a, x){ - if (x[0] == "Field") a.push(x); - else a = a.concat(x[2]); - return a; - }, [], contents); - fields = map(function(f){return f[1];}, fields); - - fields.sort(function(a, b){return compare(a.full_name.join('_').toLowerCase(), b.full_name.join('_').toLowerCase());}); + contents = clsdoc.contents; + fields = contents.filter(function(f){return f[0] == "Field";}).map(function(f){return f[1];}); + fields.sort(function(a, b){return a.field_name.toLowerCase().charCodeAt(0) - b.field_name.toLowerCase().charCodeAt(0);}); messages = clsdoc.messages; - messages = filter(function(m){return m.msg_hide_from_docs == false;}, messages); - messages.sort(function(a, b){return compare(a.msg_name.toLowerCase(), b.msg_name.toLowerCase())}); + messages = messages.filter(function(m){return m.msg_hide_from_docs == false;}) + messages.sort(function(a, b){return a.msg_name.toLowerCase().charCodeAt(0) - b.msg_name.toLowerCase().charCodeAt(0)}); html = ""; - html += ''; - html += '
' + current_lifecycle_stage(clsdoc.obj_lifecycle) + '
'; html += '

Class: ' + cls + '

\n'; html += '
' + clsdoc.description + '
'; - html += ''; - - html += ''; - - set_content(html); - - html = '

Fields

'; + html += '

Fields

'; if (fields.length > 0) { for (i in fields) html += make_field(fields[i], i); @@ -260,101 +184,24 @@ function class_doc() else html += '

None.

'; - append_content(html); -} - -function compare_release_notes(a, b) -{ - function change_to_num(x) { - if (x.indexOf('Published') > -1) return '0'; - else if (x.indexOf('Extended') > -1) return '1'; - else if (x.indexOf('Changed') > -1) return '2'; - else if (x.indexOf('Deprecated') > -1) return '3'; - else if (x.indexOf('Removed') > -1) return '4'; - else return '5'; - } - function element_to_num(x) { - if (x.indexOf('class') > -1) return '0'; - else if (x.indexOf('field') > -1) return '1'; - else if (x.indexOf('message') > -1) return '2'; - else return '3'; - } - x = change_to_num(a[0]) + element_to_num(a[0]) + (a[1]+a[2]).toLowerCase(); - y = change_to_num(b[0]) + element_to_num(b[0]) + (b[1]+b[2]).toLowerCase(); - return compare(x, y); -} - -function release_doc() -{ - changes = []; - - for (i in release_info) { - c = release_info[i]; - for (j in c.obj_changes) - changes.push([c.obj_changes[j][0] + ' class', c.cls, '', c.obj_changes[j][2]]); - for (j in c.field_changes) - changes.push([c.field_changes[j][0] + ' field', c.cls, c.field_changes[j][1], c.field_changes[j][2]]); - for (j in c.msg_changes) - changes.push([c.msg_changes[j][0] + ' message', c.cls, c.msg_changes[j][1], c.msg_changes[j][2]]); - } - - changes.sort(compare_release_notes); - - html = ""; - html += '

Release notes: ' + get_release_name(rel) + '

\n'; - - html += ''; - - for (i in changes) { - html += ''; - } - - html += '
ChangeElementDescription
' + changes[i][0] + '' + - changes[i][1] + (changes[i][2] != '' ? '.' + changes[i][2] : '') + '' + changes[i][3] + '
'; - set_content(html); } -function class_list() +function build() { + html = ""; html = '

Classes

'; - classes.sort(function(a, b){return compare(a.toLowerCase(), b.toLowerCase())}); + classes.sort(function(a, b){return a.toLowerCase().charCodeAt(0) - b.toLowerCase().charCodeAt(0)}); for (i in classes) { c = classes[i]; html += '' + c + '
'; } append_sidebar(html); -} - -function release_list() -{ - html = '

Release notes

'; - - for (i in releases) { - r = releases[i]; - html += '' + get_release_name(r) + '
'; - } - append_sidebar(html); -} - -function build() -{ if (cls != "") { - class_list(); - release_list(); class_doc(); } - else if (rel != "") { - class_list(); - release_list(); - release_doc(); - } - else { - class_list(); - release_list(); - } } diff --git a/ocaml/doc/index.html b/ocaml/doc/index.html index 1e6d7121..c347158f 100644 --- a/ocaml/doc/index.html +++ b/ocaml/doc/index.html @@ -2,38 +2,28 @@ - OCamlDoc + Xapi Toolstack - - -
-

Introduction

-

These web pages contain source documentation of the main libraries and executables related to xapi. The documentation is automatically generated from the OCaml source files via a custom generator for OCamlDoc. Below is a list of all components that are covered, the most important one being the xapi executable itself. Clicking on a component name will bring up an overview of the OCaml modules contained in it. Clicking further will reveal the internals of a module.

-

The OCaml source code contains special comments that are displayed in the documentation, which explain the use of modules, functions etc. We are working hard to add such comments wherever they are needed, but a lot of work still needs to be done. We encourage everyone who contributes to xapi to help out and include good documentation! :)

-

Details on how to generate the documentation yourself, and how to properly document the source code, are described on this wiki page.

+

Welcome

+

These pages contain documentation of the Xapi toolstack, part of the Xen Cloud Platform, and the API it provides. +

+

The documentation is automatically generated from comments in the source code.

diff --git a/ocaml/doc/jsapi.ml b/ocaml/doc/jsapi.ml index 86d25b9e..ad1c4f5e 100644 --- a/ocaml/doc/jsapi.ml +++ b/ocaml/doc/jsapi.ml @@ -18,7 +18,7 @@ let _ = let create_json obj = let name = obj.Datamodel_types.name in let s = Jsonrpc.to_string (Datamodel_types.rpc_of_obj obj) in - Unixext.write_string_to_file ("api/" ^ name ^ ".json") s; + Unixext.write_string_to_file ("api/" ^ name ^ ".json") ("clsdoc = " ^ s); name in let names = List.map create_json objs in diff --git a/ocaml/doc/main.js b/ocaml/doc/main.js index 02d2f95b..c70041a4 100644 --- a/ocaml/doc/main.js +++ b/ocaml/doc/main.js @@ -47,40 +47,3 @@ function showhide(obj) obj.style.display = ''; } -// functional stuff - -function filter(f, l) -{ - var x = []; - for (i in l) { - if (f(l[i])) - x.push(l[i]); - } - return x; -} - -function map(f, l) -{ - var x = []; - for (i in l) { - x[i] = f(l[i]); - } - return x; -} - -function fold(f, a, l) -{ - if (l.length == 0) - return a; - else - return fold(f, f(a, l[0]), l.slice(1)); -} - -// compare function for sorting -function compare(a, b) -{ - if (a < b) return -1; - if (a > b) return 1; - return 0; -} - diff --git a/ocaml/doc/ocamldoc.js b/ocaml/doc/ocamldoc.js index 66f38461..cca65ac5 100644 --- a/ocaml/doc/ocamldoc.js +++ b/ocaml/doc/ocamldoc.js @@ -25,19 +25,6 @@ var component_deps = {}; var root = '/bind/myrepos/'; var code_url = 'http://xenbits.xen.org/xapi/'; - -// function from http://www.bloggingdeveloper.com/post/JavaScript-QueryString-ParseGet-QueryString-with-Client-Side-JavaScript.aspx -function getQuerystring(key, default_) -{ - if (default_ == null) default_ = ""; - key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); - var regex = new RegExp("[\\?&]"+key+"=([^&#]*)"); - var qs = regex.exec(window.location.href); - if (qs == null) - return default_; - else - return qs[1]; -} function fill_components() { @@ -59,7 +46,7 @@ function do_search() for (y in component_modules[c]) { m = component_modules[c][y].name; if (m.toLowerCase().indexOf(query) > -1) - html += '' + m + ' (' + c + ')
'; + html += '' + m + ' (' + c + ')
'; } } @@ -101,19 +88,11 @@ function find_component_for_module(m) return ""; } -function toggle(i) -{ - if (i % 2 == 0) - return "" - else - return "2" -} - function construct_url(mod, fn) { comp = find_component_for_module(mod.split('.')[0]); if (comp != "") - return 'index.html?c=' + comp + '&m=' + mod + '#' + fn; + return 'codedoc.html?c=' + comp + '&m=' + mod + '#' + fn; else return '#'; } @@ -161,7 +140,7 @@ function value(v, n) html = '
'; if (v.params.length > 0) - html += ''; + html += ''; html += ''; html += '
' + name + '
'; @@ -309,7 +288,7 @@ function included_module(v, n) name = l[l.length - 1]; html = '
'; - html += ''; + html += ''; html += ''; html += '
' + name + '
'; html += '
'; @@ -418,7 +397,7 @@ function make_dependencies(deps) uses = deps.uses.sort(); - html = '

Dependencies

'; + html = '

Dependencies

'; html += '

Uses

'; for (i in uses) { c = find_component_for_module(uses[i]) @@ -443,14 +422,13 @@ function make_dependencies(deps) function moduledoc(mod) { - set_sidebar(""); make_dependencies(mod.dependencies); html = ""; html += '

Module: '; chain = []; for (i in module_chain) - chain[i] = '' + module_chain[i] + ''; html += chain.join('.') + '

\n'; @@ -551,7 +529,7 @@ function module_index() // Sidebar - html = '

Module Groups

'; + html = '

Module Groups

'; if (group_names.length > 0) { for (i in group_names) html += '' + group_names[i] + '
'; @@ -570,7 +548,7 @@ function module_index() html += '

Libraries

'; for (i in libs) { if (libraries.indexOf(libs[i]) > -1) - html += '' + libs[i] + '
'; + html += '' + libs[i] + '
'; else html += '' + libs[i] + '
'; } @@ -582,13 +560,13 @@ function module_index() html += '

Packages

'; for (i in packs) { if (packages.indexOf(packs[i]) > -1) - html += '' + packs[i] + '
'; + html += '' + packs[i] + '
'; else html += '' + packs[i] + '
'; } } - set_sidebar(html); + append_sidebar(html); } function component_index() @@ -602,7 +580,7 @@ function component_index() stats = component_stats[executables[i]]; total_descr_cnt += stats.descr_cnt; total_completed_descr_cnt += stats.completed_descr_cnt; - html += '' + executables[i] + ''; + html += '' + executables[i] + ''; html += ' (' + Math.round(100 * stats.completed_descr_cnt / stats.descr_cnt) + '\%)
'; } @@ -610,7 +588,7 @@ function component_index() libraries.sort() for (i in libraries) { stats = component_stats[libraries[i]]; - html += '' + libraries[i] + ''; + html += '' + libraries[i] + ''; html += ' (' + Math.round(100 * stats.completed_descr_cnt / stats.descr_cnt) + '\%)
'; } @@ -618,7 +596,7 @@ function component_index() packages.sort() for (i in packages) { stats = component_stats[packages[i]]; - html += '' + packages[i] + ''; + html += '' + packages[i] + ''; html += ' (' + Math.round(100 * stats.completed_descr_cnt / stats.descr_cnt) + '\%)
'; } @@ -654,23 +632,3 @@ function build() } } -function set_content(html) -{ - document.getElementById('content').innerHTML = html; -} - -function append_content(html) -{ - document.getElementById('content').innerHTML += html; -} - -function set_sidebar(html) -{ - document.getElementById('sidebar').innerHTML = html; -} - -function append_sidebar(html) -{ - document.getElementById('sidebar').innerHTML += html; -} - diff --git a/ocaml/doc/style.css b/ocaml/doc/style.css index 5e66ec1d..fc110407 100644 --- a/ocaml/doc/style.css +++ b/ocaml/doc/style.css @@ -161,6 +161,16 @@ hr { text-decoration: none; } +#sidemenu { + padding-top: 1em; + padding-bottom: 1em; +// border-bottom: 1px solid white; + font-size: 1em; + text-align: center; + font-weight: bold; + background-color: #ee4400; +} + .grey { color: #ccc; } @@ -250,6 +260,20 @@ tt, .code { padding: .3em .5em .3em 0; } +.inline-type { + margin-right: .5em; +} + +.inline-qualifier { + font-size: 70%; + vertical-align: top; + margin-left: .5em; +} + +.inline-params { + margin-left: .5em; +} + .small-button { font-size: 70%; // text-align: right; -- 2.39.5