Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85823322
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/fast_html.ex b/lib/fast_html.ex
index 8cb824a..91c94a4 100644
--- a/lib/fast_html.ex
+++ b/lib/fast_html.ex
@@ -1,101 +1,102 @@
defmodule :fast_html do
@moduledoc """
A module to decode html into a tree structure.
Based on [Alexander Borisov's myhtml](https://github.com/lexborisov/myhtml),
this binding gains the properties of being html-spec compliant and very fast.
## Example
iex> :fast_html.decode("<h1>Hello world</h1>")
{"html", [], [{"head", [], []}, {"body", [], [{"h1", [], ["Hello world"]}]}]}
Benchmark results (removed Nif calling mode) on various file sizes on a 2,5Ghz Core i7:
Settings:
duration: 1.0 s
## FileSizesBench
[15:28:42] 1/3: github_trending_js.html 341k
[15:28:46] 2/3: w3c_html5.html 131k
[15:28:48] 3/3: wikipedia_hyperlink.html 97k
Finished in 7.52 seconds
## FileSizesBench
benchmark name iterations average time
wikipedia_hyperlink.html 97k 1000 1385.86 µs/op
w3c_html5.html 131k 1000 2179.30 µs/op
github_trending_js.html 341k 500 5686.21 µs/op
"""
@type tag() :: String.t() | atom()
@type attr() :: {String.t(), String.t()}
@type attr_list() :: [] | [attr()]
@type comment_node() :: {:comment, String.t()}
@type comment_node3() :: {:comment, [], String.t()}
@type tree() ::
{tag(), attr_list(), tree()}
| {tag(), attr_list(), nil}
| comment_node()
| comment_node3()
@type format_flag() :: :html_atoms | :nil_self_closing | :comment_tuple3
@doc """
Returns a tree representation from the given html string.
## Examples
iex> :fast_html.decode("<h1>Hello world</h1>")
{"html", [], [{"head", [], []}, {"body", [], [{"h1", [], ["Hello world"]}]}]}
iex> :fast_html.decode("<span class='hello'>Hi there</span>")
{"html", [],
[{"head", [], []},
{"body", [], [{"span", [{"class", "hello"}], ["Hi there"]}]}]}
iex> :fast_html.decode("<body><!-- a comment --!></body>")
{"html", [], [{"head", [], []}, {"body", [], [comment: " a comment "]}]}
iex> :fast_html.decode("<br>")
{"html", [], [{"head", [], []}, {"body", [], [{"br", [], []}]}]}
"""
@spec decode(String.t()) :: tree()
def decode(bin) do
decode(bin, format: [])
end
@doc """
Returns a tree representation from the given html string.
This variant allows you to pass in one or more of the following format flags:
* `:html_atoms` uses atoms for known html tags (faster), binaries for everything else.
* `:nil_self_closing` uses `nil` to designate self-closing tags and void elements.
For example `<br>` is then being represented like `{"br", [], nil}`.
See http://w3c.github.io/html-reference/syntax.html#void-elements for a full list of void elements.
* `:comment_tuple3` uses 3-tuple elements for comments, instead of the default 2-tuple element.
## Examples
iex> :fast_html.decode("<h1>Hello world</h1>", format: [:html_atoms])
{:html, [], [{:head, [], []}, {:body, [], [{:h1, [], ["Hello world"]}]}]}
iex> :fast_html.decode("<br>", format: [:nil_self_closing])
{"html", [], [{"head", [], []}, {"body", [], [{"br", [], nil}]}]}
iex> :fast_html.decode("<body><!-- a comment --!></body>", format: [:comment_tuple3])
{"html", [], [{"head", [], []}, {"body", [], [{:comment, [], " a comment "}]}]}
iex> html = "<body><!-- a comment --!><unknown /></body>"
iex> :fast_html.decode(html, format: [:html_atoms, :nil_self_closing, :comment_tuple3])
{:html, [],
[{:head, [], []},
{:body, [], [{:comment, [], " a comment "}, {"unknown", [], nil}]}]}
"""
@spec decode(String.t(), format: [format_flag()]) :: tree()
def decode(bin, format: flags) do
- Myhtmlex.Safe.decode(bin, flags)
+ {:ok, res} = Nodex.Cnode.call(FastHtml.Cnode, {:decode, bin, flags})
+ res
end
end
diff --git a/lib/myhtmlex/safe.ex b/lib/fast_html/application.ex
similarity index 51%
rename from lib/myhtmlex/safe.ex
rename to lib/fast_html/application.ex
index 98b98d5..6d55509 100644
--- a/lib/myhtmlex/safe.ex
+++ b/lib/fast_html/application.ex
@@ -1,39 +1,30 @@
-defmodule Myhtmlex.Safe do
+defmodule FastHtml.Application do
@moduledoc false
use Application
- app = Mix.Project.config()[:app]
+ application = Mix.Project.config()[:app]
defp random_sname, do: :crypto.strong_rand_bytes(4) |> Base.encode16(case: :lower)
- defp sname, do: :"myhtmlex_#{random_sname()}"
+ defp sname, do: :"fasthtml_#{random_sname()}"
def start(_type, _args) do
import Supervisor.Spec
unless Node.alive?() do
Nodex.Distributed.up()
end
- myhtml_worker = Path.join(:code.priv_dir(unquote(app)), "myhtml_worker")
+ myhtml_worker = Path.join(:code.priv_dir(unquote(application)), "myhtml_worker")
children = [
worker(Nodex.Cnode, [
%{exec_path: myhtml_worker, sname: sname()},
- [name: Myhtmlex.Safe.Cnode]
+ [name: FastHtml.Cnode]
])
]
- Supervisor.start_link(children, strategy: :one_for_one, name: Myhtmlex.Safe.Supervisor)
- end
-
- def decode(bin) do
- decode(bin, [])
- end
-
- def decode(bin, flags) do
- {:ok, res} = Nodex.Cnode.call(Myhtmlex.Safe.Cnode, {:decode, bin, flags})
- res
+ Supervisor.start_link(children, strategy: :one_for_one, name: FastHtml.Supervisor)
end
end
diff --git a/mix.exs b/mix.exs
index e5d5c93..ff8ad8d 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,153 +1,150 @@
defmodule FastHTML.Mixfile do
use Mix.Project
def project do
[
app: :fast_html,
version: "0.2.1",
elixir: "~> 1.5",
deps: deps(),
package: package(),
compilers: [:fast_html_cnode_make] ++ Mix.compilers(),
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
name: "FastHTML",
description: """
A module to decode HTML into a tree,
porting all properties of the underlying
library myhtml, being fast and correct
in regards to the html spec.
Originally based on Myhtmlex.
""",
docs: docs()
]
end
def package do
[
maintainers: ["Ariadne Conill"],
licenses: ["GNU LGPL"],
links: %{
"GitLab" => "https://git.pleroma.social/pleroma/fast_html",
"Issues" => "https://git.pleroma.social/pleroma/fast_html/issues",
"MyHTML" => "https://github.com/lexborisov/myhtml"
},
files: [
"lib",
"c_src",
"priv/.gitignore",
"test",
"Makefile",
"mix.exs",
"README.md",
"LICENSE"
]
]
end
def application do
[
extra_applications: [:logger],
- mod: {Myhtmlex.Safe, []},
+ mod: {FastHtml.Application, []},
# used to detect conflicts with other applications named processes
- registered: [Myhtmlex.Safe.Cnode, Myhtmlex.Safe.Supervisor],
- env: [
- mode: Myhtmlex.Safe
- ]
+ registered: [FastHtml.Cnode, FastHtml.Supervisor]
]
end
defp deps do
[
# documentation helpers
{:ex_doc, ">= 0.0.0", only: :dev},
# benchmarking helpers
{:benchee, "~> 1.0", only: :dev},
# cnode helpers
{:nodex,
git: "https://git.pleroma.social/pleroma/nodex",
ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"}
]
end
defp docs do
[
main: "FastHTML"
]
end
end
defmodule Mix.Tasks.Compile.FastHtmlCnodeMake do
@artifacts [
"priv/myhtml_worker"
]
def find_make do
_make_cmd =
System.get_env("MAKE") ||
case :os.type() do
{:unix, :freebsd} -> "gmake"
{:unix, :openbsd} -> "gmake"
{:unix, :netbsd} -> "gmake"
{:unix, :dragonfly} -> "gmake"
_ -> "make"
end
end
defp otp_version do
:erlang.system_info(:otp_release)
|> to_string()
|> String.to_integer()
end
defp otp_22_or_newer? do
otp_version() >= 22
end
def run(_) do
make_cmd = find_make()
exit_code =
if match?({:win32, _}, :os.type()) do
IO.warn("Windows is not yet a target.")
1
else
{result, exit_code} =
System.cmd(
make_cmd,
@artifacts,
stderr_to_stdout: true,
env: [
{"MIX_ENV", to_string(Mix.env())},
{"OTP22_DEF", (otp_22_or_newer?() && "YES") || "NO"}
]
)
IO.binwrite(result)
exit_code
end
if exit_code == 0 do
:ok
else
{:error,
[
%Mix.Task.Compiler.Diagnostic{
compiler_name: "FastHTML Cnode",
message: "Make exited with #{exit_code}",
severity: :error,
file: nil,
position: nil
}
]}
end
end
def clean() do
make_cmd = find_make()
{result, _error_code} = System.cmd(make_cmd, ["clean"], stderr_to_stdout: true)
Mix.shell().info(result)
:ok
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Oct 29, 4:14 AM (4 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1797522
Default Alt Text
(9 KB)
Attached To
Mode
R16 fast_html
Attached
Detach File
Event Timeline