fdoc: a poor man's 'edoc', or, what I stole from Lisp
Luke Gorrie
luke@REDACTED
Wed Feb 26 23:31:40 CET 2003
Ahoy,
Just did a kinda fun hack. The idea is a semi-automatic documentation
system that:
1. Can be queried online
2. Can find documentation by itself (nothing extra in Makefiles)
3. Has a simple documentation syntax that looks good in source files
Basically, Lisp "docstrings".
The syntax I chose is: any comment appearing before a function head is
considered to be documentation for that function. Happily, this syntax
is already used by a lot of erlang code :-).
To find the documentation I have it look at the loaded modules, find
out where their sources are, and then scan the comments out of the
source files. So, it doesn't need any setup, but you may need to have
it regenerate its doc database after you load a lot of new modules.
The main interface functions are:
apropos(Regexp): print docs for all functions matching the regexp
describe(Mod, [Fun, [Arity]]): print docs for specific function(s)
Anyway, I hacked it up and checked it in on the Jungerl: module 'fdoc'
in the 'msc' application - it's kinda fun. The results it gets are
mixed (an incredible understatement), but here are a few
not-so-randomly-chosen examples to give the idea:
(erlang@REDACTED)220> fdoc:apropos("FIXME").
gstk:to_ascii/3:
FIXME: Currently we accept newlines in strings and handle this at
the Tcl side. Is this the best way or should we translate to "\n"
here?
gstk_font:choose_ascii/2:
Returns: Font specification string in Tk format
The input is {Family,Size} or {Family,Style,Size} where Family and
Style are atoms ?! FIXME true???
ok
(erlang@REDACTED)221> fdoc:describe(gen_server, call).
gen_server:call/2:
Make a call to a generic server.
If the server is located at another node, that node will
be monitored.
If the client is trapping exits and is linked server termination
is handled here (? Shall we do that here (or rely on timeouts) ?).
gen_server:call/3:
(undocumented)
ok
(erlang@REDACTED)222> fdoc:describe(regexp).
regexp:first_match/2:
-type first_match(String, RegExp) -> matchres().
Find the first match of RegExp in String.
regexp:format_error/1:
format_error(Error) -> String.
regexp:gsub/3:
-type gsub(String, RegExp, Replace) -> subres().
Substitute every match of the regular expression RegExp with the
string New in String. Accept pre-parsed regular expressions.
regexp:match/2:
-type match(String, RegExp) -> matchres().
Find the longest match of RegExp in String.
regexp:matches/2:
-type matches(String, RegExp) -> {match,[{Start,Length}]} | {error,E}.
Return the all the non-overlapping matches of RegExp in String.
regexp:parse/1:
parse(RegExp) -> {ok,RE} | {error,E}.
Parse the regexp described in the string RegExp.
regexp:sh_to_awk/1:
sh_to_awk(ShellRegExp)
Convert a sh style regexp into a full AWK one. The main difficulty is
getting character sets right as the conventions are different.
regexp:split/2:
-type split(String, RegExp) -> splitres().
Split a string into substrings where the RegExp describes the
field seperator. The RegExp " " is specially treated.
regexp:sub/3:
-type sub(String, RegExp, Replace) -> subsres().
Substitute the first match of the regular expression RegExp with
the string Replace in String. Accept pre-parsed regular
expressions.
ok
Cheers,
Luke
More information about the erlang-questions
mailing list