Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit1fd0740

Browse files
author
mydearxym
committed
refactor: 💡 editor-js
basic markdown to editor converter workflow
1 parent8de6466 commit1fd0740

File tree

7 files changed

+164
-8
lines changed

7 files changed

+164
-8
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,92 @@
1+
defmoduleHelper.Converter.MdToEditordo
2+
@moduledoc"""
3+
parse markdown ast to editor json data
14
5+
see https://editorjs.io/
6+
"""
7+
8+
@supported_header["h1","h2","h3"]
9+
10+
@specparse(binary|[any])::any
11+
defparse(mdstring)do
12+
{:ok,ast,_opt}=Earmark.as_ast(mdstring)
13+
# IO.inspect(ast, label: "raw ast")
14+
15+
editor_blocks=
16+
Enum.reduce(ast,[],fnast_item,acc->
17+
parsed=parse_block(ast_item)
18+
acc++[parsed]
19+
end)
20+
21+
# IO.inspect(editor_blocks, label: "final editor_blocks")
22+
editor_blocks
23+
end
24+
25+
# TODO: parse h4-6 as h3
26+
defpparse_block({type,_opt,content})
27+
whentypein@supported_headerdo
28+
content_text=
29+
Enum.reduce(content,[],fncontent_item,acc->
30+
parsed=parse_content(type,content_item)
31+
acc++parsed
32+
end)
33+
34+
# IO.inspect(content_text, label: "h-type content_text")
35+
36+
[_,level]=String.split(type,"h")
37+
level=String.to_integer(level)
38+
39+
%{
40+
type:"header",
41+
data:%{
42+
text:content_text,
43+
level:level
44+
}
45+
}
46+
end
47+
48+
defpparse_block({"p",_opt,content})do
49+
content_text=
50+
Enum.reduce(content,[],fncontent_item,acc->
51+
parsed=parse_content("p",content_item)
52+
acc++parsed
53+
end)
54+
55+
%{
56+
type:"paragraph",
57+
data:%{
58+
text:content_text
59+
}
60+
}
61+
end
62+
63+
defpparse_block({_type,_opt,_content})do
64+
# IO.inspect(name, label: "parse block")
65+
# IO.inspect(content, label: "content")
66+
%{}
67+
end
68+
69+
# 字符串直接返回,作为 editor.js 中的 text/data/code 等字段
70+
defpparse_content(content)whenis_binary(content)do
71+
content
72+
end
73+
74+
# TODO: editor.js 暂时不支持 del 标签,所以直接返回字符串内容即可
75+
defpparse_content({"del",[],[content]})do
76+
content
77+
end
78+
79+
defpparse_content(_type,content)whenis_binary(content)do
80+
content
81+
end
82+
83+
defpparse_content(type,{_type,_opt,[content]})
84+
whentypein@supported_headerdo
85+
parse_content(content)
86+
end
87+
88+
# defp parse_content({type, _opt, content})
89+
# when type == "h1" or type == "h2" or type == "h3" do
90+
# content
91+
# end
92+
end

‎mix.exs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ defmodule GroupherServer.Mixfile do
103103
# cron-like scheduler job
104104
{:quantum,"~> 2.3"},
105105
{:html_sanitize_ex,"~> 1.3"},
106-
{:open_graph,"~> 0.0.3"}
106+
{:open_graph,"~> 0.0.3"},
107+
{:earmark,"~> 1.4.0"}
107108
]
108109
end
109110

‎mix.lock‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"db_connection":{:hex,:db_connection,"2.1.1","a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5",[:mix],[{:connection,"~> 1.0.2",[hex::connection,repo:"hexpm",optional:false]}],"hexpm"},
2323
"decimal":{:hex,:decimal,"1.8.0","ca462e0d885f09a1c5a342dbd7c1dcf27ea63548c65a65e67334f4b61803822e",[:mix],[],"hexpm"},
2424
"dialyxir":{:hex,:dialyxir,"1.0.0-rc.6","78e97d9c0ff1b5521dd68041193891aebebce52fc3b93463c0a6806874557d7d",[:mix],[{:erlex,"~> 0.2.1",[hex::erlex,repo:"hexpm",optional:false]}],"hexpm"},
25+
"earmark":{:hex,:earmark,"1.4.0","397e750b879df18198afc66505ca87ecf6a96645545585899f6185178433cc09",[:mix],[],"hexpm"},
2526
"ecto":{:hex,:ecto,"3.1.7","fa21d06ef56cdc2fdaa62574e8c3ba34a2751d44ea34c30bc65f0728421043e5",[:mix],[{:decimal,"~> 1.6",[hex::decimal,repo:"hexpm",optional:false]},{:jason,"~> 1.0",[hex::jason,repo:"hexpm",optional:true]}],"hexpm"},
2627
"ecto_sql":{:hex,:ecto_sql,"3.1.6","1e80e30d16138a729c717f73dcb938590bcdb3a4502f3012414d0cbb261045d8",[:mix],[{:db_connection,"~> 2.0",[hex::db_connection,repo:"hexpm",optional:false]},{:ecto,"~> 3.1.0",[hex::ecto,repo:"hexpm",optional:false]},{:mariaex,"~> 0.9.1",[hex::mariaex,repo:"hexpm",optional:true]},{:myxql,"~> 0.2.0",[hex::myxql,repo:"hexpm",optional:true]},{:postgrex,"~> 0.14.0 or ~> 0.15.0",[hex::postgrex,repo:"hexpm",optional:true]},{:telemetry,"~> 0.4.0",[hex::telemetry,repo:"hexpm",optional:false]}],"hexpm"},
2728
"elixir_make":{:hex,:elixir_make,"0.4.0","992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf",[],[],"hexpm"},

