# Copyright (c) 2012, Limin Fu
# This document is released under the GNU Free Documentation License.

load help;


const help_message =
@[]
  Module Help is loaded.
  Now you may run "help()" to list all the available help entries;
  or run "help('help')" for detailed information about the help system.
@[]



################################################################################
################################################################################
#### HELP
################################################################################
################################################################################
@[name]
help
@[name]

@[title]
The Online Help Module
@[title]

@[author]
Limin Fu
@[author]

@[license]
GNU Free Documentation License
@[license]


@[text]
Module @[green]help@[green] is an integrate help system to provide convenient online help for Dao.
This module provides a single type named @[green]help@[green] and a singleton object
named @[green]__helper__@[green]. The singleton object has no particular use except that
it will be the only instance object to be returned by the initializer of @[green]help@[green].
The type @[green]help@[green] provides several of initializers and static methods
to access the help system:
@[list]
==@[green]help()@[green]: see @[node]help.method.help@[node] for details;
@[comment]
There are three versions of initializers:
@[code()]
help()
help( keywords :string, run = 0 )
help( object :any, keywords :string, run = 0 )
@[code()]
The first initializer @[code]help()@[code].
@[comment]
==@[green]help.search()@[green]: see @[node]help.method.search@[node] for details;
==@[green]help.load()@[green]: see @[node]help.method.load@[node] for details;
==@[green]help.export()@[green]: see @[node]help.method.export@[node] for details;
==@[green]help.list()@[green]: see @[node]help.method.list@[node] for details;
@[list]

To understand how to write help files for this help system, 
please see @[node]help.format@[node].
@[text]




################################################################################
################################################################################
#### HELP.FORMAT
################################################################################
################################################################################
@[name]
help.format
@[name]

@[title]
Format of The Help Files
@[title]

@[text]
Help files are regular Dao source files which contain mostly verbatim texts,
and can be loaded as regular Dao modules.
Such files must have the following loading statement before any use of verbatims:

@[code(dao)]
load help;
@[code(dao)]


Then the captions of the verbatims determine how they will be interpreted by the 
help system.


Each verbatim that is captioned with "name" contains an ID string of the help entry,
example:

@[code(dao)]
@[name]
help.format
@[name]
@[code(dao)]

All the help entries in the help system are organized as a tree.
Such ID string instructs how this entry will be stored in the tree,
and how it will be located.
Each ID string is composed of multiple parts which are delimited by dots.
There is one node in the tree that is corresponding to each part of the ID string.


Each help entry may have a title which is represented by a verbatim text captioned
by "title":

@[code(dao)]
@[title]
Format of The Help Files
@[title]
@[code(dao)]


The main text of the help must be placed in verbatim strings captioned with "text".
Inside the text, several tags are supported for formatting the text:
@[list(formats)]
==Referencing help entry:
@[code]
@[node]entry_id@[node]
@[code]
For example:
@[code]
@[node]help.format@[node]
@[code]
produces this @[node]help.format@[node].

==Text coloring:

@[code]
@[foreground]text@[foreground]
@[:background]text@[:background]
@[foreground:background]text@[foreground:background]
@[code]
For example:
@[code]
@[blue]text@[blue]
@[:green]text@[:green]
@[blue:green]text@[blue:green]
@[code]
produce:
@[blue]text@[blue]
@[:green]text@[:green]
@[blue:green]text@[blue:green].

==Item listing:

@[code]
@[list]
--Item 1;
--Item 2;
@[list]
@[code]
Use @[green]==@[green] for ordered list and @[green]--@[green] for unordered list.

==Code highlighting:

@[code(example)]
@[code(lang)]
io.writeln( 'hello world!' );
sum = 0
for( i = 1 : 5 ) sum += i
@[code(lang)]
@[code(example)]
Where @[green]lang@[green] can be anything, but currently they will all be highlighted
in the same way. @[green](lang)@[green] can also be omitted.


The above example produces:

@[code(lang)]
io.writeln( 'hello world!' );
sum = 0
for( i = 1 : 5 ) sum += i
@[code(lang)]

@[list(formats)]


