Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
13 KB
Referenced Files
None
Subscribers
None
diff --git a/Makefile b/Makefile
index ac1d0f7..e7d221f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,102 +1,102 @@
MIX = mix
-MYHTMLEX_CFLAGS = -g -O2 -std=c99 -pedantic -Wcomment -Wextra -Wno-old-style-declaration -Wall
+MYHTML_WORKER_CFLAGS = -g -O2 -std=c99 -pedantic -Wcomment -Wextra -Wno-old-style-declaration -Wall
# we need to compile position independent code
-MYHTMLEX_CFLAGS += -fpic -DPIC
+MYHTML_WORKER_CFLAGS += -fpic -DPIC
# For some reason __erl_errno is undefined unless _REENTRANT is defined
-MYHTMLEX_CFLAGS += -D_REENTRANT
+MYHTML_WORKER_CFLAGS += -D_REENTRANT
# myhtmlex is using stpcpy, as defined in gnu string.h
-# MYHTMLEX_CFLAGS += -D_GNU_SOURCE
+# MYHTML_WORKER_CFLAGS += -D_GNU_SOURCE
# base on the same posix c source as myhtml
-# MYHTMLEX_CFLAGS += -D_POSIX_C_SOURCE=199309
+# MYHTML_WORKER_CFLAGS += -D_POSIX_C_SOURCE=199309
# turn warnings into errors
-# MYHTMLEX_CFLAGS += -Werror
+# MYHTML_WORKER_CFLAGS += -Werror
# ignore unused variables
-# MYHTMLEX_CFLAGS += -Wno-unused-variable
+# MYHTML_WORKER_CFLAGS += -Wno-unused-variable
# ignore unused parameter warnings
-MYHTMLEX_CFLAGS += -Wno-unused-parameter
+MYHTML_WORKER_CFLAGS += -Wno-unused-parameter
# set erlang include path
ERLANG_PATH = $(shell erl -eval 'io:format("~s", [lists:concat([code:root_dir(), "/erts-", erlang:system_info(version)])])' -s init stop -noshell)
-MYHTMLEX_CFLAGS += -I$(ERLANG_PATH)/include
+MYHTML_WORKER_CFLAGS += -I$(ERLANG_PATH)/include
# expecting myhtml as a submodule in c_src/
# that way we can pin a version and package the whole thing in hex
# hex does not allow for non-app related dependencies.
MYHTML_PATH = c_src/myhtml
MYHTML_STATIC = $(MYHTML_PATH)/lib/libmyhtml_static.a
-MYHTMLEX_CFLAGS += -I$(MYHTML_PATH)/include
+MYHTML_WORKER_CFLAGS += -I$(MYHTML_PATH)/include
# avoid undefined reference errors to phtread_mutex_trylock
-MYHTMLEX_CFLAGS += -lpthread
+MYHTML_WORKER_CFLAGS += -lpthread
# that would be used for a dynamically linked build
-# MYHTMLEX_CFLAGS += -L$(MYHTML_PATH)/lib
+# MYHTML_WORKER_CFLAGS += -L$(MYHTML_PATH)/lib
-MYHTMLEX_LDFLAGS = -shared
+MYHTML_WORKER_LDFLAGS = -shared
# C-Node
ERL_INTERFACE = $(wildcard $(ERLANG_PATH)/../lib/erl_interface-*)
-CNODE_CFLAGS = $(MYHTMLEX_CFLAGS)
+CNODE_CFLAGS = $(MYHTML_WORKER_CFLAGS)
CNODE_CFLAGS += -L$(ERL_INTERFACE)/lib
CNODE_CFLAGS += -I$(ERL_INTERFACE)/include
CNODE_LDFLAGS =
ifeq ($(OTP22_DEF),YES)
CNODE_CFLAGS += -DOTP_22_OR_NEWER
else
CNODE_LDFLAGS += -lerl_interface
endif
CNODE_LDFLAGS += -lei -pthread
# enumerate docker build tests
BUILD_TESTS := $(patsubst %.dockerfile, %.dockerfile.PHONY, $(wildcard ./build-test/*.dockerfile))
# platform specific environment
UNAME = $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
- MYHTMLEX_LDFLAGS += -dynamiclib -undefined dynamic_lookup
+ MYHTML_WORKER_LDFLAGS += -dynamiclib -undefined dynamic_lookup
else
# myhtmlex is using stpcpy, as defined in gnu string.h
- MYHTMLEX_CFLAGS += -D_GNU_SOURCE
+ MYHTML_WORKER_CFLAGS += -D_GNU_SOURCE
# base on the same posix c source as myhtml
- # MYHTMLEX_CFLAGS += -D_POSIX_C_SOURCE=199309
+ # MYHTML_WORKER_CFLAGS += -D_POSIX_C_SOURCE=199309
endif
.PHONY: all
all: myhtmlex
myhtmlex: priv/myhtml_worker
$(MIX) compile
$(MYHTML_STATIC): $(MYHTML_PATH)
$(MAKE) -C $(MYHTML_PATH) library MyCORE_BUILD_WITHOUT_THREADS=YES
priv/myhtml_worker: c_src/myhtml_worker.c $(MYHTML_STATIC)
$(CC) -o $@ $< $(MYHTML_STATIC) $(CNODE_CFLAGS) $(CNODE_LDFLAGS)
clean: clean-myhtml
$(RM) -r priv/myhtmlex*
$(RM) priv/myhtml_worker
$(RM) myhtmlex-*.tar
$(RM) -r package-test
clean-myhtml:
$(MAKE) -C $(MYHTML_PATH) clean
# publishing the package and docs separately is required
# otherwise the build artifacts are included in the package
# and the tarball gets too big to be published
publish: clean
$(MIX) hex.publish package
$(MIX) hex.publish docs
test:
$(MIX) test
build-tests: test $(BUILD_TESTS)
%.dockerfile.PHONY: %.dockerfile
docker build -f $< .
diff --git a/lib/myhtmlex.ex b/lib/fast_html.ex
similarity index 83%
rename from lib/myhtmlex.ex
rename to lib/fast_html.ex
index 1114010..8cb824a 100644
--- a/lib/myhtmlex.ex
+++ b/lib/fast_html.ex
@@ -1,101 +1,101 @@
-defmodule Myhtmlex do
+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> Myhtmlex.decode("<h1>Hello world</h1>")
+ 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> Myhtmlex.decode("<h1>Hello world</h1>")
+ iex> :fast_html.decode("<h1>Hello world</h1>")
{"html", [], [{"head", [], []}, {"body", [], [{"h1", [], ["Hello world"]}]}]}
- iex> Myhtmlex.decode("<span class='hello'>Hi there</span>")
+ iex> :fast_html.decode("<span class='hello'>Hi there</span>")
{"html", [],
[{"head", [], []},
{"body", [], [{"span", [{"class", "hello"}], ["Hi there"]}]}]}
- iex> Myhtmlex.decode("<body><!-- a comment --!></body>")
+ iex> :fast_html.decode("<body><!-- a comment --!></body>")
{"html", [], [{"head", [], []}, {"body", [], [comment: " a comment "]}]}
- iex> Myhtmlex.decode("<br>")
+ 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> Myhtmlex.decode("<h1>Hello world</h1>", format: [:html_atoms])
+ iex> :fast_html.decode("<h1>Hello world</h1>", format: [:html_atoms])
{:html, [], [{:head, [], []}, {:body, [], [{:h1, [], ["Hello world"]}]}]}
- iex> Myhtmlex.decode("<br>", format: [:nil_self_closing])
+ iex> :fast_html.decode("<br>", format: [:nil_self_closing])
{"html", [], [{"head", [], []}, {"body", [], [{"br", [], nil}]}]}
- iex> Myhtmlex.decode("<body><!-- a comment --!></body>", format: [:comment_tuple3])
+ 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> Myhtmlex.decode(html, format: [:html_atoms, :nil_self_closing, :comment_tuple3])
+ 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)
end
end
diff --git a/test/myhtmlex.safe_test.exs b/test/fast_html_test.exs
similarity index 72%
rename from test/myhtmlex.safe_test.exs
rename to test/fast_html_test.exs
index 122cd9a..304edd0 100644
--- a/test/myhtmlex.safe_test.exs
+++ b/test/fast_html_test.exs
@@ -1,140 +1,140 @@
-defmodule Myhtmlex.SafeTest do
+defmodule :fast_html_test do
use ExUnit.Case
- doctest Myhtmlex
+ doctest :fast_html
test "doesn't segfault when <!----> is encountered" do
- assert {"html", _attrs, _children} = Myhtmlex.decode("<div> <!----> </div>")
+ assert {"html", _attrs, _children} = :fast_html.decode("<div> <!----> </div>")
end
test "builds a tree, formatted like mochiweb by default" do
assert {"html", [],
[
{"head", [], []},
{"body", [],
[
{"br", [], []}
]}
- ]} = Myhtmlex.decode("<br>")
+ ]} = :fast_html.decode("<br>")
end
test "builds a tree, html tags as atoms" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{:br, [], []}
]}
- ]} = Myhtmlex.decode("<br>", format: [:html_atoms])
+ ]} = :fast_html.decode("<br>", format: [:html_atoms])
end
test "builds a tree, nil self closing" do
assert {"html", [],
[
{"head", [], []},
{"body", [],
[
{"br", [], nil},
{"esi:include", [], nil}
]}
- ]} = Myhtmlex.decode("<br><esi:include />", format: [:nil_self_closing])
+ ]} = :fast_html.decode("<br><esi:include />", format: [:nil_self_closing])
end
test "builds a tree, multiple format options" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{:br, [], nil}
]}
- ]} = Myhtmlex.decode("<br>", format: [:html_atoms, :nil_self_closing])
+ ]} = :fast_html.decode("<br>", format: [:html_atoms, :nil_self_closing])
end
test "attributes" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{:span, [{"id", "test"}, {"class", "foo garble"}], []}
]}
]} =
- Myhtmlex.decode(~s'<span id="test" class="foo garble"></span>',
+ :fast_html.decode(~s'<span id="test" class="foo garble"></span>',
format: [:html_atoms]
)
end
test "single attributes" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{:button, [{"disabled", "disabled"}, {"class", "foo garble"}], []}
]}
]} =
- Myhtmlex.decode(~s'<button disabled class="foo garble"></span>',
+ :fast_html.decode(~s'<button disabled class="foo garble"></span>',
format: [:html_atoms]
)
end
test "text nodes" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
"text node"
]}
- ]} = Myhtmlex.decode(~s'<body>text node</body>', format: [:html_atoms])
+ ]} = :fast_html.decode(~s'<body>text node</body>', format: [:html_atoms])
end
test "broken input" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{:a, [{"<", "<"}], [" asdf"]}
]}
- ]} = Myhtmlex.decode(~s'<a <> asdf', format: [:html_atoms])
+ ]} = :fast_html.decode(~s'<a <> asdf', format: [:html_atoms])
end
test "namespaced tags" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{"svg:svg", [],
[
{"svg:path", [], []},
{"svg:a", [], []}
]}
]}
- ]} = Myhtmlex.decode(~s'<svg><path></path><a></a></svg>', format: [:html_atoms])
+ ]} = :fast_html.decode(~s'<svg><path></path><a></a></svg>', format: [:html_atoms])
end
test "custom namespaced tags" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
{"esi:include", [], nil}
]}
- ]} = Myhtmlex.decode(~s'<esi:include />', format: [:html_atoms, :nil_self_closing])
+ ]} = :fast_html.decode(~s'<esi:include />', format: [:html_atoms, :nil_self_closing])
end
test "html comments" do
assert {:html, [],
[
{:head, [], []},
{:body, [],
[
comment: " a comment "
]}
- ]} = Myhtmlex.decode(~s'<body><!-- a comment --></body>', format: [:html_atoms])
+ ]} = :fast_html.decode(~s'<body><!-- a comment --></body>', format: [:html_atoms])
end
end

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 29, 5:42 AM (10 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1797605
Default Alt Text
(13 KB)

Event Timeline