%% ``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 Licence for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ericsson AB. %% Portions created by Ericsson are Copyright 1999-2006, Ericsson AB. %% All Rights Reserved.´´ %% %% $Id$ %% -module(docb_edoc_xml_cb). %% This is the EDoc callback module for creating DocBuilder erlref %% documents (man pages) in XML format, and also a DocBuilder chapter %% document based on "overview.edoc". %% %% Usage examples: %% docb_gen File %% docb_gen -chapter overview.edoc %% or (from an Erlang shell) %% edoc:file(File, [{layout,docb_edoc_xml_cb},{file_suffix,".xml"}, %% {preprocess,true}]). %% %% The origin of this file is the edoc module otpsgml_layout.erl %% written by Richard Carlsson. -export([module/2, overview/2]). -include("xmerl.hrl"). -define(NL, "\n"). %%-User interface------------------------------------------------------- %% ERLREF module(Element, Opts) -> SortP = proplists:get_value(sort_functions, Opts, true), XML = layout_module(Element, SortP), xmerl:export_simple([XML], docb_xmerl_xml_cb, []). %% CHAPTER overview(Element, _Opts) -> XML = layout_chapter(Element), xmerl:export_simple([XML], docb_xmerl_xml_cb, []). %%--Internal functions-------------------------------------------------- layout_module(#xmlElement{name = module, content = Es}=E, SortP) -> Name = get_attrval(name, E), Desc = get_content(description, Es), ShortDesc = text_only(get_content(briefDescription, Desc)), FullDesc = otp_xmlify(get_content(fullDescription, Desc)), Types0 = get_content(typedecls, Es), Types1 = lists:sort([{type_name(Et), Et} || Et <- Types0]), Functions = case SortP of true -> lists:sort([{function_name(Ef), Ef} || Ef <- get_content(functions, Es)]); false -> [{function_name(Ef), Ef} || Ef <- get_content(functions, Es)] end, Header = {header, [ ?NL,{title, [Name]}, ?NL,{prepared, [""]}, ?NL,{responsible, [""]}, ?NL,{docno, ["1"]}, ?NL,{approved, [""]}, ?NL,{checked, [""]}, ?NL,{date, [""]}, ?NL,{rev, ["A"]}, ?NL,{file, [Name++".xml"]} ]}, Module = {module, [Name]}, ModuleSummary = {modulesummary, ShortDesc}, Description = {description, [?NL|FullDesc]}, Types = case Types1 of [] -> []; _ -> [?NL, {section,[{title,["DATA TYPES"]}, {marker,[{id,"types"}],[]}, ?NL|types(Types1)]}] end, Funcs = functions(Functions), See = seealso_module(Es), Authors = {authors, authors(Es)}, {erlref, [?NL,Header, ?NL,Module, ?NL,ModuleSummary, ?NL,Description] ++ Types ++ [?NL,Funcs, ?NL,See, ?NL,Authors] }. layout_chapter(#xmlElement{name=overview, content=Es}) -> Title = get_text(title, Es), Header = {header, [ ?NL,{title,[Title]}, ?NL,{prepared,[""]}, ?NL,{docno,[""]}, ?NL,{date,[""]}, ?NL,{rev,[""]}, ?NL,{file, ["chapter.xml"]} ]}, DescEs = get_content(description, Es), FullDescEs = get_content(fullDescription, DescEs), Sections = chapter_ify(FullDescEs, first), {chapter, [?NL, Header, ?NL | Sections]}. chapter_ify([], _) -> []; chapter_ify(Es, first) -> %% Everything up to the first section should be made into %% plain paragraphs -- or if no first section is found, everything %% should be made into one case find_next(h3, Es) of {Es, []} -> SubSections = subchapter_ify(Es, first), [{section, [?NL,{title,["Overview"]}, ?NL | SubSections]}]; {FirstEs, RestEs} -> otp_xmlify(FirstEs) ++ chapter_ify(RestEs, next) end; chapter_ify([#xmlElement{name=h3} = E | Es], next) -> {SectionEs, RestEs} = find_next(h3, Es), SubSections = subchapter_ify(SectionEs, first), {Marker, Title} = chapter_title(E), [{section, [?NL,{marker,[{id,Marker}],[]}, ?NL,{title,[Title]}, ?NL | SubSections]} | chapter_ify(RestEs, next)]. subchapter_ify([], _) -> []; subchapter_ify(Es, first) -> %% Everything up to the (possible) first subsection should be %% made into plain paragraphs {FirstEs, RestEs} = find_next(h4, Es), otp_xmlify(FirstEs) ++ subchapter_ify(RestEs, next); subchapter_ify([#xmlElement{name=h4} = E | Es], next) -> {SectionEs, RestEs} = find_next(h4, Es), Elements = otp_xmlify(SectionEs), {Marker, Title} = chapter_title(E), [{section, [?NL,{marker,[{id,Marker}],[]}, ?NL,{title,[Title]}, ?NL | Elements]} | subchapter_ify(RestEs, next)]. chapter_title(#xmlElement{content=Es}) -> % name = h3 | h4 case Es of [#xmlElement{name=a} = E] -> {get_attrval(name, E), get_text(E)} end. %%--XHTML->XML transformation------------------------------------------- %% otp_xmlify(Es1) -> Es2 %% Es1 = Es2 = [#xmlElement{} | #xmlText{}] %% Fix things that are allowed in XHTML but not in chapter/erlref DTDs. %% 1) lists (