-module(erlman). %% Module which generates an HTML page in current directory which provides %% a convenient index over Erlang manpages. Also provides a shellscript to %% do something similar. Generates 4 files in the current directory: %% modules_search.html, modules.html, about_erlman.html and eman %% %% Typical use: %% %% erlman:go("/usr/local/doc/erlang"). %% %% Then point your browser at the file "modules.html". %% %% -or- %% %% run the shellscript (after making it executable), e.g. %% %% eman lis %% %% Limitations: %% %% - can't cope with two modules with the same name (then again, neither %% can Erlang, so it's no problem in practice) %% %% - picks up some documentation files we're not really interested in, %% e.g. the four zillion 'part.html' ones. %% %% Compatibility of version 1.3 (and, presumably, later ones) %% %% I use Firefox on linux. So that should always work. Beyond that: %% %% Reported working: %% IE 6, Win XP Pro (PB) %% IE 6, Win XP (VD) %% IE 6, Win 2k (ES, BB, AP) %% IE 6, Win 98 (FK) %% IE ?, OSX 1.5 (CW) %% IE 5.5, NT4.0 SP5,SP6 (TS, BM) %% %% Firefox 2.x %% Moz 1.1, Win 2k (BB) %% Netscape 4.79, NT %% Netscape 4.79, OpenBSD 3.1 (RP) %% Netscape 4.79, Solaris (UW) %% Netscape 4.79, Linux (MK) %% Netscape 4.61, Solaris (LV) %% Netscape 4.78, Win 95 (SM) %% Netscape 6.x, Win 98 (FC) %% Opera 6.03, linux (MK) %% Opera 6.01, win 95 (SM) %% Icab 2.8.2, Mac (BK) %% %% Reported buggy: %% %% Konqueror on linux (can only search one time, even the 'modules %% index button stops working) (MK) %% %% IE 4.72. Doesn't seem to be able to search the array at all. (BM) %% %% Wishlist %% %% - when there are multiple matches, some people would like a list instead %% of the shortest match. Could make this optional. %% %% Changelog: %% %% 23. Nov 2010 %% Updated for R14B %% %% 6. May 2004 %% Added function searching for the command line version. Code and %% idea courtesy of Mats Cronqvist %% %% 10. November 2003 %% Updated so that it works with the index file from the R9C docs %% %% 9. September 2002 %% Applied patch from Chandrashekhar to make it work with IE5/NT %% Changed the way we make the index. Now "parses" man_index.html %% instead of walking the directory tree. Better approach. %% Made the WWW version go to 'modules_index' when the longest match is 0 %% Added a 'what's this?' page %% %% 4. September 2002 %% Added go/2 which allows manual specification of a prefix. This %% allows creation of a version of the index which works on the WWW %% Search result now returns the shortest match first %% Made the search case insensitive for the shell version %% Fixed the javascript code to work around IE problems %% %% August 2002 Released to the mailing list %% -author('matthias@corelatus.se'). -export([go/0, go/1, go/2]). -include_lib("kernel/include/file.hrl"). %% This is where the HTML files happen to be on my machines. You probably %% want to use go/1 or go/2. go() -> go("/usr/local/src/otp_doc_R14B0"). %% Dir: the directory where you unpacked the otp_html_Rxxx.tar.gz file. go(Dir) -> go(Dir, "file://" ++ Dir). %% Prefix: string to dump in front of all man page URLs %% %% If you want to generate a version which points at erlang.org, %% use the atom 'web' as the prefix. It's a magic value which %% chops the URLs into the same format erlang.org uses. %% %% erlman:go("/usr/local/src/otp_doc_html_R12B-1", web). %% go(Dir, Prefix) -> Search = list_to_binary(javascript(Dir, Prefix)), ok = file:write_file(target_filename(), Search), Frames = list_to_binary(frames(Prefix)), ok = file:write_file(frame_filename(), Frames), ok = file:write_file(about_filename(), list_to_binary(about())), Shellscript = list_to_binary(shellscript(Dir)), ok = file:write_file(shellscript_filename(), Shellscript). %% where to write the resulting HTML page target_filename() -> "modules_search.html". frame_filename() -> "modules.html". about_filename() -> "about_erlman.html". shellscript_filename() -> "eman". %% The name of your browser, if you're using the 'eman' shell script browser_executable() -> "iceweasel". %% How big should the frame with the search box in it be. 35 is enough %% for mozilla. Seem to need 50 for some Netscape versions. Erk. There %% must be a better way to do this. upper_frame_size() -> "50". %% Javascript which does the searching. Currently implemented as a linear %% search, could be changed to binary search if speed is a problem %% (it isn't on my machine). %% %% Dir is the top of the java pages on the local hard disk %% %% Prefix is prepended to the URLs the script generates, so if you %% use the prefix "http://www.erlang.org/Doc/" you could generate %% an index for the online stuff. %% javascript(Dir, web) -> Format_fun = fun(Module, Canonical) -> Pathlist = string:tokens(Canonical, "/"), Suffix = hd(lists:reverse(Pathlist)), ["\"", Module, " /doc/man/", Suffix, "\","] end, javascript(Dir, "http://www.erlang.org/", Format_fun); javascript(Dir, Prefix) -> Format_fun = fun(Module, Canonical) -> ["\"", Module, " ", Canonical, "\","] end, javascript(Dir, Prefix, Format_fun). javascript(Dir, Prefix, Format_fun) -> %% First two clauses are to special case modules which are both %% in erts and elsewhere. The Erts version is the interesting one. Sort_fun = fun([_,A,_,"/erts" ++ _|_], [_,A|_]) -> true; ([_,A|_], [_,A,_,"/erts" ++ _|_]) -> false; ([_, A|_], [_, B|_]) when length(A) < length(B) -> true; ([_, A|_], [_, B|_]) when length(A) > length(B) -> false; ([_, A|_], [_, B|_]) -> A < B end, [" Erlang Manpage Quick Index
What is this?
"]. %% An explanation of what this is and how it works about() -> " Erlman

Erlman

This is an automatically generated search page for the Erlang man pages.

Idea: you type in the start of the name of the page you want. Your browser shows the page which matches the longest prefix of your search term.

If there are several equally long matches, it displays the page with the shortest filename.

If there are no matches, it displays the manual page index.

Examples

You typeBrowser shows Explanation
mnemnesia
mnesia_smnesia_session
lislists
zmodule_index No page starts with z, so we show the index

How it works

The WWW version is javascript. Your browser goes through an array of pages searching for the best match. The array of pages is pre-generated.

You can download the erlang code which generates the index and use it to generate an index of the erlang documentation on your local hard disk. The documentation itself can be downloaded from www.erlang.org.

There is also a command line version which ONLY works for mozilla on linux. You can type 'eman lis dro' on your shell's command line and mozilla will display the page you wanted.

Problems

Please don't bug the OTP guys about problems with this search hack. Send some mail to me (matthias@corelatus.com) or the mailing list. ". %% The Frame containing the search field and the page we'll look at frames(web) -> frames("http://www.erlang.org/"); frames(Dir) -> [" Module Index With Search "]. shellscript(Dir) -> FF = fun(Module, Canonical) -> [Module, " ", Canonical, "\n"] end, %% The first two clauses are to special-case modules which have moved %% to 'erts'. I want them sorted first. Sort_fun = fun([A,_,"/erts" ++ _|_], [A|_]) -> true; ([A|_], [A,_,"/erts" ++ _|_]) -> false; ([A|_], [B|_]) when length(A) < length(B) -> true; ([A|_], [B|_]) when length(A) > length(B) -> false; ([A|_], [B|_]) -> A < B end, ["#!/bin/sh # Shell script generated by erlman.erl. # # Use: eman [] # # Displays Erlang man pages in your browser search=^$1 doc_base=file://", Dir, " file=`grep -i \"^$1.*[ ]\" $0 | head -n 1| cut -f 2 -d ' '` if [ -z $file ]; then echo \"nothing relevant found, showing index\" page=\"$doc_base/doc/man_index.html\" else page=\"$doc_base$file\" if [ $# -gt 1 ]; then anchor=`grep \"A NAME=.$2\" ", Dir, "$file | cut -f2 -d'\"'| head -n1` if [ ! -z \"$anchor\" ]; then page=$page#$anchor else echo \"no function matched\" fi fi fi echo \"showing $page\" ", browser_executable(), " -new-tab \"$page\" exit echo \"we never reach this line\"", "\n", FF("modules", "/doc/man_index.html"), manpage_array(Dir, FF, Sort_fun)]. %% Returns a list of strings of form %% %% "modulename /path/modulename.html" %% %% The path is relative to the erlang documentation root. It must start with %% a slash. %% %% The Fun is a fun(Module, Canonical) -> String %% %% The list is sorted in order of shortest module name. (Sean's idea) manpage_array(Dir, Format, Sort) when is_function(Sort), is_function(Format) -> {ok, F} = file:open(Dir ++ "/doc/man_index.html", [read]), lists:sort(Sort, manpage_array(F, Format)). manpage_array(F, Format) -> case io:get_line(F, "") of eof -> []; "\n" -> %% R8 documentation looks like this emit_manpage_line(F, Format); " \n" -> %% R9 documentation has indenting emit_manpage_line(F, Format); _X -> manpage_array(F, Format) end. emit_manpage_line(F, Format) -> Line = string:strip(io:get_line(F, "")), case string:tokens(Line, "<>") of ["TD", Href, Module|_] -> [_, Clean_ref] = string:tokens(Href, "\""), Chopped_ref = string:substr(Clean_ref, 3), [Format(Module, Chopped_ref)|manpage_array(F, Format)]; _ -> io:fwrite("Skipping useless line: ~s\n", [Line]), manpage_array(F, Format) end.