aboutsummaryrefslogtreecommitdiffstats
path: root/lib/docbuilder/src/docb_tr_index2html.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/docbuilder/src/docb_tr_index2html.erl')
-rw-r--r--lib/docbuilder/src/docb_tr_index2html.erl197
1 files changed, 197 insertions, 0 deletions
diff --git a/lib/docbuilder/src/docb_tr_index2html.erl b/lib/docbuilder/src/docb_tr_index2html.erl
new file mode 100644
index 0000000000..bbf419f3ef
--- /dev/null
+++ b/lib/docbuilder/src/docb_tr_index2html.erl
@@ -0,0 +1,197 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999-2000, Ericsson
+%% Utvecklings AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(docb_tr_index2html).
+
+-export([extension/0, transform/3, rule/2]).
+
+extension() ->
+ ".html".
+
+transform(_File0, {index, Attrs, [Header| Trees0]}, _Opts) ->
+ Trees1 = prune_flat(Trees0, false),
+ %%
+ %% Now each element of Trees1 is a tree with tag `name' and
+ %% attribute `File', and with one `pcdata' subtree containing the
+ %% name `Func' of the function. We extract `File' and `Func', and
+ %% create new trees.
+ %%
+ %% `File' is attribute CDATA (from an <include file=...>), and
+ %% `Func' is PCDATA.
+ %%
+ FileFuncs =
+ [{File, RefType, Func} ||
+ {name, [{_, _, File}, {_, _, RefType}|_],
+ [{pcdata, [], Func}]}
+ <- Trees1],
+ Trees2 = new_trees(FileFuncs),
+ {index, Attrs, [Header| Trees2]}.
+
+%% Remove all elements except those with tag equal to `name'.
+%% Within `name' remove all elements except those equal to `pcdata'.
+%% Add attribute `filetype' to `name'.
+%%
+%% Refs: appref, comref, cref, erlref, fileref
+prune_flat([{appref, _Attrs, More}| Rest], _) ->
+ RefType = appref,
+ lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType));
+prune_flat([{comref, _Attrs, More}| Rest], _) ->
+ RefType = comref,
+ lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType));
+prune_flat([{cref, _Attrs, More}| Rest], _) ->
+ RefType = cref,
+ lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType));
+prune_flat([{erlref, _Attrs, More}| Rest], _) ->
+ RefType = erlref,
+ lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType));
+prune_flat([{fileref, _Attrs, More}| Rest], _) ->
+ RefType = fileref,
+ lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType));
+prune_flat([{name, [Attr0|Attrs0], More}| Rest], RefType) ->
+ Attrs = [Attr0, {"FILETYPE", "CDATA", RefType} |
+ Attrs0],
+ [{name, Attrs, keep_pcdata(More)}| prune_flat(Rest, RefType)];
+prune_flat([{pcdata, _, _}| Rest], RefType) -> % special case
+ prune_flat(Rest, RefType);
+prune_flat([{_Tag, _Attrs, More}| Rest], RefType) ->
+ lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType));
+prune_flat([], _) ->
+ [].
+
+keep_pcdata(Trees) ->
+ lists:filter(fun({pcdata, _, _}) -> true;
+ (_) -> false
+ end, Trees).
+
+new_trees(FileFuncs) ->
+ Files0 = [{File, RefType} || {File, RefType, _} <- FileFuncs],
+ Files1 = lists:usort(Files0),
+ FileEntries = [{reffile, File, RefType,
+ [Fu || {Fi, _, Fu} <- FileFuncs, Fi == File]}
+ || {File, RefType} <- Files1],
+ FuncEntries = [{func, Func, RefType, [File]}
+ || {File, RefType, Func} <- FileFuncs],
+ Entries = FileEntries ++ FuncEntries,
+ SortedEntries = sort_entries(Entries),
+ %%
+ %% We create a tree according to the following "dtd":
+ %%
+ %% element index (reffile | funcdef)*
+ %% element reffile (funcdef2)*
+ %% attribute reffile filename CDATA
+ %% attribute reffile filetype CDATA
+ %% element funcdef2 PCDATA
+ %% attribute funcdef2 filename CDATA
+ %% attribute funcdef2 filetype CDATA
+ %% element funcdef PCDATA
+ %% attribute funcdef filename CDATA
+ %% attribute funcdef filetype CDATA
+ %%
+ %% For example:
+ %% <index>
+ %% <reffile filename="mymod" filetype="erlref">
+ %% <funcdef2 filename="mymod" filetype="erlref">myfunca(A)</>
+ %% <funcdef2 filename="mymod" filetype="erlref">myfuncb(A, B)</>
+ %% </>
+ %% <funcdef filename="mymod" filetype="erlref">myfunca(A)</>
+ %% <funcdef filename="mymod" filetype="erlref">myfuncb(A, B)</>
+ %% </>
+ lists:flatmap(
+ fun({reffile, File, RefType, Funcs}) ->
+ %% A reffile tree
+ [{reffile, [{"FILENAME", "CDATA", File},
+ {"FILETYPE", "CDATA", RefType}],
+ [{funcdef2, [{"FILENAME", "CDATA", File},
+ {"FILETYPE", "CDATA", RefType}],
+ [{pcdata, [], Func}]} || Func <- Funcs]}];
+ ({func, Func, RefType, [File]}) ->
+ %% A func tree
+ [{funcdef, [{"FILENAME", "CDATA", File},
+ {"FILETYPE", "CDATA", RefType}],
+ [{pcdata, [], Func}]}]
+ end, SortedEntries).
+
+%% Sorting of entries
+%%
+%% The sorting is based on how names of files and functions are
+%% presented (in a browser).
+%% Requires conversion to "function/2" etc.
+%%
+sort_entries(Entries) ->
+ ExpEntries =
+ lists:map(
+ fun({reffile, File, RefType, Funcs}) ->
+ HFile = filename_sort_order(File),
+ HFuncs = [{funcdef_sort_order(Fu, RefType), Fu} || Fu <- Funcs],
+ {reffile, HFile, File, RefType, lists:sort(HFuncs)};
+ ({func, Func, RefType, [File]}) ->
+ HFunc = funcdef_sort_order(Func, RefType),
+ HFile = filename_sort_order(File),
+ {func, HFunc, Func, RefType, [{HFile, File}]}
+ end, Entries),
+ SortedExpEntries = lists:keysort(2, ExpEntries),
+ lists:map(
+ fun({Tag, _HName, Name, RefType, Vals}) ->
+ NVals = lists:map(fun({_HVal, Val}) -> Val end, Vals),
+ {Tag, Name, RefType, NVals}
+ end, SortedExpEntries).
+
+rule([index| _], _) ->
+ {docb_html_layout:index_top("") ++
+ "<dl>\n",
+ "</dl>\n" ++ docb_html_layout:index_bot()};
+
+rule([header| _], _) ->
+ {drop, ""};
+
+rule([reffile| _], {_, [File, _RefType|_], _}) ->
+ CFile = docb_html_util:attribute_cdata_to_html(File),
+ {"<dt><em>" ++ CFile ++ "</em></dt>\n", ""};
+
+rule([funcdef2| _], {_, [File, RefType|_], [{pcdata, [], FuncDef}]}) ->
+ FFuncDef = lists:flatten(docb_html_util:pcdata_to_html(FuncDef)),
+ TFuncDef = docb_util:trim(FFuncDef),
+ ShortFuncDef = docb_html_util:make_funcdef_short(TFuncDef, RefType),
+ HRef =
+ docb_html_util:make_anchor_href_short(File, TFuncDef, RefType),
+ {drop,
+ "<dd><a href=\"" ++ HRef ++ "\"><code>" ++
+ ShortFuncDef ++ "</code></a></dd>\n"};
+
+rule([funcdef| _], {_, [File, RefType|_], [{pcdata, [], FuncDef}]}) ->
+ FFuncDef = lists:flatten(docb_html_util:pcdata_to_html(FuncDef)),
+ TFuncDef = docb_util:trim(FFuncDef),
+ ShortFuncDef = docb_html_util:make_funcdef_short(TFuncDef, RefType),
+ HRef =
+ docb_html_util:make_anchor_href_short(File, TFuncDef, RefType),
+ CFile = docb_html_util:attribute_cdata_to_html(File),
+ {drop,
+ "<dt><code>" ++ ShortFuncDef ++ "</code></dt>\n"
+ "<dd><a href=\"" ++ HRef ++ "\"><em>" ++
+ CFile ++ "</em></a></dd>\n"};
+
+rule(_, _) ->
+ {drop, ""}.
+
+filename_sort_order(File) ->
+ docb_html_util:html_latin1_sort_order(
+ lists:flatten(
+ docb_html_util:attribute_cdata_to_html(string:strip(File)))).
+
+funcdef_sort_order(FuncDef, RefType) ->
+ docb_html_util:html_latin1_sort_order(
+ docb_html_util:make_anchor_name_short(FuncDef, RefType)).