Page MenuHomePhorge

No OneTemporary

Size
10 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/bbcode/generator.ex b/lib/bbcode/generator.ex
index 2f0375a..14b78b0 100644
--- a/lib/bbcode/generator.ex
+++ b/lib/bbcode/generator.ex
@@ -1,73 +1,73 @@
defmodule BBCode.Generator do
@moduledoc """
Generate HTML from BBCode fragments in AST form.
The BBCode syntax supported is described at [bbcode.org][bbcode].
[bbcode]: https://www.bbcode.org/reference.php
"""
defp start_tag(tagname), do: Enum.join(["<", tagname, ">"])
defp end_tag(tagname), do: Enum.join(["</", tagname, ">"])
defp simple_tag(tagname, subtree) do
{:ok, text} = reduce_subtree(subtree)
{:ok, [start_tag(tagname), text, end_tag(tagname)] |> Enum.join()}
end
defp link_tag(url), do: Enum.join(["<a href=\"", url, "\">"])
defp reduce_subtree({:b, subtree}), do: simple_tag("strong", subtree)
defp reduce_subtree({:i, subtree}), do: simple_tag("em", subtree)
defp reduce_subtree({:u, subtree}), do: simple_tag("u", subtree)
defp reduce_subtree({:s, subtree}), do: simple_tag("del", subtree)
defp reduce_subtree({:ul, subtree}), do: simple_tag("ul", subtree)
defp reduce_subtree({:ol, subtree}), do: simple_tag("ol", subtree)
defp reduce_subtree({:li, subtree}), do: simple_tag("li", subtree)
defp reduce_subtree({:code, subtree}), do: simple_tag("pre", subtree)
defp reduce_subtree({:quote, subtree}), do: simple_tag("blockquote", subtree)
defp reduce_subtree({:table, subtree}), do: simple_tag("table", subtree)
defp reduce_subtree({:tr, subtree}), do: simple_tag("tr", subtree)
defp reduce_subtree({:th, subtree}), do: simple_tag("th", subtree)
defp reduce_subtree({:td, subtree}), do: simple_tag("td", subtree)
defp reduce_subtree({:url, text}),
do: {:ok, [link_tag(text), text, end_tag("a")] |> Enum.join()}
defp reduce_subtree({:url, address, text}),
do: {:ok, [link_tag(address), text, end_tag("a")] |> Enum.join()}
defp reduce_subtree({:img, address}),
do: {:ok, "<img src=\"#{address}\">"}
defp reduce_subtree({:img, width, height, address}),
do: {:ok, "<img src=\"#{address}\" width=\"#{width}\" height=\"#{height}\">"}
- defp reduce_subtree({:br}), do: {:ok, "<br>\n"}
+ defp reduce_subtree({:br}), do: {:ok, "<br>"}
defp reduce_subtree(text_node) when is_binary(text_node),
do: {:ok, text_node}
defp reduce_subtree(children) when is_list(children) do
with {:ok, new_tree} <-
Enum.reduce_while(children, {:ok, []}, fn x, {:ok, acc} ->
with {:ok, new_tree} <- reduce_subtree(x) do
{:cont, {:ok, acc ++ [new_tree]}}
else
{:error, e} ->
{:halt, {:error, e}}
end
end) do
{:ok, Enum.join(new_tree)}
else
{:error, e} ->
{:error, e}
end
end
defp reduce_subtree(tree), do: {:error, "unknown input #{inspect(tree)}"}
def to_html(tree) when is_list(tree), do: reduce_subtree(tree)
def to_html(_), do: {:error, "not a valid tree"}
end
diff --git a/test/bbcode/generator_test.exs b/test/bbcode/generator_test.exs
index 2d1ea9b..e9e1ddb 100644
--- a/test/bbcode/generator_test.exs
+++ b/test/bbcode/generator_test.exs
@@ -1,167 +1,157 @@
defmodule BBCode.Generator.Test do
use ExUnit.Case
describe "simple tags" do
test "[b] tags are translated to <strong>" do
assert {:ok, "<strong>testing</strong>"} = BBCode.to_html("[b]testing[/b]")
end
test "[i] tags are translated to <em>" do
assert {:ok, "<em>testing</em>"} = BBCode.to_html("[i]testing[/i]")
end
test "[u] tags are translated to <u>" do
assert {:ok, "<u>testing</u>"} = BBCode.to_html("[u]testing[/u]")
end
test "[s] tags are translated to <del>" do
assert {:ok, "<del>testing</del>"} = BBCode.to_html("[s]testing[/s]")
end
test "[code] tags are translated to <pre>" do
assert {:ok, "<pre>testing</pre>"} = BBCode.to_html("[code]testing[/code]")
end
test "[quote] tags are translated to <blockquote>" do
assert {:ok, "<blockquote>testing</blockquote>"} = BBCode.to_html("[quote]testing[/quote]")
end
test "compounding simple tags works as expected" do
assert {:ok, "<strong><em>testing</em></strong>"} = BBCode.to_html("[b][i]testing[/i][/b]")
end
end
describe "lists" do
test "[ul] lists are rendered properly" do
data = """
[ul]
[*]a
[*]b
[*]c
[/ul]
"""
expected = "<ul><li>a</li><li>b</li><li>c</li></ul>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
test "[ol] lists are rendered properly" do
data = """
[ol]
[*]a
[*]b
[*]c
[/ol]
"""
expected = "<ol><li>a</li><li>b</li><li>c</li></ol>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
end
describe "tables" do
test "[table] tables are rendered properly" do
data = """
[table]
[tr]
[th]header[/th]
[/tr]
[tr]
[td]cell[/td]
[/tr]
[/table]
"""
expected = "<table><tr><th>header</th></tr><tr><td>cell</td></tr></table>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
end
describe "links" do
test "bare [url] links are rendered properly" do
data = """
[url]http://example.com[/url]
"""
- expected = "<a href=\"http://example.com\">http://example.com</a><br>\n"
+ expected = "<a href=\"http://example.com\">http://example.com</a><br>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
test "named [url] links are rendered properly" do
data = """
[url=http://example.com]Example[/url]
"""
- expected = "<a href=\"http://example.com\">Example</a><br>\n"
+ expected = "<a href=\"http://example.com\">Example</a><br>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
end
describe "images" do
test "bare [img] links are rendered properly" do
data = """
[img]http://example.com/image.jpg[/img]
"""
- expected = "<img src=\"http://example.com/image.jpg\"><br>\n"
+ expected = "<img src=\"http://example.com/image.jpg\"><br>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
test "sized [img] links are rendered properly" do
data = """
[img=32x32]http://example.com/image.jpg[/img]
"""
- expected = "<img src=\"http://example.com/image.jpg\" width=\"32\" height=\"32\"><br>\n"
+ expected = "<img src=\"http://example.com/image.jpg\" width=\"32\" height=\"32\"><br>"
assert {:ok, ^expected} = BBCode.to_html(data)
end
end
describe "documents" do
test "it correctly renders a complex document" do
data = """
[quote]
A multiline quote.
This is the second line.
[/quote]
[ul]
[*]a
[*]b
[*]c
[/ul]
[b]bold[/b]
[i]italic[/i]
[u]underline[/u]
[s]strikethrough[/s]
[url=http://example.com]a link[/url]
@kaniini (a mention)
"""
- expected = """
- <blockquote>A multiline quote.<br>
- This is the second line.<br>
- </blockquote><ul><li>a</li><li>b</li><li>c</li></ul><strong>bold</strong><br>
- <em>italic</em><br>
- <u>underline</u><br>
- <del>strikethrough</del><br>
- <br>
- <a href="http://example.com">a link</a><br>
- <br>
- @kaniini (a mention)<br>
- """
+ {:ok, output} = BBCode.to_html(data)
- assert {:ok, ^expected} = BBCode.to_html(data)
+ assert output ==
+ "<blockquote>A multiline quote.<br>This is the second line.<br></blockquote><ul><li>a</li><li>b</li><li>c</li></ul><strong>bold</strong><br><em>italic</em><br><u>underline</u><br><del>strikethrough</del><br><br><a href=\"http://example.com\">a link</a><br><br>@kaniini (a mention)<br>"
end
end
end
diff --git a/test/bbcode/parser_test.exs b/test/bbcode/parser_test.exs
index e4bb7fa..52d7d35 100644
--- a/test/bbcode/parser_test.exs
+++ b/test/bbcode/parser_test.exs
@@ -1,92 +1,91 @@
defmodule BBCode.Parser.Test do
use ExUnit.Case
alias BBCode.Parser
describe "simple tags" do
test "it parses [b] tags correctly" do
assert {:ok, [b: "testing"]} = Parser.parse("[b]testing[/b]")
end
test "it parses [i] tags correctly" do
assert {:ok, [i: "testing"]} = Parser.parse("[i]testing[/i]")
end
test "it parses [u] tags correctly" do
assert {:ok, [u: "testing"]} = Parser.parse("[u]testing[/u]")
end
test "it parses [s] tags correctly" do
assert {:ok, [s: "testing"]} = Parser.parse("[s]testing[/s]")
end
test "it parses [code] tags correctly" do
assert {:ok, [code: "testing"]} = Parser.parse("[code]testing[/code]")
end
test "it parses [quote] tags correctly" do
assert {:ok, [quote: "testing"]} = Parser.parse("[quote]testing[/quote]")
end
end
describe "nested tags" do
test "it parses [ul] lists correctly" do
assert {:ok, [{:ul, [{:li, "a"}, {:li, "b"}]}]} =
Parser.parse("[ul][li]a[/li][li]b[/li][/ul]")
end
test "it parses [ol] lists correctly" do
assert {:ok, [{:ol, [{:li, "a"}, {:li, "b"}]}]} =
Parser.parse("[ol][li]a[/li][li]b[/li][/ol]")
end
end
describe "multiline" do
test "it parses a multiline [li] list" do
data = """
[ul]
[li]a[/li]
[li]b[/li]
[/ul]
"""
assert {:ok, [{:ul, [{:li, "a"}, {:li, "b"}]}]} = Parser.parse(data)
end
test "it parses a multiline [*] list" do
data = """
[ul]
[*]a
[*]b
[/ul]
"""
assert {:ok, [{:ul, [{:li, ["a"]}, {:li, ["b"]}]}]} = Parser.parse(data)
end
test "it parses a multiline [*] list with children" do
data = """
[ul]
[*][url=http://example.com]Example[/url]
[/ul]
"""
assert {:ok, [{:ul, {:li, [{:url, "http://example.com", "Example"}]}}]} = Parser.parse(data)
end
end
describe "property tags" do
test "it parses [url=] tags correctly" do
assert {:ok, [{:url, "http://example.com", "Example"}]} =
Parser.parse("[url=http://example.com]Example[/url]")
end
end
describe "non-tags" do
test "it properly handles bracket text" do
data = "oh no! [swearing intensifies]"
- assert {:ok, ["oh no! ", "[swearing intensifies]"]} =
- Parser.parse(data)
+ assert {:ok, ["oh no! ", "[swearing intensifies]"]} = Parser.parse(data)
end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 24, 12:38 PM (1 d, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39420
Default Alt Text
(10 KB)

Event Timeline