docb_main.erl

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

ERL
618
字号
    false.verify_list([H|T], Path, Level) ->    case verify(H, Path, Level) of	true ->	    verify_list(T, Path, Level +1);	false ->	    false    end;verify_list([], _, _) ->    true.verify_optional([{_, _, _}|T], Path, Level) ->    verify_optional(T, Path, Level);verify_optional([], _Path, _Level) ->    true;verify_optional(X, Path, Level) ->    verify_error(X, Path, Level).%%----------------------------------------------------------------------%% pp(File, Opts) -> {ok, OutFile} | errors%% Parses the source file and, if successful, prints the resulting tree%% structure to a file with the extension ".pp".pp(File, Opts) ->    case parse(File, Opts) of	{ok, Tree} ->	    OutFile = File ++ ".pp",	    dump(OutFile, Tree),	    {ok, OutFile};	errors ->	    errors    end.dump(File, Struct) ->    {ok, Stream} = file:open(File, write),    io:format("Info: Dump on ~p ...", [File]),    io:format(Stream, "~n~s~n", [docb_pretty_format:term(Struct)]),    io:format(" done.\n"),    file:close(Stream).%%----------------------------------------------------------------------%% insert_after(Tag, Tree, Obj) -> Tree | {'EXIT', Reason}%% Insert an element in a tree structureinsert_after(Tag, Tree, Obj) ->    edit(Tag, Tree, {insert_after, Obj}).%% edit Op = delete, insert_before, insert_afteredit(Tag, Tree, Op) ->    case catch edit1(Tag, Tree, Op) of	error ->	    docb_util:message(error, "Cannot do ~p to ~w", [Op, Tag]),	    Tree;	Other ->	    Other    end.edit1(Tag, {Tag, _O, _A}, _Op) ->    throw(error);edit1(Tag, {Tag1, O, A}, Op) ->    {Tag1, O, edit1_list(Tag, A, Op)};edit1(_, _, _) ->    throw(error).edit1_list(Tag, [{pcdata, Str}|T], Op) ->    [{pcdata, Str}|edit1_list(Tag, T, Op)];edit1_list(Tag, [{Tag, O, A}|T], {insert_after, Obj}) ->    [{Tag, O, A}, Obj|T];edit1_list(Tag, [H|T], Op) ->    [H|edit1_list(Tag, T, Op)];edit1_list(_Tag, [], _Op) ->    [].%%______________________________________________________________________%% transform(From, To, Opts, File, Tree) -> void()%% Actual transformation of tree structure to desired format.transform(From, To, Opts, File, Tree) ->    Filter = if		 To==html; To==kwic ->		     list_to_atom("docb_tr_" ++ atom_to_list(From) ++				  [$2|atom_to_list(To)]);		 true ->		     list_to_atom("sgml_tr_" ++ atom_to_list(From) ++				  [$2|atom_to_list(To)])	     end,    case catch apply(Filter, transform, [File, Tree, Opts]) of	%% R5C	{'EXIT', {undef, [{Filter, transform, [File, Tree, Opts]}|_]}}->	    %% No transformation defined	    finish_transform(Tree, File, Opts, Filter);		{'EXIT', {undef, {Filter, transform, [File, Tree, Opts]}}} ->	    %% No transformation defined	    finish_transform(Tree, File, Opts, Filter);	{'EXIT', What} ->	    docb_util:message(error,			      "Transformation trouble in ~P", [What,9]),	    transformation_error;	{error, Reason} ->	    docb_util:message(error, Reason),	    transformation_error;		{Tree1, Opts1} ->	    %% transformation returning both new parse and new options	    finish_transform(Tree1, File, Opts1, Filter);		Tree1 ->	    %% transformation returning only new parse	    finish_transform(Tree1, File, Opts, Filter)    end.finish_transform(Tree, File, Opts, Filter) ->    {Str, NewOpts} = pp(Tree, [], 1, Filter, Opts),    Extension =	case catch apply(Filter, extension, [NewOpts]) of	    {'EXIT', _} ->		apply(Filter, extension, []);	    Others ->		Others	end,    {ok, Out} =	file:open(docb_util:outfile(File, Extension, NewOpts), write),    put_chars(Out, Str),    file:close(Out).put_chars(Out, Str) -> put_chars(Out, Str, 0).put_chars(Out, [$\n|Cs], _Pos) ->    io:put_chars(Out, [$\n]),    put_chars(Out, Cs, 0);put_chars(Out, [$\011|Cs], Pos) -> % tab    TabbedPos = 8*((Pos div 8)+1),    Nblanks = TabbedPos - Pos,    io:put_chars(Out, lists:duplicate(Nblanks, $ )),    put_chars(Out, Cs, Pos+Nblanks);put_chars(Out, [C|Cs], Pos) when is_integer(C) ->    io:put_chars(Out, [C]),    put_chars(Out, Cs, Pos+1);put_chars(Out, [L|Cs], Pos) when is_list(L) ->    put_chars(Out, Cs, put_chars(Out, L, Pos));put_chars(_Out, [], Pos) ->    Pos.pp({Tag, Optional, Args}, TagPath, Level, Filter, Opts) ->    TagPath1  = [Tag|TagPath],    Optional1 = reduce_optional(Optional),    %% First try Filter:rule/3. It returns {Return, NewOpts}    %%                          where Return is as from rule/2:    Rule_3_result =	case catch Filter:rule(TagPath1, {Level,Optional1,Args},Opts) of	    %% R5C	    {'EXIT', {undef, [{_, rule, _}|_]}} -> % No rule/3 defined		failed;	    {'EXIT', {undef, {_, rule, _}}} -> % No rule/3 defined		failed;	    %% R5C	    {'EXIT', {function_clause, [{_, rule, _}|_]}} -> % No MATCHING rule/3		failed;	    {'EXIT', {function_clause, {_, rule, _}}} -> % No MATCHING rule/3		failed;	    {'EXIT', What} ->		docb_util:message(error,				  "Serious Error: ~P", [What, 9]);	    Others ->		Others	end,    handle_rule_call_result({r3, Rule_3_result}, Filter, TagPath1, Tag,			    Level, Optional1, Args, Opts).handle_rule_call_result({r3, failed}, Filter, TagPath1, Tag, Level, Optional1,			Args, Opts) ->    %% Hmmm, try Filter:rule/2    Rule_2_result = (catch Filter:rule(TagPath1, {Level, Optional1, Args})),    handle_rule_call_result({r2, Rule_2_result}, Filter, TagPath1, Tag,			    Level, Optional1, Args, Opts);handle_rule_call_result({r3, {Result, NewOpts}}, Filter, TagPath1, Tag, Level,			Optional1, Args, _Opts) ->    handle_rule_call_result({r2, Result}, Filter, TagPath1, Tag, Level,			    Optional1, Args, NewOpts);handle_rule_call_result({_, {func, F}}, _Filter, _TagPath1, _Tag, _Level,			_Optional1, Args, Opts) ->    {F(Args), Opts};handle_rule_call_result({_, {'EXIT', Why}}, _Filter, TagPath1, _Tag, Level,			Optional1, Args, Opts) ->    report_error(TagPath1, Why, {Level, Optional1, Args}),    {[], Opts};handle_rule_call_result({_, {drop, Str}}, _Filter, _TagPath1, _Tag, _Level,			_Optional1, _Args, Opts) ->    {[Str], Opts};handle_rule_call_result({_, {newargs, NewArgs}}, Filter, TagPath1, _Tag, _Level,			_Optional1, _Args, Opts) ->    {List, NewOpts} = pp_list(NewArgs, TagPath1, 1, Filter, Opts),    {[List], NewOpts};handle_rule_call_result({_, {newargs, Before, NewArgs, After}}, Filter, TagPath1, _Tag, _Level,			_Optional1, _Args, Opts) ->    {List, NewOpts} = pp_list(NewArgs, TagPath1, 1, Filter, Opts),    {[Before, List, After], NewOpts};handle_rule_call_result({_, {Before, After}}, Filter, TagPath1, _Tag, _Level,			_Optional1, Args, Opts) when is_list(Before) ->    {List, NewOpts} = pp_list(Args, TagPath1, 1, Filter, Opts),    {[Before, List, After], NewOpts}.pp_list([H|T], TagPath, Level, Rules, Opts) ->    {Hpp, Hopts} = pp(H, TagPath, Level, Rules, Opts),    {Tpp, Tops} = pp_list(T, TagPath, Level + 1, Rules, Hopts),    {[Hpp|Tpp], Tops};pp_list([], _, _, _, Opts) ->    {[], Opts}.reduce_optional([{_, _, H}|T]) -> [H|reduce_optional(T)];reduce_optional([])          -> [].report_error(Arg1, Cause, Arg2) ->    [Tag|_] = Arg1,    docb_util:message(error,		      "Formatting trouble in ~p: ~p", [Tag, Cause]),    docb_util:message(error, "Failure in rule(~p, ~p)", [Arg1, Arg2]).%%----------------------------------------------------------------------%% include_file(File, Tag) -> {ok, String} | errorinclude_file(File, Tag) ->    include(File, "%S" ++ Tag, "%E" ++ Tag).%% include(File, StartTag, StopTag) -> {ok, String} | errorinclude(File, "", "") ->    case file:open(File, read) of	{ok, Fd} ->	    {ok, include_all(Fd)};	_ ->	    docb_util:message(error,			      "Include file ~s not found", [File]),	    error    end;include(File, StartTag, StopTag) ->    case file:open(File, read) of	{ok, Fd} ->	    String = extract(File, Fd, StartTag, StopTag, searching),	    file:close(Fd),	    {ok, lists:flatten(String)};	_ ->	    docb_util:message(error,			      "Include file ~s not found", [File]),	    error    end.include_all(Fd) ->    case io:get_line(Fd, '') of	eof ->	    [];	ListOfChars ->	    lists:append(ListOfChars, include_all(Fd))    end.extract(File, Fd, StartTag, StopTag, State) ->    Line=io:get_line(Fd, ''),    extract(File, Fd, StartTag, StopTag, State, Line).extract(File, _, _, _, _, eof) ->    docb_util:message(error,		      "Premature end of file in include file ~p",		      [File]),    [];extract(File, Fd, StartTag, StopTag, searching, Line) ->    case regexp:match(Line, "^" ++ StartTag) of	{match, _Start, _Length} ->	    extract(File, Fd, StartTag, StopTag, copying);	nomatch ->	    extract(File, Fd, StartTag, StopTag, searching);	{error, _Error} ->	    docb_util:message(error, "Bad syntax in ~s", [File]),	    []    end;extract(File, Fd, StartTag, StopTag, copying, Line) ->    case regexp:match(Line, "^" ++ StopTag) of	{match, _Start, _Length} ->	    [];	nomatch ->	    [Line|extract(File, Fd, StartTag, StopTag, copying)];	{error, _Error} ->	    docb_util:message(error, "Bad syntax in ~s", [File]),	    []    end.%%----------------------------------------------------------------------eval_str(Str) ->    case lib:eval_str(Str) of	{error, Report} ->	    docb_util:message(error,			      "ErlEval failed: ~s (~s)", [Str, Report]);	{ok, S} ->	    io_lib:format("~p~n", [S])    end.

⌨️ 快捷键说明

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