@@ -2,7 +2,7 @@ defmodule ComponentsGuideWeb.DownView do
2
2
use ComponentsGuideWeb , :view
3
3
4
4
defmodule ParserState do
5
- defstruct bold: false , italics: false , html: [ ]
5
+ defstruct html: [ ] , italics: nil , bold: nil , link: nil
6
6
7
7
@ spec parse ( binary ) ::
8
8
{ :safe ,
@@ -15,33 +15,93 @@ defmodule ComponentsGuideWeb.DownView do
15
15
next ( % __MODULE__ { } , input )
16
16
end
17
17
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 , [ ] } }
20
22
|> next ( rest )
21
23
end
22
24
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 } }
25
27
|> next ( rest )
26
28
end
27
29
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: "**" }
30
68
|> next ( rest )
31
69
end
32
70
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
35
87
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
40
97
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
44
102
103
+ defp next ( state = % __MODULE__ { } , "" ) do
104
+ html = state . html |> Enum . reverse ( ) |> Enum . join ( )
45
105
Phoenix.HTML . raw ( html )
46
106
end
47
107
end
0 commit comments