diff options
Diffstat (limited to 'lib/docbuilder/src/docb_tr_index2html.erl')
-rw-r--r-- | lib/docbuilder/src/docb_tr_index2html.erl | 197 |
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)). |