‎test/groupher_server_web/controller/og_test.exs‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ defmodule GroupherServerWeb.Test.Controller.OG do
44
"""
55
useGroupherServer.TestTools
66

7-
@tag:wip
87
test"should return valid structure when query url is valid"do
98
conn=build_conn()
109

@@ -24,7 +23,6 @@ defmodule GroupherServerWeb.Test.Controller.OG do
2423
assertMap.has_key?(image,"url")
2524
end
2625

27-
@tag:wip
2826
test"should return valid structure & error msg when query domain is not exsit"do
2927
conn=build_conn()
3028

@@ -52,7 +50,6 @@ defmodule GroupherServerWeb.Test.Controller.OG do
5250
assertMap.has_key?(image,"url")
5351
end
5452

55-
@tag:wip
5653
test"return empty valid structure when url not follow open-graph"do
5754
conn=build_conn()
5855

‎test/helper/converter/editor_to_html_test.exs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHtml do
183183
assert{:error,converted}=Parser.string_to_json(string)
184184
end
185185

186-
@tag:wip
187186
test"real-world editor.js data should work"do
188187
{:ok,converted}=Parser.string_to_json(@real_editor_data)
189188

@@ -193,7 +192,6 @@ defmodule GroupherServer.Test.Helper.Converter.EditorToHtml do
193192
assertconverted["time"]|>is_integer
194193
end
195194

196-
@tag:wip
197195
test"todo"do
198196
# IO.inspect(converted, label: "haha")
199197
Parser.convert_to_html(@real_editor_data)

‎test/helper/converter/html_sanitizer_test.exs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ defmodule GroupherServer.Test.Helper.Converter.HtmlSanitizer do
77
aliasHelper.Converter.HtmlSanitizer,as:Sanitizer
88

99
describe"[snaitizer test]"do
10-
@tag:wip2
1110
test"should strip p h4-6 etc tags"do
1211
html=
1312
"<form>hello</form><h4>1</h4><h5>2</h5><h6>3</h6><h4>4</h4><h5>5</h5><h6>6</h6><h1>world</h1><h2>world2</h2><h3>world3</h3>"
@@ -29,7 +28,6 @@ defmodule GroupherServer.Test.Helper.Converter.HtmlSanitizer do
2928
"This is <a href=\"http://coderplanets.com/post/1\" name=\"name\" title=\"title\">cps</a>"
3029
end
3130

32-
@tag:wip2
3331
test"allow mark tag with class attr"do
3432
html="This <form>is</form> <mark class=\"cool-look\" other=\"other\">mark text</mark>"
3533
assertSanitizer.sanitize(html)=="This is <mark class=\"cool-look\">mark text</mark>"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
defmoduleGroupherServer.Test.Helper.Converter.MdToEditordo
2+
useGroupherServerWeb.ConnCase,async:true
3+
4+
aliasHelper.Converter.MdToEditor,as:Converter
5+
6+
describe"[basic md test]"do
7+
@tag:wip
8+
test"ast parser should work"do
9+
mdstring="""
10+
11+
## hello
12+
13+
this is a basic markdown text
14+
15+
### ~~delete me~~
16+
this is a basic markdown text
17+
18+
### _~~italic me~~_
19+
this is a basic markdown text
20+
"""
21+
22+
res=Converter.parse(mdstring)
23+
24+
assertres==
25+
[
26+
%{data:%{level:2,text:"hello"},type:"header"},
27+
%{
28+
data:%{text:"this is a basic markdown text"},
29+
type:"paragraph"
30+
},
31+
%{data:%{level:3,text:"delete me"},type:"header"},
32+
%{
33+
data:%{text:"this is a basic markdown text"},
34+
type:"paragraph"
35+
},
36+
%{data:%{level:3,text:"italic me"},type:"header"},
37+
%{
38+
data:%{text:"this is a basic markdown text"},
39+
type:"paragraph"
40+
}
41+
]
42+
43+
# IO.inspect(res, label: "ast")
44+
45+
# assert Sanitizer.sanitize(html) == "hello123456<h1>world</h1><h2>world2</h2><h3>world3</h3>"
46+
end
47+
48+
@tag:wip2
49+
test"complex ast parser should work"do
50+
mdstring="""
51+
52+
## hello
53+
54+
this is a basic *markdown* text
55+
56+
### ~~delete me~~
57+
58+
### _~~italic me~~_
59+
60+
My `in-line-code-content` is **best**
61+
"""
62+
63+
res=Converter.parse(mdstring)
64+
65+
# IO.inspect(res, label: "ast")
66+
67+
# assert Sanitizer.sanitize(html) == "hello123456<h1>world</h1><h2>world2</h2><h3>world3</h3>"
68+
end
69+
end
70+
end

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp