api_proc_documentation (public)

 api_proc_documentation [ -format format ] [ -script ] [ -source ] \
    [ -xql ] [ -label label ] [ -first_line_tag first_line_tag ] \
    [ -proc_type proc_type ] proc_name

Defined in packages/acs-api-browser/tcl/acs-api-documentation-procs.tcl

Generates formatted documentation for a procedure.

Switches:
-format
(optional)
the type of documentation to generate. This parameter is deprecated and has no effect.
-script
(boolean) (optional)
include information about what script this proc lives in?
-source
(boolean) (optional)
include the source code for the script?
-xql
(boolean) (optional)
include the source code for the related xql files?
-label
(optional)
the label printed for the proc in the header line
-first_line_tag
(defaults to "<h3>") (optional)
tag for the markup of the first line
-proc_type
(optional)
Parameters:
proc_name - the name of the procedure for which to generate documentation.
Returns:
the formatted documentation string.
Error:
if the procedure is not defined.

Partial Call Graph (max 5 caller/called nodes):
%3 test_acs_api_browser_api_proc_documentation acs_api_browser_api_proc_documentation (test acs-api-browser) api_proc_documentation api_proc_documentation test_acs_api_browser_api_proc_documentation->api_proc_documentation ad_log ad_log (public) api_proc_documentation->ad_log api_call_graph_snippet api_call_graph_snippet (private) api_proc_documentation->api_call_graph_snippet api_get_body api_get_body (public) api_proc_documentation->api_get_body api_proc_format_switch api_proc_format_switch (private) api_proc_documentation->api_proc_format_switch api_proc_pretty_name api_proc_pretty_name (public) api_proc_documentation->api_proc_pretty_name api_describe_function api_describe_function (public) api_describe_function->api_proc_documentation packages/acs-api-browser/www/proc-view.tcl packages/acs-api-browser/ www/proc-view.tcl packages/acs-api-browser/www/proc-view.tcl->api_proc_documentation packages/acs-api-browser/www/procs-file-view.tcl packages/acs-api-browser/ www/procs-file-view.tcl packages/acs-api-browser/www/procs-file-view.tcl->api_proc_documentation packages/xotcl-core/www/show-object.tcl packages/xotcl-core/ www/show-object.tcl packages/xotcl-core/www/show-object.tcl->api_proc_documentation system.methodHelp system.methodHelp (public) system.methodHelp->api_proc_documentation

