edoc_lib.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 222 行

ERL
222
字号
%% =====================================================================%% This library is free software; you can redistribute it and/or modify%% it under the terms of the GNU Lesser General Public License as%% published by the Free Software Foundation; either version 2 of the%% License, or (at your option) any later version.%%%% This library is distributed in the hope that it will be useful, but%% WITHOUT ANY WARRANTY; without even the implied warranty of%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU%% Lesser General Public License for more details.%%%% You should have received a copy of the GNU Lesser General Public%% License along with this library; if not, write to the Free Software%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307%% USA%%%% $Id$%%%% @private%% @copyright 2001-2003 Richard Carlsson%% @author Richard Carlsson <richardc@csd.uu.se>%% @see edoc%% @end%% =====================================================================%% @doc Utility functions for EDoc.-module(edoc_lib).-export([count/2, lines/1, split_at/2, split_at_stop/1,	 split_at_space/1, filename/1, transpose/1, segment/2,	 get_first_sentence/1, is_space/1, strip_space/1, parse_expr/2,	 parse_contact/2, escape_uri/1, join_uri/2, is_relative_uri/1,	 is_name/1, to_label/1, find_doc_dirs/0, find_sources/2,	 find_sources/3, find_file/3, try_subdir/2, unique/1,	 write_file/3, write_file/4, write_info_file/4,	 read_info_file/1, get_doc_env/1, get_doc_env/4, copy_file/2,	 uri_get/1, run_doclet/2, run_layout/2,	 simplify_path/1, timestr/1, datestr/1]).-import(edoc_report, [report/2, warning/2]).-include("edoc.hrl").-include("xmerl.hrl").-define(FILE_BASE, "/").%% ---------------------------------------------------------------------%% List and string utilitiestimestr({H,M,Sec}) ->    lists:flatten(io_lib:fwrite("~2.2.0w:~2.2.0w:~2.2.0w",[H,M,Sec])).datestr({Y,M,D}) ->    Ms = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",	  "Oct", "Nov", "Dec"],    lists:flatten(io_lib:fwrite("~s ~w ~w",[lists:nth(M, Ms),D,Y])).count(X, Xs) ->    count(X, Xs, 0).count(X, [X | Xs], N) ->    count(X, Xs, N + 1);count(X, [_ | Xs], N) ->    count(X, Xs, N);count(_X, [], N) ->    N.lines(Cs) ->    lines(Cs, [], []).lines([$\n | Cs], As, Ls) ->    lines(Cs, [], [lists:reverse(As) | Ls]);lines([C | Cs], As, Ls) ->    lines(Cs, [C | As], Ls);lines([], As, Ls) ->    lists:reverse([lists:reverse(As) | Ls]).split_at(Cs, K) ->    split_at(Cs, K, []).split_at([K | Cs], K, As) ->    {lists:reverse(As), Cs};split_at([C | Cs], K, As) ->    split_at(Cs, K, [C | As]);split_at([], _K, As) ->    {lists:reverse(As), []}.split_at_stop(Cs) ->    split_at_stop(Cs, []).split_at_stop([$., $\s | Cs], As) ->    {lists:reverse(As), Cs};split_at_stop([$., $\t | Cs], As) ->    {lists:reverse(As), Cs};split_at_stop([$., $\n | Cs], As) ->    {lists:reverse(As), Cs};split_at_stop([$.], As) ->    {lists:reverse(As), []};split_at_stop([C | Cs], As) ->    split_at_stop(Cs, [C | As]);split_at_stop([], As) ->    {lists:reverse(As), []}.split_at_space(Cs) ->    split_at_space(Cs, []).split_at_space([$\s | Cs], As) ->    {lists:reverse(As), Cs};split_at_space([$\t | Cs], As) ->    {lists:reverse(As), Cs};split_at_space([$\n | Cs], As) ->    {lists:reverse(As), Cs};split_at_space([C | Cs], As) ->    split_at_space(Cs, [C | As]);split_at_space([], As) ->    {lists:reverse(As), []}.is_space([$\s | Cs]) -> is_space(Cs);is_space([$\t | Cs]) -> is_space(Cs);is_space([$\n | Cs]) -> is_space(Cs);is_space([_C | _Cs]) -> false;is_space([]) -> true.strip_space([$\s | Cs]) -> strip_space(Cs);strip_space([$\t | Cs]) -> strip_space(Cs);strip_space([$\n | Cs]) -> strip_space(Cs);strip_space(Cs) -> Cs.segment(Es, N) ->    segment(Es, [], [], 0, N).segment([E | Es], As, Cs, N, M) when N < M ->    segment(Es, [E | As], Cs, N + 1, M);segment([_ | _] = Es, As, Cs, _N, M) ->    segment(Es, [], [lists:reverse(As) | Cs], 0, M);segment([], [], Cs, _N, _M) ->    lists:reverse(Cs);segment([], As, Cs, _N, _M) ->    lists:reverse([lists:reverse(As) | Cs]).transpose([]) -> [];transpose([[] | Xss]) -> transpose(Xss);transpose([[X | Xs] | Xss]) ->    [[X | [H || [H | _T] <- Xss]]     | transpose([Xs | [T || [_H | T] <- Xss]])].%% Note that the parser will not produce two adjacent text segments;%% thus, if a text segment ends with a period character, it marks the%% end of the summary sentence only if it is also the last segment in%% the list, or is followed by a 'p' or 'br' ("whitespace") element.get_first_sentence([#xmlElement{name = p, content = Es} | _]) ->    %% Descend into initial paragraph.    get_first_sentence_1(Es);get_first_sentence(Es) ->    get_first_sentence_1(Es).get_first_sentence_1([E = #xmlText{value = Txt} | Es]) ->    Last = case Es of	       [#xmlElement{name = p} | _] -> true;	       [#xmlElement{name = br} | _] -> true;	       [] -> true;	       _ -> false	   end,    case end_of_sentence(Txt, Last) of	{value, Txt1} ->	    [E#xmlText{value = Txt1}];	none ->	    [E | get_first_sentence_1(Es)]    end;get_first_sentence_1([E | Es]) ->    % Skip non-text segments - don't descend further    [E | get_first_sentence_1(Es)];get_first_sentence_1([]) ->    [].end_of_sentence(Cs, Last) ->    end_of_sentence(Cs, Last, []).%% We detect '.' and '!' as end-of-sentence markers.end_of_sentence([C=$., $\s | _], _, As) ->    end_of_sentence_1(C, true, As);end_of_sentence([C=$., $\t | _], _, As) ->    end_of_sentence_1(C, true, As);end_of_sentence([C=$., $\n | _], _, As) ->    end_of_sentence_1(C, true, As);end_of_sentence([C=$.], Last, As) ->    end_of_sentence_1(C, Last, As);end_of_sentence([C=$!, $\s | _], _, As) ->    end_of_sentence_1(C, true, As);end_of_sentence([C=$!, $\t | _], _, As) ->    end_of_sentence_1(C, true, As);end_of_sentence([C=$!, $\n | _], _, As) ->    end_of_sentence_1(C, true, As);end_of_sentence([C=$!], Last, As) ->    end_of_sentence_1(C, Last, As);end_of_sentence([C | Cs], Last, As) ->    end_of_sentence(Cs, Last, [C | As]);end_of_sentence([], Last, As) ->    end_of_sentence_1($., Last, strip_space(As)).  % add a '.'end_of_sentence_1(C, true, As) ->    {value, lists:reverse([C | As])};end_of_sentence_1(_, false, _) ->    none.%% For handling ISO 8859-1 (Latin-1) we use the following information:%%%% 000 - 037	NUL - US	control%% 040 - 057	SPC - /		punctuation%% 060 - 071	0 - 9		digit%% 072 - 100	: - @		punctuation%% 101 - 132	A - Z		uppercase%% 133 - 140	[ - `		punctuation%% 141 - 172	a - z		lowercase%% 173 - 176	{ - ~		punctuation%% 177		DEL		control%% 200 - 237			control%% 240 - 277	NBSP - 

⌨️ 快捷键说明

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