docb_html_util.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 537 行 · 第 1/2 页

ERL
537
字号
%% ``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_html_util).-export([attribute_cdata_to_html/1,	 element_cdata_to_html/1,	 pcdata_to_html/1, pcdata_to_html/2]).-export([copy_pics/3]).-export([extract_header_data/2, all_header_data/1]).-export([make_uri/1,	 make_anchor_href/1, make_anchor_href_short/3,	 make_anchor_name_short/2,	 make_funcdef_short/2]).-export([erl_include/2, code_include/2, erl_eval/1]).-export([number/3, count_sections/1]).-export([format_toc/1]).-export([html_latin1_sort_order/1]).%%--Handle CDATA and PCDATA---------------------------------------------%% NB: Functions for transforming sgmls/XMerL data output to html.%%     Do not use these for included text files (cf code_include and%%     erl_include).attribute_cdata_to_html(Data) ->    data2html(Data, false).element_cdata_to_html(Data) ->    data2html(Data, false).pcdata_to_html(Data) ->    data2html(Data, true).pcdata_to_html(Data, RmSp) ->    data2html(Data, RmSp).%% PCDATA, CDATA: Replace entities, and optionally delete%% leading and multiple spaces. CDATA never contains entities to%% replace.%% data2html(Cs, RmSpace)data2html([$>| Cs], RmSp) ->    [$&, $#, $6, $2, $;| data2html(Cs, RmSp)];data2html([$<| Cs], RmSp) ->    [$&, $#, $6, $0, $;| data2html(Cs, RmSp)];data2html([$&| Cs], RmSp) ->    [$&, $#, $3, $8, $;| data2html(Cs, RmSp)];data2html([$\"| Cs], RmSp) ->    [$&, $#, $3, $4, $;| data2html(Cs, RmSp)];data2html([$\n| Cs], RmSp) ->    data2html(Cs, RmSp);data2html([$\\, $n| Cs], false) ->    [$\n| data2html(Cs, false)];data2html([$\\, $n| Cs], true) ->    [$\n| data2html(delete_leading_space(Cs), true)];data2html([$ , $ | Cs], true) ->		% delete multiple space    [$ | data2html(delete_leading_space(Cs), true)];data2html([$\\, $|| Cs0], RmSp) ->    {Ent, Cs1} = collect_entity(Cs0),    [entity_to_html(Ent)|  data2html(Cs1, RmSp)];data2html([$\\, $0, $1, $2| Cs], RmSp) ->    data2html(Cs, RmSp);data2html([$\\, $\\, $n| Cs], RmSp) ->    [$\\, $n| data2html(Cs, RmSp)];data2html([$\\, O1, O2, O3| Cs], RmSp)  when O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->    case octal2dec(O1, O2, O3) of	173 ->					% soft hyphen	    data2html(Cs, RmSp);	C when C > 31, C < 256 ->	    Ent = io_lib:format("&#~w;", [C]),	    [Ent|  data2html(Cs, RmSp)];	C ->	    [C| data2html(Cs, RmSp)]    end;data2html([$\\, $\\| Cs], RmSp) ->    [$\\| data2html(Cs, RmSp)];data2html([C| Cs], RmSp) ->    [C| data2html(Cs, RmSp)];data2html([], _) ->    [].delete_leading_space([$ | Cs]) ->    delete_leading_space(Cs);delete_leading_space(Cs) ->    Cs.collect_entity(Data) ->    collect_entity(Data, []).collect_entity([$\\, $|| Cs], Rs) ->    {lists:reverse(Rs), Cs};collect_entity([C| Cs], Rs) ->    collect_entity(Cs, [C| Rs]);collect_entity([], Rs) ->    {[], lists:reverse(Rs)}.entity_to_html("&") -> "&#38;";entity_to_html("\"") -> "&#34;";entity_to_html("<") -> "&#60;";entity_to_html(">") -> "&#62;";entity_to_html([$\\, O1, O2, O3])  when O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->    case octal2dec(O1, O2, O3) of	173 ->					% soft hyphen	    "";	Value ->	    io_lib:format("&#~w;", [Value])    end;entity_to_html(Other) ->    docb_html_util_iso:entity_to_html(Other).octal2dec(O1, O2, O3) ->    (O1*8+O2)*8+O3-73*$0.%%--Copy images---------------------------------------------------------copy_pics(Src, Dest, Opts) ->    Dir = code:lib_dir(docbuilder),    InFile = filename:join([Dir, "etc", Src]),    OutFile = docb_util:outfile(Dest, "", Opts),    case filelib:last_modified(OutFile) of	0 -> % File doesn't exist	    file:copy(InFile, OutFile);	OutMod2 ->	    InMod1s = calendar:datetime_to_gregorian_seconds(			filelib:last_modified(InFile)),	    OutMod2s = calendar:datetime_to_gregorian_seconds(OutMod2),	    if		InMod1s > OutMod2s -> % InFile is newer than OutFile		    file:copy(InFile, OutFile);		true ->		    ok	    end    end.%%--Resolve header data-------------------------------------------------extract_header_data(Key, {header, [], List}) ->    case lists:keysearch(Key, 1, List) of	{value, {Key, [], []}} ->	    "";	{value, {Key, [], [{pcdata, [], Value}]}} ->	    pcdata_to_html(Value);	false ->	    ""    end.all_header_data(Header) ->    all_header_data(Header,		    [title, prepared, responsible, docno, approved,		     checked, date, rev, file]).all_header_data(_Header, []) ->    [];all_header_data(Header, [Key| Rest]) ->    [extract_header_data(Key, Header) | all_header_data(Header, Rest)].%%--Resolve hypertext references----------------------------------------%% URI regular expression (RFC 2396):%%    "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"%% We split it in five parts:%% scheme:	"^(([^:/?#]+):)?"	(includes trailing `:')%% authority:	"^(//([^/?#]*))?"	(includes leading `//')%% path:	"^([^?#]*)"%% query:	"^(\\?([^#]*))?"	(includes leading `?')%% fragment:	"^(#(.*))?"		(includes leading `#')make_uri(Cs) ->    lists:flatmap(      fun({path, S}) ->	      case regexp:match(S, "\.xml?\$") of		  {match, _, _} ->		      {ok, NS, _} = regexp:sub(S, "\.xml?\$", ".html"),		      NS;		  _  ->		      S	      end;	 ({_, S}) ->	      S      end,      split_uri(Cs)).split_uri(URI) ->    split_uri(URI, [{scheme, "^(([^:/?#]+):)?"},		    {authority, "^(//([^/?#]*))?"},		    {path, "^([^?#]*)"},		    {'query', "^(\\?([^#]*))?"},		    {fragment, "^(#(.*))?"}]).split_uri("", [{Tag, _R}| T]) ->    [{Tag, ""}| split_uri("", T)];split_uri(Cs0, [{Tag, R}| T]) ->    {match, 1, N} = regexp:match(Cs0, R),    Cs1 = string:substr(Cs0, 1, N),    Cs2 = strip_and_escape_uri_component(Tag, Cs1),    [{Tag, Cs2}| split_uri(string:substr(Cs0, N+1), T)];split_uri(_, []) ->    [].strip_and_escape_uri_component(authority, "//" ++ Cs) ->    "//" ++ escape_uri(string:strip(Cs));strip_and_escape_uri_component(path, Cs) ->    escape_uri(string:strip(Cs));strip_and_escape_uri_component('query', "?" ++ Cs) ->    "?" ++ escape_uri(string:strip(Cs));strip_and_escape_uri_component(fragment, "#" ++ Cs) ->    "#" ++ escape_uri(string:strip(Cs));strip_and_escape_uri_component(_, "") ->    "";strip_and_escape_uri_component(_, Cs) ->    escape_uri(string:strip(Cs)).escape_uri([C|Cs]) when C =< 32;                        C == $<; C == $<; C == $#; C == $%; C == $";                        C == $?;			C == ${; C == $}; C ==$|; C == $\\; C == $^;			C == $[; C == $]; C ==$';			C >= 127 ->    [$%, mk_hex(C div 16), mk_hex(C rem 16)| escape_uri(Cs)];escape_uri([C|Cs]) ->    [C|escape_uri(Cs)];escape_uri([]) ->    [].mk_hex(C) when C<10 ->    C + $0;mk_hex(C) ->    C - 10 + $a.make_anchor_href(HRef) ->    case regexp:split(HRef, "#") of	{ok, [HRef]} ->	    %% No `#' in HRef, i.e. only path	    make_anchor_href(HRef, "");	 {ok, [Path, Fragment]}->	    make_anchor_href(Path, Fragment)    end.make_anchor_href(Path0, Frag0) ->    Frag1 = string:strip(Frag0),    Path1 = case Path0 of		"" ->		    "";		_  ->		    case regexp:match(Path0, "\.xml?\$") of			nomatch ->			    Path0 ++ ".html";			_ ->			    {ok, NewPath, _} = regexp:sub(Path0,							  "\.xml?\$",

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?