Tests of Dao scripts can be embedded into the help file by using a pair of
@[green]@[code(test)]@[green]. The scripts embedded by this may declare
the following global variables and constants for checking the status of
the testing result:
@[list(test)]
--@[green]global __result__@[green]: this variable should be used to 
  hold the object that needs checking;
--@[green]global __answer__@[green]: this variable should contain the
  expected value of @[green]__result__@[green];
--@[green]cosnt __stdout__@[green]: this constant can be defined to
  hold the expected standard output;
--@[green]cosnt __stderr__@[green]: this constant can be defined for
  negative tests which must fail; it should contain a phrase that is
  expected to be found in the error message.
@[list(test)]

An example to check a result object:
@[code(test)]
tup = ( index => 123, 'abc' )
tup.index = 456

global __result__ = tup
global __answer__ = ( 456, 'abc' )
@[code(test)]
An example to check the standard output:
@[code(test)]
io.writeln( 'hello!' )

const __stdout__ = 'hello!\n'
@[code(test)]
An example to check the error:
@[code(test)]
tup = ( 123, 'abc' )
idx = tup.non_existing_field

const __stderr__ = 'Member not exist'
@[code(test)]

@[text]




################################################################################
################################################################################
#### HELP.METHOD.HELP
################################################################################
################################################################################
@[name]
help.method.help
@[name]

@[title]
help()
@[title]

@[text]
@[list]
==@[green]help()@[green]

Display loaded help entried as a tree structure.

==@[green]help( keywords :string, run = 0 )@[green]

Display the help entry for @[green]keywords@[green].


The @[green]keywords@[green] can contain single or multiple dot delimited keywords,
which tells the help system how to find the help file for these keywords.
For example, with @[green]AA.BB.CC@[green], the help system will first search
a module file named @[green]help_AA_BB_CC.dao@[green], if failed, it will search
@[green]help_AA_BB.dao@[green], and then @[green]help_AA.dao@[green].
If such file is found, it will be loaded as a normal module,
and the content of the help will be extracted via the callbacks for the verbatim strings.
On successful loading, the help entries from the module will be added to the tree
in the help system.


Then the help entry with id @[green]AA.BB.CC@[green] will be searched in the help system,
and printed to the standard output if found.
If @[green]run@[green] in non-zero, all the embedded tests will be executed
and checked.


Loading a help file as a normal module will guarantee that it is loaded only once,
if it hasn't been modified since the last loading, otherwise, it will be reloaded
to update the relevant help entries in the help system.


==@[green]help( object :any, keywords :string, run = 0 )@[green]

Display the help entry for @[green]keywords@[green] that is associated with the type of
@[green]object@[green].


This method adds a prefix that is built from the type name of @[green]object@[green]
to the @[green]keywords@[green], 
then hehave identically to @[green]help( keywords :string, run = 0 )@[green].
The prefix consts of the non template-like part of the type name,
with double colons being replaced by single dots.
An additional dot is appended to the end of the prefix.

@[list]
@[text]




################################################################################
################################################################################
#### HELP.METHOD.SEARCH
################################################################################
################################################################################
@[name]
help.method.search
@[name]

@[title]
help.search()
@[title]




################################################################################
################################################################################
#### HELP.METHOD.LOAD
################################################################################
################################################################################
@[name]
help.method.load
@[name]

@[title]
help.load()
@[title]

@[text]
@[code]
load( help_file :string )
@[code]
@[text]




################################################################################
################################################################################
#### HELP.METHOD.EXPORT
################################################################################
################################################################################
@[name]
help.method.export
@[name]

@[title]
help.export()
@[title]

@[text]
@[code]
export( root = '', dir = '', format :enum<html> = $html, run = 0 )
@[code]
This method exports all the help entries under the entry @[green]root@[green]
to files in folder @[green]dir@[green] in format @[green]format@[green].
If @[green]run@[green] in non-zero, all the embedded tests will be executed
and checked.
@[text]




################################################################################
################################################################################
#### HELP.METHOD.LIST
################################################################################
################################################################################
@[name]
help.method.list
@[name]

@[title]
help.list()
@[title]

@[text]
@[code]
help.list( object :any, type :enum<values,methods,auxmeths>=$methods )
@[code]

List the values, methods or auxiliary methods that are associated with the type
of the @[green]object@[green].
@[text]
