@@ -2,7 +2,7 @@ defmodule ComponentsGuideWeb.DownView do
22 use ComponentsGuideWeb , :view
33
44 defmodule ParserState do
5- defstruct bold: false , italics: false , html: [ ]
5+ defstruct html: [ ] , italics: nil , bold: nil , link: nil
66
77 @ spec parse ( binary ) ::
88 { :safe ,
@@ -15,33 +15,93 @@ defmodule ComponentsGuideWeb.DownView do
1515 next ( % __MODULE__ { } , input )
1616 end
1717
18- defp next ( state = % __MODULE__ { italics: true } , << "_" :: utf8 >> <> rest ) do
19- % __MODULE__ { state | html: [ state . html ] , italics: false }
18+ # Links
19+
20+ defp next ( state = % __MODULE__ { link: nil } , << "[" :: utf8 >> <> rest ) do
21+ % __MODULE__ { state | link: { :capturing_text , [ ] } }
2022 |> next ( rest )
2123 end
2224
23- defp next ( state = % __MODULE__ { italics: false } , << "_ " :: utf8 >> <> rest ) do
24- % __MODULE__ { state | html: [ "<em1>" | state . html ] , italics: true }
25+ defp next ( state = % __MODULE__ { link: { :capturing_text , text_chars } } , << "] " :: utf8 >> <> rest ) do
26+ % __MODULE__ { state | link: { :ready_for_url , text_chars } }
2527 |> next ( rest )
2628 end
2729
28- defp next ( state = % __MODULE__ { } , << char :: utf8 >> <> rest ) do
29- % __MODULE__ { state | html: [ << char :: utf8 >> | state . html ] }
30+ defp next (
31+ state = % __MODULE__ { link: { :capturing_text , text_chars } } ,
32+ << char :: utf8 >> <> rest
33+ ) do
34+ % __MODULE__ { state | link: { :capturing_text , [ char | text_chars ] } }
35+ |> next ( rest )
36+ end
37+
38+ defp next ( state = % __MODULE__ { link: { :ready_for_url , text_chars } } , << "(" :: utf8 >> <> rest ) do
39+ % __MODULE__ { state | link: { :capturing_url , text_chars , [ ] } }
40+ |> next ( rest )
41+ end
42+
43+ defp next (
44+ state = % __MODULE__ { link: { :capturing_url , text_chars , url_chars } } ,
45+ << ")" :: utf8 >> <> rest
46+ ) do
47+ text = text_chars |> Enum . reverse ( ) |> List . to_string ( )
48+ url = url_chars |> Enum . reverse ( ) |> List . to_string ( )
49+
50+ anchor_html = Phoenix.HTML.Link . link ( text , to: url ) |> Phoenix.HTML . safe_to_string ( )
51+
52+ % __MODULE__ { state | html: [ anchor_html | state . html ] , link: nil }
53+ |> next ( rest )
54+ end
55+
56+ defp next (
57+ state = % __MODULE__ { link: { :capturing_url , link_chars , url_chars } } ,
58+ << char :: utf8 >> <> rest
59+ ) do
60+ % __MODULE__ { state | link: { :capturing_url , link_chars , [ char | url_chars ] } }
61+ |> next ( rest )
62+ end
63+
64+ # Bold
65+
66+ defp next ( state = % __MODULE__ { bold: nil } , << "**" :: utf8 >> <> rest ) do
67+ % __MODULE__ { state | html: [ "<strong>" | state . html ] , bold: "**" }
3068 |> next ( rest )
3169 end
3270
33- defp next ( state = % __MODULE__ { italics: italics } , "" ) do
34- html = Enum . reverse ( state . html ) |> Enum . join ( )
71+ defp next ( state = % __MODULE__ { bold: "**" } , << "**" :: utf8 >> <> rest ) do
72+ % __MODULE__ { state | html: [ "</strong>" | state . html ] , bold: nil }
73+ |> next ( rest )
74+ end
75+
76+ # Italics
77+
78+ defp next ( state = % __MODULE__ { italics: nil } , << "_" :: utf8 >> <> rest ) do
79+ % __MODULE__ { state | html: [ "<em>" | state . html ] , italics: "_" }
80+ |> next ( rest )
81+ end
82+
83+ defp next ( state = % __MODULE__ { italics: "_" } , << "_" :: utf8 >> <> rest ) do
84+ % __MODULE__ { state | html: [ "</em>" | state . html ] , italics: nil }
85+ |> next ( rest )
86+ end
3587
36- html =
37- case italics do
38- true ->
39- html <> "</em>"
88+ defp next ( state = % __MODULE__ { italics: nil } , << "*" :: utf8 >> <> rest ) do
89+ % __MODULE__ { state | html: [ "<em>" | state . html ] , italics: "*" }
90+ |> next ( rest )
91+ end
92+
93+ defp next ( state = % __MODULE__ { italics: "*" } , << "*" :: utf8 >> <> rest ) do
94+ % __MODULE__ { state | html: [ "</em>" | state . html ] , italics: nil }
95+ |> next ( rest )
96+ end
4097
41- false ->
42- html
43- end
98+ defp next ( state = % __MODULE__ { } , << char :: utf8 >> <> rest ) do
99+ % __MODULE__ { state | html: [ << char :: utf8 >> | state . html ] }
100+ |> next ( rest )
101+ end
44102
103+ defp next ( state = % __MODULE__ { } , "" ) do
104+ html = state . html |> Enum . reverse ( ) |> Enum . join ( )
45105 Phoenix.HTML . raw ( html )
46106 end
47107 end
0 commit comments