diff --git a/src/edown_layout.erl b/src/edown_layout.erl index f33ee16262032e9ca0deb36610bb1186b176dd61..55e289e4f079cb2ae541ad2d12db5d71b373556f 100644 --- a/src/edown_layout.erl +++ b/src/edown_layout.erl @@ -185,9 +185,7 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) -> Body = ([] % navigation("top") ++ [{h1, Title}] ++ doc_index(FullDesc, Functions, Types) - ++ [{p,[]}] ++ ShortDesc - ++ [{p,[]}] ++ copyright(Es) ++ deprecated(Es, "module") ++ version(Es) @@ -219,8 +217,7 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) -> %% io:fwrite("not edown_doclet (~p)~n", [Name]) %% end, %% xhtml(Title, stylesheet(Opts), Body). - Res = to_simple(markdown(Title, stylesheet(Opts), Body)), - Res. + to_simple(markdown(Title, stylesheet(Opts), Body)). %% This function is a workaround for a bug in xmerl_lib:expand_content/1 that %% causes it to lose track of the parents if #xmlElement{} records are @@ -1268,9 +1265,10 @@ ot_name([E]) -> get_first_sentence([#xmlElement{name = p, content = Es} | Tail]) -> %% Descend into initial paragraph. + Tail1 = drop_empty_lines(Tail), {First, Rest} = get_first_sentence_1(Es), {First, - [#xmlElement{name = p, content = Rest} || Rest =/= []] ++ Tail}; + [#xmlElement{name = p, content = Rest} || Rest =/= []] ++ Tail1}; get_first_sentence(Es) -> get_first_sentence_1(Es). @@ -1290,7 +1288,8 @@ get_first_sentence_1([E = #xmlText{value = Txt} | Es], Acc) -> if Rest == [] -> Es; true -> - [#xmlText{value=Rest} | Es] + [#xmlText{value=trim_leading_lines( + normalize_text(Rest))} | Es] end}; none -> get_first_sentence_1(Es, [E | Acc]) @@ -1298,8 +1297,10 @@ get_first_sentence_1([E = #xmlText{value = Txt} | Es], Acc) -> get_first_sentence_1([E | Es], Acc) -> % Skip non-text segments - don't descend further get_first_sentence_1(Es, [E | Acc]); +get_first_sentence_1([], []) -> + {[], []}; get_first_sentence_1([], Acc) -> - {lists:reverse(Acc), []}. + {{p, lists:reverse(Acc)}, []}. end_of_sentence(Cs, Last) -> end_of_sentence(Cs, Last, []). @@ -1323,3 +1324,17 @@ end_of_sentence_1(C, Cs, true, As) -> {value, lists:reverse([C | As]), Cs}; end_of_sentence_1(_, _, false, _) -> none. + +drop_empty_lines([#xmlText{value = Txt}=H|T]) -> + case trim_leading_lines(normalize_text(Txt)) of + [] -> + drop_empty_lines(T); + Rest -> + [H#xmlText{value = Rest}|T] + end. + +trim_leading_lines([H|T]) when H==$\n; H==$\t; H==$\s -> + trim_leading_lines(T); +trim_leading_lines(Str) -> + Str. + diff --git a/src/edown_xmerl.erl b/src/edown_xmerl.erl index c11e80847b5dfa6140c47d52c87900974396b5ed..aa01c23820b88f08b88fe3cf39d12f38863c592f 100644 --- a/src/edown_xmerl.erl +++ b/src/edown_xmerl.erl @@ -50,21 +50,23 @@ to_string(S) -> unicode:characters_to_list([S]). strip(Str) -> lstrip(rstrip(Str)). -lstrip(Str) -> re:replace(Str,"^\\s","", [unicode]). -rstrip(Str) -> re:replace(Str, "\\s\$", "", [unicode]). +lstrip(Str) -> re:replace(Str,"^\\s","", [unicode,{return, list}]). +rstrip(Str) -> re:replace(Str, "\\s\$", "", [unicode, {return, list}]). % Strip double spaces at end of line -- markdown reads as hard return. -brstrip(Str) -> re:replace(Str, "\\s+\\s\$", "", [global, multiline, unicode]). +brstrip(Str) -> re:replace(Str, "\\s+\\s\$", "", [global, multiline, unicode, + {return, list}]). %% The '#root#' tag is called when the entire structure has been %% exported. It does not appear in the structure itself. '#root#'(Data, Attrs, [], _E) -> + Data1 = replace_edown_p(Data), case find_attribute(header, Attrs) of {value, Hdr} -> - [lists:flatten(io_lib:fwrite("HEADER: ~p~n", [Hdr])), Data]; + [lists:flatten(io_lib:fwrite("HEADER: ~p~n", [Hdr])), Data1]; false -> - Data + Data1 end. %% Note that SGML does not have the <Tag/> empty-element form. @@ -195,7 +197,7 @@ md_elem(Tag, Data, Attrs, Parents, E) -> 'div' -> Data; ul -> Data; ol -> Data; - p -> ["\n", Data, "\n"]; + p -> ["<edown_p>", Data, "<edown_p>"]; % no need to use closing tag b -> ["__", no_nl(Data), "__"]; em -> ["_", no_nl(Data), "_"]; i -> ["_", no_nl(Data), "_"]; @@ -263,6 +265,23 @@ no_nl(S) -> string:strip([C || C <- to_string(S), C =/= $\n], both). +replace_edown_p(Data) -> + Data1 = binary_to_list(iolist_to_binary(Data)), + io:fwrite("Data1 = ~p~n", [Data1]), + replace_edown_p(Data1, []). + +replace_edown_p("<edown_p>" ++ Data, Acc) -> + case lstrip(Data) of + "<edown_p>" ++ _ = Data1 -> + replace_edown_p(Data1, Acc); + Data1 -> + replace_edown_p(Data1, "\n\n" ++ lstrip(Acc)) + end; +replace_edown_p([H|T], Acc) -> + replace_edown_p(T, [H|Acc]); +replace_edown_p([], Acc) -> + lists:reverse(Acc). + %% attr(#xmlAttribute{name = N, value = V}) -> %% "(" ++ atom_to_list(N) ++ "=" ++ [a_val(V)] ++ ")".