Testcases:
acs_api_browser_api_proc_documentation
Source code:
    #
    # Sanitize input
    #
    if {[string match *::::* $proc_name]} {
        ad_log warning "api_proc_documentation: received invalid proc_name <$proc_name>, try to sanitize"
        regsub -all -- {::::} $proc_name :: proc_name
    }
    if {[info exists format]} {
        ad_log warning "-format flag is deprecated and has no effect"
    }
    array set doc_elements {
        flags ""
        default_values ""
        switches0 ""
        switches1 ""
        positionals ""
        varargs_p 0
        script ""
        deprecated_p 0
        main ""
    }
    array set doc_elements [nsv_get api_proc_doc $proc_name]
    array set flags $doc_elements(flags)
    array set default_values $doc_elements(default_values)

    if {![info exists label]} {
        if {[llength $proc_name] > 1 && [namespace which ::xo::api] ne ""} {
            set label [::xo::api method_label $proc_name]
        } else {
            set label $proc_name
        }
    }
    if { $script_p } {
        set pretty_name [api_proc_pretty_name  -include_debug_controls  -proc_type $proc_type  -label $label  $proc_name]
    } else {
        set pretty_name [api_proc_pretty_name  -include_debug_controls  -link  -proc_type $proc_type  -label $label  $proc_name]
    }
    if {[regexp {<([^ >]+)} $first_line_tag match tag]} {
        set end_tag "</$tag>"
    } else {
        set first_line_tag "<h3>"
        set end_tag "</h3>"
    }
    append out $first_line_tag$pretty_name$end_tag

    if {[regexp {^(.*) (inst)?proc (.*)$} $proc_name match cl prefix method]
        && [namespace which ::xo::api] ne ""
    } {
        set xotclArgs 1
        set scope ""
        #
        # Since we get "method" via regexp, we have to remove the
        # curly brackets for ensemble methods
        #
        set method [lindex $method 0]
        regexp {^(.+) (.+)$} $cl match scope cl
        if {$prefix eq ""} {
            set pretty_proc_name "[::xo::api object_link $scope $cl$method"
        } else {
            set pretty_proc_name [subst {<i>&lt;instance of [::xo::api object_link $scope $cl]&gt;</i> $method}]
        }
    } else {
        set xotclArgs 0
        if {[namespace which ::xo::api] ne "" && [::xo::api isclass "" [lindex $proc_name 1]]} {
            set name [lindex $proc_name 1]
            set pretty_proc_name "[$name info class] [::xo::api object_link {} $name]"
        } else {
            set pretty_proc_name $proc_name
        }
    }

    lappend command_line $pretty_proc_name
    foreach switch $doc_elements(switches0) {
        lappend command_line [api_proc_format_switch $xotclArgs $flags($switch) $switch]
    }

    set counter 0
    foreach positional $doc_elements(positionals) {
        if { [info exists default_values($positional)] } {
            lappend command_line "\[ <i>$positional</i> \]"
        } else {
            lappend command_line "<i>$positional</i>"
        }
    }
    if { $doc_elements(varargs_p) } {
        lappend command_line "\[ <i>args</i>... \]"
    }
    foreach switch $doc_elements(switches1) {
        lappend command_line [api_proc_format_switch $xotclArgs $flags($switch) $switch]
    }

    append out [util_wrap_list $command_line]

    set intro_out ""
    if { $script_p } {
        append intro_out [subst {<p>Defined in
            <a href="/api-doc/procs-file-view?path=[ns_urlencode $doc_elements(script)]">$doc_elements(script)</a>
            <p>}]
    }

    if { $doc_elements(deprecated_p) } {
        append intro_out "<b><i>Deprecated."
        if { $doc_elements(warn_p) } {
            append intro_out " Invoking this procedure generates a warning."
        }
        append intro_out "</i></b><p>\n"
    }

    set main [lindex $doc_elements(main) 0]
    if {$main ne ""} {
        append intro_out "<p>[lindex $doc_elements(main) 0]\n<p>\n"
    }

    set blocks_out "<dl>\n"

    if { [info exists doc_elements(param)] } {
        foreach param $doc_elements(param) {
            if { [regexp {^([^ \t\n]+)[ \t\n]+(.*)$} $param "" name value] } {
                set params($name$value
            }
        }
    }

    set switches [concat $doc_elements(switches0) $doc_elements(switches1)]
    if { [llength $switches] > 0 } {
        append blocks_out "<dt>Switches:</dt><dd><dl>\n"
        foreach switch $switches {
            append blocks_out "<dt>-$switch</dt>"
            if {"boolean" in $flags($switch)} {
                append blocks_out " (boolean)"
            }

            if { [info exists default_values($switch)]
                 && $default_values($switch) ne ""
             } {
                append blocks_out " (defaults to <code>\"[ns_quotehtml $default_values($switch)]\"</code>)"
            }

            if {"required" in $flags($switch)} {
                append blocks_out " (required)"
            } else {
                append blocks_out " (optional)"
            }
            append blocks_out "</dt>"
            if { [info exists params($switch)] } {
                append blocks_out "<dd>$params($switch)</dd>"
            }
        }
        append blocks_out "</dl></dd>\n"
    }

    if { [llength $doc_elements(positionals)] > 0 } {
        append blocks_out "<dt>Parameters:</dt><dd>\n"
        foreach positional $doc_elements(positionals) {
            append blocks_out "<b>$positional</b>"
            if { [info exists default_values($positional)] } {
                if { $default_values($positional) eq "" } {
                    append blocks_out " (optional)"
                } else {
                    append blocks_out " (defaults to <code>\"$default_values($positional)\"</code>)"
                }
            }
            if { [info exists params($positional)] } {
                append blocks_out " - $params($positional)"
            }
            append blocks_out "<br>\n"
        }
        append blocks_out "</dd>\n"
    }


    # @option is used in  template:: and cms:: (and maybe should be used in some other
    # things like ad_form which have internal arg parsers.  although an option
    # and a switch are the same thing, just one is parsed in the proc itself rather than
    # by ad_proc.

    if { [info exists doc_elements(option)] } {
        append blocks_out "<b>Options:</b><dl>"
        foreach param $doc_elements(option) {
            if { [regexp {^([^ \t]+)[ \t](.+)$} $param "" name value] } {
                append blocks_out "<dt>-$name</dt><dd>$value<br></dd>"
            }
        }
        append blocks_out "</dl>"
    }


    if { [info exists doc_elements(return)] } {
        append blocks_out "<dt>Returns:</dt><dd>[join $doc_elements(return) "<br>"]</dd>\n"
    }

    if { [info exists doc_elements(error)] } {
        append blocks_out "<dt>Error:</dt><dd>[join $doc_elements(error) "<br>"]</dd>\n"
    }

    append blocks_out [::apidoc::format_common_elements doc_elements]
    set css {
        /*svg g a:link {text-decoration: none;}*/
        div.inner svg {width: 100%; margin: 0 auto;}
        svg g polygon {fill: transparent;}
        svg g g ellipse {fill: #eeeef4;}
        svg g g polygon {fill: #f4f4e4;}
    }

    set callgraph [util::inline_svg_from_dot -css $css  [api_call_graph_snippet -proc_name $proc_name -maxnodes 5]]
    if {$callgraph ne ""} {
        append blocks_out "<p><dt>Partial Call Graph (max 5 caller/called nodes):</dt><dd>$callgraph</dd>\n"
    }

    append blocks_out "<p><dt>Testcases:</dt><dd>\n"

    if {[info exists doc_elements(testcase)]} {
        set cases {}
        foreach testcase_pair $doc_elements(testcase) {
            set url [api_test_case_url $testcase_pair]
            lappend cases [subst {<a href="[ns_quotehtml $url]">[ns_quotehtml [lindex $testcase_pair 0]]</a>}]
        }
        append blocks_out [join $cases {, }]
    } else {
        append blocks_out "No testcase defined."
    }
    append blocks_out "</dd>\n</dl>\n"


    if { $source_p } {
        if {[parameter::get_from_package_key  -package_key acs-api-browser  -parameter FancySourceFormattingP  -default 1]} {
            set source_out [subst {<dt>Source code:</dt><dd>
                <pre class="code">[::apidoc::tcl_to_html $proc_name]</pre>
                </dd>
            }]
        } else {
            set source_out [subst {<dt>Source code:</dt><dd>
                <pre class="code">[ns_quotehtml [api_get_body $proc_name]]</pre>
                </dd>
            }]
        }
    } else {
        set source_out ""
    }

    set xql_base_name $::acs::rootdir/
    append xql_base_name [file rootname $doc_elements(script)]
    if { $xql_p } {
        set there {}
        set missing {}
        set xql_fn [file rootname $doc_elements(script)].xql
        if { [file exists $::acs::rootdir/$xql_fn] } {
            set content [apidoc::get_xql_snippet -proc_name $proc_name -xql_file $xql_fn]
            if {$content ne ""} {set content "<pre class='code'>$content</pre>"}
            append there [subst {<dt>Generic XQL file:</dt>
                <dd>$content
                <a href="[ns_quotehtml [export_vars -base content-page-view {{source_p 1} {path $xql_fn}}]]">$xql_fn</a>
                <p>
                </dd>

            }]
        } else {
            lappend missing Generic
        }
        set xql_fn [file rootname $doc_elements(script)]-postgresql.xql
        if { [file exists $::acs::rootdir/$xql_fn] } {
            set content [apidoc::get_xql_snippet -proc_name $proc_name -xql_file $xql_fn]
            if {$content ne ""} {set content "<pre class='code'>$content</pre>"}
            set href [export_vars -base content-page-view {{source_p 1} {path $xql_fn}}]
            append there [subst {<dt>PostgreSQL XQL file:</dt>
                <dd>$content
                <a href="[ns_quotehtml $href]">$xql_fn</a>
                <p>
                </dd>
            }]
        } else {
            lappend missing PostgreSQL
        }
        set xql_fn [file rootname $doc_elements(script)]-oracle.xql

        if { [file exists $::acs::rootdir/$xql_fn] } {
            set content [apidoc::get_xql_snippet -proc_name $proc_name -xql_file $xql_fn]
            if {$content ne ""} {set content "<pre class='code'>$content</pre>"}
            set href [export_vars -base content-page-view {{source_p 1} {path $xql_fn}}]
            append there [subst {<dt>Oracle XQL file:</dt>
                <dd>$content
                <a href="[ns_quotehtml $href]">$xql_fn</a>
                <p>
                </dd>
            }]
        } else {
            lappend missing Oracle
        }
        if {[llength $missing] > 0} {
            set xql_out [subst {<dt>XQL Not present:</dt><dd>[join $missing ", "]</dd>}]
        }
        append xql_out $there
    } else {
        set xql_out ""
    }

    set out_sections $intro_out$blocks_out$source_out$xql_out
    if {$out_sections ne ""} {
        append out <blockquote>$out_sections</blockquote>
    }
    # No "see also" yet.

    return $out
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: