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 + -
显示快捷键?