aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-06-11 22:26:00 +0200
committerLoïc Hoguin <[email protected]>2018-06-11 22:26:00 +0200
commit112f38e3c7ba6cb5f8aa2ed4c7601ba098e68627 (patch)
tree1fb99f6b7a0401b2c29ec367692a8b85b9493d77
parentcbe1b68796f8621821a1902488d1286c420a6b49 (diff)
downloadasciideck-112f38e3c7ba6cb5f8aa2ed4c7601ba098e68627.tar.gz
asciideck-112f38e3c7ba6cb5f8aa2ed4c7601ba098e68627.tar.bz2
asciideck-112f38e3c7ba6cb5f8aa2ed4c7601ba098e68627.zip
Many fixes based on reading the HTML renders of Cowboy docs
-rw-r--r--src/asciideck_block_parser.erl13
-rw-r--r--src/asciideck_inline_pass.erl17
-rw-r--r--src/asciideck_to_html.erl58
3 files changed, 71 insertions, 17 deletions
diff --git a/src/asciideck_block_parser.erl b/src/asciideck_block_parser.erl
index e0faceb..09d3f1a 100644
--- a/src/asciideck_block_parser.erl
+++ b/src/asciideck_block_parser.erl
@@ -1018,12 +1018,13 @@ para(St) ->
fold_para(eof) ->
done;
-fold_para(Line0) ->
- case trim(Line0) of
+fold_para(Line) ->
+ case trim(Line) of
<<>> -> done;
<<"+">> -> done;
+ <<"//", _/bits>> -> done;
%% @todo Detect delimited block or list.
- Line -> {more, Line}
+ _ -> {more, Line}
end.
-ifdef(TEST).
@@ -1042,6 +1043,12 @@ para_test() ->
[{paragraph, _, LoremIpsum, _}] = parse(<< LoremIpsum/binary, "\n">>),
%% Paragraph followed by end of file with no trailing line break..
[{paragraph, _, LoremIpsum, _}] = parse(LoremIpsum),
+ %% Paragraph followed by list continuation.
+ [{paragraph, _, LoremIpsum, _}, {list_item_continuation, _, _, _}]
+ = parse(<<LoremIpsum/binary, "\n+">>),
+ %% Paragraph followed by comment.
+ [{paragraph, _, LoremIpsum, _}, {comment_line, _, <<"@todo Double check.">>, _}]
+ = parse(<<LoremIpsum/binary, "\n// @todo Double check.">>),
%% Two paragraphs.
[{paragraph, _, LoremIpsum, _}, {paragraph, _, LoremIpsum, _}]
= parse(<<
diff --git a/src/asciideck_inline_pass.erl b/src/asciideck_inline_pass.erl
index 3ed79b1..469c9f3 100644
--- a/src/asciideck_inline_pass.erl
+++ b/src/asciideck_inline_pass.erl
@@ -170,7 +170,10 @@ direct_link(Data, Prefix) ->
{Target0, Rest0} = while(fun(C) ->
(C =/= $[) andalso (C =/= $\s) andalso (C =/= $\t)
andalso (C =/= $\r) andalso (C =/= $\n)
+ andalso (C =/= $,)
end, Data),
+ %% The link must be more than just the prefix.
+ false = Target0 =:= <<>>,
Target = <<Prefix/binary, Target0/binary>>,
%% It is optionally followed by a caption. Otherwise
%% the link itself is the caption.
@@ -191,6 +194,13 @@ direct_link(Data, Prefix) ->
-ifdef(TEST).
http_link_test() ->
+ <<"Incomplete http: link">> = inline(<<"Incomplete http: link">>),
+ [
+ {link, #{
+ target := <<"http://example.org:8080">>
+ }, <<"http://example.org:8080">>, _},
+ <<", continued">>
+ ] = inline(<<"http://example.org:8080, continued">>),
[
<<"If you have ">>,
{link, #{
@@ -221,6 +231,13 @@ https_link(<<"https:", Rest/bits>>, Prev) when ?IS_BOUNDARY(Prev) ->
-ifdef(TEST).
https_link_test() ->
+ <<"Incomplete https: link">> = inline(<<"Incomplete https: link">>),
+ [
+ {link, #{
+ target := <<"https://example.org:8080">>
+ }, <<"https://example.org:8080">>, _},
+ <<", continued">>
+ ] = inline(<<"https://example.org:8080, continued">>),
[
<<"If you have ">>,
{link, #{
diff --git a/src/asciideck_to_html.erl b/src/asciideck_to_html.erl
index b904f3a..6f8a393 100644
--- a/src/asciideck_to_html.erl
+++ b/src/asciideck_to_html.erl
@@ -71,21 +71,42 @@ ast_node(Node={Type, _, _, _}) ->
listing_block -> listing_block(Node);
list -> list(Node);
table -> table(Node);
+ block_macro -> block_macro(Node);
comment_line -> comment_line(Node);
- _ ->
- io:format("Ignored AST node ~p~n", [Node]),
- []
+ _ -> ast_error({unknown_type, Node})
end
- catch _:_ ->
- io:format("Ignored AST node ~p~n", [Node]),
- []
+ catch C:E ->
+ ast_error({crash, C, E, erlang:get_stacktrace(), Node})
end.
+ast_error(Error) ->
+ [
+ "<p class=\"asciideck-error\">",
+ html_encode(unicode:characters_to_binary(io_lib:format("~p", [Error]))),
+ "</p>"
+ ].
+
%% Section titles.
-section_title({section_title, #{level := Level}, Title, _}) ->
+section_title({section_title, Attrs=#{level := Level}, Title, _}) ->
LevelC = $1 + Level,
- ["<h", LevelC, ">", inline(Title), "</h", LevelC, ">\n"].
+ ID = case Attrs of
+ #{<<"id">> := ID0} -> ID0;
+ _ -> id_from_title(Title)
+ end,
+ ["<h", LevelC, " id=\"", ID, "\">", inline(Title), "</h", LevelC, ">\n"].
+
+%% Asciidoc User Guide 8.4.2
+%% @todo Handle cases where the title is repeated in the same document.
+id_from_title(Title) ->
+ ID0 = unicode:characters_to_binary(string:to_lower(unicode:characters_to_list(Title))),
+ ID1 = <<if
+ C >= $a, C =< $z -> <<C/utf8>>;
+ C >= $0, C =< $9 -> <<C/utf8>>;
+ true -> <<$_>>
+ end || <<C/utf8>> <= ID0>>,
+ ID = string:strip(unicode:characters_to_list(ID1), both, $_),
+ [$_, unicode:characters_to_binary(ID)].
%% Paragraphs.
@@ -129,11 +150,10 @@ bulleted_list_item({list_item, _, [{paragraph, _, Text, _}|AST], _}) ->
"</li>\n"
].
-labeled_list_item({list_item, #{label := Label}, [{paragraph, _, Text, _}|AST], _}) ->
+labeled_list_item({list_item, #{label := Label}, AST, _}) ->
[
"<dt>", inline(Label), "</dt>\n",
"<dd>",
- inline(Text), "\n",
ast(AST),
"</dd>\n"
].
@@ -160,6 +180,13 @@ table_body_cells(Cells) ->
[["<td>", inline(Text), "</td>\n"]
|| {cell, _, Text, _} <- Cells].
+%% Block macros.
+
+block_macro({block_macro, #{name := <<"image">>,
+ target := Target, 1 := Caption}, _, _}) ->
+ ["<img src=\"", html_encode(Target), "\" "
+ "alt=\"", html_encode(Caption), "\"/>"].
+
%% Comment lines are printed in the generated file
%% but are not visible in viewers.
@@ -170,9 +197,10 @@ comment_line({comment_line, _, Text, _}) ->
inline(Text) when is_binary(Text) ->
html_encode(Text);
-inline({Link, #{target := Target}, Text, _})
- when Link =:= link; Link =:= xref ->
+inline({link, #{target := Target}, Text, _}) ->
["<a href=\"", html_encode(Target), "\">", html_encode(Text), "</a>"];
+inline({xref, #{id := ID}, Text, _}) ->
+ ["<a href=\"#", html_encode(ID), "\">", html_encode(Text), "</a>"];
inline({emphasized, _, Text, _}) ->
["<em>", inline(Text), "</em>"];
inline({strong, _, Text, _}) ->
@@ -187,5 +215,7 @@ html_encode(Text) ->
$& -> <<"&amp;">>;
$< -> <<"&lt;">>;
$> -> <<"&gt;">>;
- _ -> <<C>>
- end || <<C>> <= Text>>.
+ $" -> <<"&quot;">>;
+ $' -> <<"&apos;">>;
+ _ -> <<C/utf8>>
+ end || <<C/utf8>> <= Text>>.