Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F5811067
earmark_renderer.ex
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
earmark_renderer.ex
View Options
# Pleroma: A lightweight social networking server
# Copyright © 2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
#
# This file is derived from Earmark, under the following copyright:
# Copyright © 2014 Dave Thomas, The Pragmatic Programmers
# SPDX-License-Identifier: Apache-2.0
# Upstream: https://github.com/pragdave/earmark/blob/master/lib/earmark/html_renderer.ex
defmodule
Pleroma.EarmarkRenderer
do
@moduledoc
false
alias
Earmark.Block
alias
Earmark.Context
alias
Earmark.HtmlRenderer
alias
Earmark.Options
import
Earmark.Inline
,
only
:
[
convert
:
3
]
import
Earmark.Helpers.HtmlHelpers
import
Earmark.Message
,
only
:
[
add_messages_from
:
2
,
get_messages
:
1
,
set_messages
:
2
]
import
Earmark.Context
,
only
:
[
append
:
2
,
set_value
:
2
]
import
Earmark.Options
,
only
:
[
get_mapper
:
1
]
@doc
false
def
render
(
blocks
,
%
Context
{
options
:
%
Options
{}}
=
context
)
do
messages
=
get_messages
(
context
)
{
contexts
,
html
}
=
get_mapper
(
context
.
options
)
.
(
blocks
,
&
render_block
(
&1
,
put_in
(
context
.
options
.
messages
,
[]))
)
|>
Enum
.
unzip
()
all_messages
=
contexts
|>
Enum
.
reduce
(
messages
,
fn
ctx
,
messages1
->
messages1
++
get_messages
(
ctx
)
end
)
{
put_in
(
context
.
options
.
messages
,
all_messages
),
html
|>
IO
.
iodata_to_binary
()}
end
#############
# Paragraph #
#############
defp
render_block
(%
Block.Para
{
lnb
:
lnb
,
lines
:
lines
,
attrs
:
attrs
},
context
)
do
lines
=
convert
(
lines
,
lnb
,
context
)
add_attrs
(
lines
,
"<p>
#{
lines
.
value
}
</p>"
,
attrs
,
[],
lnb
)
end
########
# Html #
########
defp
render_block
(%
Block.Html
{
html
:
html
},
context
)
do
{
context
,
html
}
end
defp
render_block
(%
Block.HtmlComment
{
lines
:
lines
},
context
)
do
{
context
,
lines
}
end
defp
render_block
(%
Block.HtmlOneline
{
html
:
html
},
context
)
do
{
context
,
html
}
end
#########
# Ruler #
#########
defp
render_block
(%
Block.Ruler
{
lnb
:
lnb
,
attrs
:
attrs
},
context
)
do
add_attrs
(
context
,
"<hr />"
,
attrs
,
[],
lnb
)
end
###########
# Heading #
###########
defp
render_block
(
%
Block.Heading
{
lnb
:
lnb
,
level
:
level
,
content
:
content
,
attrs
:
attrs
},
context
)
do
converted
=
convert
(
content
,
lnb
,
context
)
html
=
"<h
#{
level
}
>
#{
converted
.
value
}
</h
#{
level
}
>"
add_attrs
(
converted
,
html
,
attrs
,
[],
lnb
)
end
##############
# Blockquote #
##############
defp
render_block
(%
Block.BlockQuote
{
lnb
:
lnb
,
blocks
:
blocks
,
attrs
:
attrs
},
context
)
do
{
context1
,
body
}
=
render
(
blocks
,
context
)
html
=
"<blockquote>
#{
body
}
</blockquote>"
add_attrs
(
context1
,
html
,
attrs
,
[],
lnb
)
end
#########
# Table #
#########
defp
render_block
(
%
Block.Table
{
lnb
:
lnb
,
header
:
header
,
rows
:
rows
,
alignments
:
aligns
,
attrs
:
attrs
},
context
)
do
{
context1
,
html
}
=
add_attrs
(
context
,
"<table>"
,
attrs
,
[],
lnb
)
context2
=
set_value
(
context1
,
html
)
context3
=
if
header
do
append
(
add_trs
(
append
(
context2
,
"<thead>"
),
[
header
],
"th"
,
aligns
,
lnb
),
"</thead>"
)
else
# Maybe an error, needed append(context, html)
context2
end
context4
=
append
(
add_trs
(
append
(
context3
,
"<tbody>"
),
rows
,
"td"
,
aligns
,
lnb
),
"</tbody>"
)
{
context4
,
[
context4
.
value
,
"</table>"
]}
end
########
# Code #
########
defp
render_block
(
%
Block.Code
{
lnb
:
lnb
,
language
:
language
,
attrs
:
attrs
}
=
block
,
%
Context
{
options
:
options
}
=
context
)
do
class
=
if
language
,
do
:
~s{ class="
#{
code_classes
(
language
,
options
.
code_class_prefix
)
}
"}
,
else
:
""
tag
=
~s[<pre><code
#{
class
}
>]
lines
=
options
.
render_code
.
(
block
)
html
=
~s[
#{
tag
}#{
lines
}
</code></pre>]
add_attrs
(
context
,
html
,
attrs
,
[],
lnb
)
end
#########
# Lists #
#########
defp
render_block
(
%
Block.List
{
lnb
:
lnb
,
type
:
type
,
blocks
:
items
,
attrs
:
attrs
,
start
:
start
},
context
)
do
{
context1
,
content
}
=
render
(
items
,
context
)
html
=
"<
#{
type
}#{
start
}
>
#{
content
}
</
#{
type
}
>"
add_attrs
(
context1
,
html
,
attrs
,
[],
lnb
)
end
# format a single paragraph list item, and remove the para tags
defp
render_block
(
%
Block.ListItem
{
lnb
:
lnb
,
blocks
:
blocks
,
spaced
:
false
,
attrs
:
attrs
},
context
)
when
length
(
blocks
)
==
1
do
{
context1
,
content
}
=
render
(
blocks
,
context
)
content
=
Regex
.
replace
(
~r{</?p>}
,
content
,
""
)
html
=
"<li>
#{
content
}
</li>"
add_attrs
(
context1
,
html
,
attrs
,
[],
lnb
)
end
# format a spaced list item
defp
render_block
(%
Block.ListItem
{
lnb
:
lnb
,
blocks
:
blocks
,
attrs
:
attrs
},
context
)
do
{
context1
,
content
}
=
render
(
blocks
,
context
)
html
=
"<li>
#{
content
}
</li>"
add_attrs
(
context1
,
html
,
attrs
,
[],
lnb
)
end
##################
# Footnote Block #
##################
defp
render_block
(%
Block.FnList
{
blocks
:
footnotes
},
context
)
do
items
=
Enum
.
map
(
footnotes
,
fn
note
->
blocks
=
append_footnote_link
(
note
)
%
Block.ListItem
{
attrs
:
"
#
fn:
#{
note
.
number
}
"
,
type
:
:ol
,
blocks
:
blocks
}
end
)
{
context1
,
html
}
=
render_block
(%
Block.List
{
type
:
:ol
,
blocks
:
items
},
context
)
{
context1
,
Enum
.
join
([
~s[<div class="footnotes">]
,
"<hr />"
,
html
,
"</div>"
])}
end
#######################################
# Isolated IALs are rendered as paras #
#######################################
defp
render_block
(%
Block.Ial
{
verbatim
:
verbatim
},
context
)
do
{
context
,
"<p>{:
#{
verbatim
}
}</p>"
}
end
####################
# IDDef is ignored #
####################
defp
render_block
(%
Block.IdDef
{},
context
),
do
:
{
context
,
""
}
#####################################
# And here are the inline renderers #
#####################################
defdelegate
br
,
to
:
HtmlRenderer
defdelegate
codespan
(
text
),
to
:
HtmlRenderer
defdelegate
em
(
text
),
to
:
HtmlRenderer
defdelegate
strong
(
text
),
to
:
HtmlRenderer
defdelegate
strikethrough
(
text
),
to
:
HtmlRenderer
defdelegate
link
(
url
,
text
),
to
:
HtmlRenderer
defdelegate
link
(
url
,
text
,
title
),
to
:
HtmlRenderer
defdelegate
image
(
path
,
alt
,
title
),
to
:
HtmlRenderer
defdelegate
footnote_link
(
ref
,
backref
,
number
),
to
:
HtmlRenderer
# Table rows
defp
add_trs
(
context
,
rows
,
tag
,
aligns
,
lnb
)
do
numbered_rows
=
rows
|>
Enum
.
zip
(
Stream
.
iterate
(
lnb
,
&
(
&1
+
1
)))
numbered_rows
|>
Enum
.
reduce
(
context
,
fn
{
row
,
lnb
},
ctx
->
append
(
add_tds
(
append
(
ctx
,
"<tr>"
),
row
,
tag
,
aligns
,
lnb
),
"</tr>"
)
end
)
end
defp
add_tds
(
context
,
row
,
tag
,
aligns
,
lnb
)
do
Enum
.
reduce
(
1
..
length
(
row
),
context
,
add_td_fn
(
row
,
tag
,
aligns
,
lnb
))
end
defp
add_td_fn
(
row
,
tag
,
aligns
,
lnb
)
do
fn
n
,
ctx
->
style
=
case
Enum
.
at
(
aligns
,
n
-
1
,
:default
)
do
:default
->
""
align
->
" style=\"text-align:
#{
align
}
\""
end
col
=
Enum
.
at
(
row
,
n
-
1
)
converted
=
convert
(
col
,
lnb
,
set_messages
(
ctx
,
[]))
append
(
add_messages_from
(
ctx
,
converted
),
"<
#{
tag
}#{
style
}
>
#{
converted
.
value
}
</
#{
tag
}
>"
)
end
end
###############################
# Append Footnote Return Link #
###############################
defdelegate
append_footnote_link
(
note
),
to
:
HtmlRenderer
defdelegate
append_footnote_link
(
note
,
fnlink
),
to
:
HtmlRenderer
defdelegate
render_code
(
lines
),
to
:
HtmlRenderer
defp
code_classes
(
language
,
prefix
)
do
[
""
|
String
.
split
(
prefix
||
""
)]
|>
Enum
.
map
(
fn
pfx
->
"
#{
pfx
}#{
language
}
"
end
)
|>
Enum
.
join
(
" "
)
end
end
File Metadata
Details
Attached
Mime Type
text/x-ruby
Expires
Thu, Aug 14, 3:29 AM (21 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
277391
Default Alt Text
earmark_renderer.ex (7 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment