# HG changeset patch # User Rob Hoes # Date 1274793987 -3600 # Node ID 7dedd3aba112c1653bbb22b7d057978a06bd6357 # Parent 16c80b1f9915e5955a3978d687464e4a5c8def0d Integrate API docs with OCamlDoc web interface Signed-off-by: Rob Hoes diff -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/apidoc.html --- /dev/null +++ b/ocaml/doc/apidoc.html @@ -0,0 +1,86 @@ + + + + + OCamlDoc + + + + + + + + +
+ +
+
+

XenAPI Classes

+

Click on a class to view the associated fields and messages.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Classes, Fields and Messages

+

Classes have both fields and messages. Messages are either implicit or explicit where an implicit message is one of:

+
    +
  • a constructor (usually called "create");
  • +
  • a destructor (usually called "destroy");
  • +
  • "get_by_name_label";
  • +
  • "get_by_uuid"
  • +
  • "get_record"; and
  • +
  • "get_all".
  • +
+

Explicit messages include all the rest, more class-specific messages (e.g. "VM.start", "VM.clone")

+

Every field has at least one accessor depending both on its type and whether it is read-only or read-write. Accessors for a field named "X" would be a proper subset of:

+
    +
  • set_X: change the value of field X (only if it is read-write);
  • +
  • get_X: retrieve the value of field X;
  • +
  • add_to_X: add a key/value pair (only if field has type set or map); and
  • +
  • remove_from_X: remove a key (only if a field has type set or map).
  • +
+ +

+
+ + +
+
+ + + diff -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/apidoc.js --- /dev/null +++ b/ocaml/doc/apidoc.js @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2006-2009 Citrix Systems Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +// global variables + +var cls = getQuerystring('c'); + +function qualifier(q) +{ + if (q == 'DynamicRO' || q == 'StaticRO') + return 'read-only'; + else + return 'read/write'; +} + +function transform_type(t) +{ + switch (t) { + case "String": + case "Int": + case "Float": + case "Bool": + case "DateTime": + return t.toLowerCase(); + } + + switch (t[0]) { + case "Ref": + return '' + t[1] + ' ref'; + case "Record": + return t[1] + ' record'; + case "Enum": + return t[1]; + case "Set": + return transform_type(t[1]) + ' set'; + case "Map": + return '(' + transform_type(t[1]) + ' \u2192 ' + transform_type(t[2]) + ') map'; + } + return 'Unknown[' + t + ']'; +} + +function transform_default(t) +{ + switch (t[0]) { + case "VString": + return '"' + t[1] + '"'; + case "VInt": + case "VFloat": + case "VBool": + case "VDateTime": + case "VEnum": + return t[1]; + case "VRef": + return (t[1] == "" ? "Null" : t[1]); + case "VRecord": + return t[1] + ' record'; + return t[1]; + case "VSet": + return '{' + t[1].map(function(v){return transform_default(v)}) + '}'; + case "VMap": + return '{' + t[1].map(function(v){return transform_default(v[0]) + ' \u2192 ' + transform_default(v[1])}) + '}'; + } + return 'Unknown[' + t + ']'; +} + +function make_field(fld, n) +{ + name = fld.field_name; + + html = ""; + html = '
'; + html += ''; + html += '
' + transform_type(fld.ty) + ' ' + name + ' [' + qualifier(fld.qualifier) + ']
'; + + html += '
'; + + return html; +} + +function make_message(msg, n) +{ + name = msg.msg_name; + + html = ""; + + html += '
'; + html += ''; + html += '
' + + (msg.msg_result != undefined ? transform_type(msg.msg_result[0]) : 'void') + + ' ' + name + ' (' + + msg.msg_params.map(function(p){return transform_type(p.param_type)}).join(', ') + + ')
'; + + html += '
' + msg.msg_doc + '
'; + + html += '
'; + + return html; +} + +function class_doc() +{ + 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 = 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 += '

Class: ' + cls + '

\n'; + + html += '
' + clsdoc.description + '
'; + + html += '

Fields

'; + if (fields.length > 0) { + for (i in fields) + html += make_field(fields[i], i); + } + else + html += '

None.

'; + + html += '

Messages

'; + if (messages.length > 0) { + for (i in messages) + html += make_message(messages[i], i); + } + else + html += '

None.

'; + + set_content(html); +} + +function build() +{ + html = ""; + html = '

Classes

'; + + 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); + + if (cls != "") { + class_doc(); + } +} + diff -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/codedoc.html --- /dev/null +++ b/ocaml/doc/codedoc.html @@ -0,0 +1,52 @@ + + + + + OCamlDoc + + + + + + + + +
+ +
+
+

Introduction

+

These 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.

+
+ + +
+
+ + + diff -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/index.html --- 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 -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/jsapi.ml --- a/ocaml/doc/jsapi.ml +++ b/ocaml/doc/jsapi.ml @@ -18,7 +18,7 @@ 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 -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/main.js --- /dev/null +++ b/ocaml/doc/main.js @@ -0,0 +1,49 @@ +// 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 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; +} + +function toggle(i) +{ + if (i % 2 == 0) + return "" + else + return "2" +} + +function showhide(obj) +{ + if (obj.style.display == '') + obj.style.display = 'none'; + else + obj.style.display = ''; +} + diff -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/ocamldoc.js --- a/ocaml/doc/ocamldoc.js +++ b/ocaml/doc/ocamldoc.js @@ -25,19 +25,6 @@ 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 @@ 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 @@ 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 @@ html = '
'; if (v.params.length > 0) - html += ''; + html += ''; html += ''; html += '
' + name + '
'; @@ -309,7 +288,7 @@ name = l[l.length - 1]; html = '
'; - html += ''; + html += ''; html += ''; html += '
' + name + '
'; html += '
'; @@ -418,7 +397,7 @@ 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 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 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 -r 16c80b1f9915 -r 7dedd3aba112 ocaml/doc/style.css --- a/ocaml/doc/style.css +++ b/ocaml/doc/style.css @@ -161,6 +161,16 @@ 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 @@ 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;