Packages
phoenix_html
3.0.1
4.3.0
4.2.1
4.2.0
4.1.1
4.1.0
4.0.0
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.0
3.1.0
3.0.4
3.0.3
retired
3.0.2
retired
3.0.1
retired
3.0.0
retired
2.14.3
2.14.2
2.14.1
2.14.0
2.13.4
2.13.3
2.13.2
2.13.1
2.13.0
2.12.0
2.11.2
2.11.1
2.11.0
2.10.5
2.10.4
2.10.3
2.10.2
2.10.1
2.10.0
2.9.3
2.9.2
2.9.1
2.9.0
2.8.0
2.7.0
2.7.0-dev
2.6.2
2.6.1
2.6.0
2.5.1
2.5.0
2.4.0
2.4.0-dev
2.3.1
2.3.0
2.2.0
2.1.2
2.1.1
2.1.0
2.0.1
2.0.0
2.0.0-dev
1.4.0
1.3.0
1.2.1
1.2.0
1.1.0
1.0.1
1.0.0
Phoenix view functions for working with HTML templates
Retired package: Security issue - The :class attribute in content_tag and in class={@class} for HEEx is not escaped against XSS
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/phoenix_html/format.ex
defmodule Phoenix.HTML.Format do
@moduledoc """
Helpers related to formatting text.
"""
@doc ~S"""
Returns text transformed into HTML using simple formatting rules.
Two or more consecutive newlines `\n\n` or `\r\n\r\n` are considered as a
paragraph and text between them is wrapped in `<p>` tags.
One newline `\n` or `\r\n` is considered as a linebreak and a `<br>` tag is inserted.
## Examples
iex> text_to_html("Hello\n\nWorld") |> safe_to_string
"<p>Hello</p>\n<p>World</p>\n"
iex> text_to_html("Hello\nWorld") |> safe_to_string
"<p>Hello<br>\nWorld</p>\n"
iex> opts = [wrapper_tag: :div, attributes: [class: "p"]]
...> text_to_html("Hello\n\nWorld", opts) |> safe_to_string
"<div class=\"p\">Hello</div>\n<div class=\"p\">World</div>\n"
## Options
* `:escape` - if `false` does not html escape input (default: `true`)
* `:wrapper_tag` - tag to wrap each paragraph (default: `:p`)
* `:attributes` - html attributes of the wrapper tag (default: `[]`)
* `:insert_brs` - if `true` insert `<br>` for single line breaks (default: `true`)
"""
@spec text_to_html(Phoenix.HTML.unsafe(), Keyword.t()) :: Phoenix.HTML.safe()
def text_to_html(string, opts \\ []) do
escape? = Keyword.get(opts, :escape, true)
wrapper_tag = Keyword.get(opts, :wrapper_tag, :p)
attributes = Keyword.get(opts, :attributes, [])
insert_brs? = Keyword.get(opts, :insert_brs, true)
string
|> maybe_html_escape(escape?)
|> String.split(["\n\n", "\r\n\r\n"], trim: true)
|> Enum.filter(¬_blank?/1)
|> Enum.map(&wrap_paragraph(&1, wrapper_tag, attributes, insert_brs?))
|> Phoenix.HTML.html_escape()
end
defp maybe_html_escape(string, true),
do: string |> Phoenix.HTML.Engine.html_escape() |> IO.iodata_to_binary()
defp maybe_html_escape(string, false),
do: string
defp not_blank?("\r\n" <> rest), do: not_blank?(rest)
defp not_blank?("\n" <> rest), do: not_blank?(rest)
defp not_blank?(" " <> rest), do: not_blank?(rest)
defp not_blank?(""), do: false
defp not_blank?(_), do: true
defp wrap_paragraph(text, tag, attributes, insert_brs?) do
[Phoenix.HTML.Tag.content_tag(tag, insert_brs(text, insert_brs?), attributes), ?\n]
end
defp insert_brs(text, false) do
text
|> split_lines()
|> Enum.intersperse(?\s)
|> Phoenix.HTML.raw()
end
defp insert_brs(text, true) do
text
|> split_lines()
|> Enum.map(&Phoenix.HTML.raw/1)
|> Enum.intersperse([Phoenix.HTML.Tag.tag(:br), ?\n])
end
defp split_lines(text) do
String.split(text, ["\n", "\r\n"], trim: true)
end
end