Page MenuHomePhorge

No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/bbcode/parser.ex b/lib/bbcode/parser.ex
index aa4afca..4c8524e 100644
--- a/lib/bbcode/parser.ex
+++ b/lib/bbcode/parser.ex
@@ -1,102 +1,105 @@
defmodule BBCode.Parser do
import NimbleParsec
@moduledoc """
Parse BBCode into an abstract tree.
"""
tag = utf8_string([?a..?z, ?A..?Z, ?0..?9], min: 1)
text = utf8_string([not: ?[, not: ?]], min: 1)
text_without_newline = utf8_string([not: ?[, not: ?\n], min: 1)
- start_tag = ignore(string("[")) |> concat(tag) |> ignore(string("]"))
+ start_tag =
+ ignore(string("[")) |> concat(tag) |> ignore(string("]")) |> ignore(optional(string("\n")))
+
end_tag = ignore(string("[/")) |> concat(tag) |> ignore(string("]"))
start_tag_with_property =
ignore(string("["))
|> concat(tag)
|> ignore(string("="))
|> concat(text)
|> ignore(string("]"))
+ |> ignore(optional(string("\n")))
star_tag = ignore(string("[*]"))
defcombinatorp(
:basic_stanza,
start_tag
|> repeat(lookahead_not(string("[/")) |> choice([parsec(:child_stanza), text]))
|> wrap()
|> concat(end_tag)
|> post_traverse(:emit_tree_node)
)
defcombinatorp(
:text_stanza,
text
|> wrap()
|> post_traverse(:emit_tree_node)
)
defcombinatorp(
:star_stanza,
star_tag
|> repeat(
lookahead_not(string("\n"))
|> choice([parsec(:child_stanza), text_without_newline])
)
|> wrap()
|> concat(ignore(string("\n")))
|> post_traverse(:emit_tree_node_star)
)
defparsec(
:prop_stanza,
start_tag_with_property
|> repeat(lookahead_not(string("[/")) |> choice([parsec(:child_stanza), text]))
|> wrap()
|> concat(end_tag)
|> post_traverse(:emit_tree_node_property)
)
defcombinatorp(
:child_stanza,
choice([parsec(:star_stanza), parsec(:prop_stanza), parsec(:basic_stanza)])
)
defcombinatorp(
:root_stanza,
choice([parsec(:child_stanza), parsec(:text_stanza)])
)
defparsecp(
:parse_tree,
repeat(lookahead_not(string("[/")) |> parsec(:root_stanza)) |> eos()
)
defp emit_tree_node_star(_rest, [nodes], context, _line, _offset),
do: {[{:li, nodes}], context}
defp emit_tree_node_property(_rest, [tag, [tag, property, inside]], context, _line, _offset),
do: {[{String.to_atom(tag), property, inside}], context}
defp emit_tree_node_property(_rest, [tag, [tag, property | nodes]], context, _line, _offset),
do: {[{String.to_atom(tag), property, nodes}], context}
defp emit_tree_node(_rest, [tag, [tag, inside]], context, _line, _offset),
do: {[{String.to_atom(tag), inside}], context}
defp emit_tree_node(_rest, [tag, [tag | nodes]], context, _line, _offset),
do: {[{String.to_atom(tag), nodes}], context}
defp emit_tree_node(_rest, [[text]], context, _line, _offset),
do: {[text], context}
def parse(text) do
with {:ok, nodes, _, _, _, _} <- parse_tree(text) do
{:ok, nodes}
else
{:error, e, _, _, _, _} ->
{:error, e}
end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 25, 3:26 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39947
Default Alt Text
(3 KB)

Event Timeline