Skip to content

Commit e74d96c

Browse files
maxbrunsfeldAshi Krishan
and
Ashi Krishan
committed
Initial commit
Co-Authored-By: Ashi Krishan <[email protected]>
0 parents  commit e74d96c

14 files changed

+2033
-0
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/src/** linguist-vendored

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
build
3+
*.log

.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
corpus
2+
build
3+
script

.travis.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: node_js
2+
sudo: false
3+
node_js:
4+
- "node"
5+
compiler: clang-3.6
6+
env:
7+
- CXX=clang-3.6
8+
addons:
9+
apt:
10+
sources:
11+
- llvm-toolchain-precise-3.6
12+
- ubuntu-toolchain-r-test
13+
packages:
14+
- clang-3.6

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 Max Brunsfeld
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

binding.gyp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"targets": [
3+
{
4+
"target_name": "tree_sitter_html_binding",
5+
"include_dirs": [
6+
"<!(node -e \"require('nan')\")",
7+
"src"
8+
],
9+
"sources": [
10+
"src/parser.c",
11+
"src/binding.cc"
12+
],
13+
"cflags_c": [
14+
"-std=c99",
15+
]
16+
}
17+
]
18+
}

corpus/main.txt

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
===================================
2+
Tags
3+
===================================
4+
<span>Hello</span>
5+
---
6+
7+
(fragment
8+
(element
9+
(start_tag (tag_name))
10+
(text)
11+
(end_tag (tag_name))))
12+
13+
===================================
14+
Tags with attributes
15+
===================================
16+
<input value=yes class="a" data-💩></input>
17+
---
18+
19+
(fragment
20+
(void_element
21+
(void_start_tag
22+
(void_tag_name)
23+
(attribute
24+
(attribute_name)
25+
(attribute_value))
26+
(attribute
27+
(attribute_name)
28+
(quoted_attribute_value (attribute_value)))
29+
(attribute
30+
(attribute_name)))
31+
(end_tag (tag_name))))
32+
33+
===================================
34+
Nested tags
35+
===================================
36+
<div>
37+
<span>a</span>
38+
b
39+
<b>c</b>
40+
</div>
41+
---
42+
43+
(fragment
44+
(element
45+
(start_tag (tag_name))
46+
(text)
47+
(element
48+
(start_tag (tag_name))
49+
(text)
50+
(end_tag (tag_name)))
51+
(text)
52+
(element
53+
(start_tag (tag_name))
54+
(text)
55+
(end_tag (tag_name)))
56+
(text)
57+
(end_tag (tag_name))))
58+
59+
==================================
60+
Void tags
61+
==================================
62+
<form><img src="somethign.png"><br><input type=submit value=Ok /></form>
63+
---
64+
65+
(fragment
66+
(element
67+
(start_tag (tag_name))
68+
(void_element
69+
(void_start_tag
70+
(tag_name)
71+
(attribute (attribute_name) (quoted_attribute_value (attribute_value)))))
72+
(void_element (void_start_tag (tag_name)))
73+
(void_element
74+
(self_closing_tag
75+
(tag_name)
76+
(attribute (attribute_name) (attribute_value))
77+
(attribute (attribute_name) (attribute_value))))
78+
(end_tag (tag_name))))

grammar.js

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
const startTag = ($, tag) => seq(
2+
'<',
3+
alias(tag, $.tag_name),
4+
repeat($.attribute),
5+
'>'
6+
)
7+
8+
module.exports = grammar({
9+
name: 'html',
10+
11+
externals: $ => [
12+
$.tag_name,
13+
14+
],
15+
16+
rules: {
17+
fragment: $ => repeat($._node),
18+
19+
_node: $ => choice(
20+
$.text,
21+
$.element,
22+
$.void_element
23+
),
24+
25+
element: $ => seq(
26+
$.start_tag,
27+
repeat($._node),
28+
$.end_tag
29+
),
30+
31+
void_element: $ => choice(
32+
seq($.void_start_tag, optional($.end_tag)),
33+
$.self_closing_tag
34+
),
35+
36+
start_tag: $ => startTag($, $.tag_name),
37+
38+
void_start_tag: $ => startTag($, $.void_tag_name),
39+
40+
self_closing_tag: $ => seq(
41+
'<',
42+
choice($.tag_name, $.void_tag_name),
43+
repeat($.attribute),
44+
'/',
45+
'>'
46+
),
47+
48+
attribute: $ => seq(
49+
alias($._attribute_part, $.attribute_name),
50+
optional(seq(
51+
'=',
52+
choice(
53+
alias($._attribute_part, $.attribute_value),
54+
$.quoted_attribute_value
55+
)
56+
))
57+
),
58+
59+
_attribute_part: $ => /[^<>"'/=\s]+/,
60+
61+
quoted_attribute_value: $ => choice(
62+
seq("'", optional(alias(/[^']+/, $.attribute_value)), "'"),
63+
seq('"', optional(alias(/[^"]+/, $.attribute_value)), '"')
64+
),
65+
66+
end_tag: $ => seq(
67+
'</',
68+
choice($.tag_name, $.void_tag_name),
69+
'>'
70+
),
71+
72+
tag_name: $ => /[a-zA-Z\-]+/,
73+
74+
void_tag_name: $ => token(prec(1, choice(
75+
'area',
76+
'base',
77+
'basefont',
78+
'bgsound',
79+
'br',
80+
'col',
81+
'command',
82+
'embed',
83+
'frame',
84+
'hr',
85+
'image',
86+
'img',
87+
'input',
88+
'isindex',
89+
'keygen',
90+
'link',
91+
'menuitem',
92+
'meta',
93+
'nextid',
94+
'param',
95+
'source',
96+
'track',
97+
'wbr'
98+
))),
99+
100+
text: $ => /[^<>]+/
101+
}
102+
});

index.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
try {
2+
module.exports = require("./build/Release/tree_sitter_html_binding");
3+
} catch (error) {
4+
try {
5+
module.exports = require("./build/Debug/tree_sitter_html_binding");
6+
} catch (_) {
7+
throw error
8+
}
9+
}

src/binding.cc

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "tree_sitter/parser.h"
2+
#include <node.h>
3+
#include "nan.h"
4+
5+
using namespace v8;
6+
7+
extern "C" TSLanguage * tree_sitter_html();
8+
9+
namespace {
10+
11+
NAN_METHOD(New) {}
12+
13+
void Init(Handle<Object> exports, Handle<Object> module) {
14+
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
15+
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
16+
tpl->InstanceTemplate()->SetInternalFieldCount(1);
17+
18+
Local<Function> constructor = tpl->GetFunction();
19+
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
20+
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_html());
21+
22+
instance->Set(Nan::New("name").ToLocalChecked(), Nan::New("html").ToLocalChecked());
23+
module->Set(Nan::New("exports").ToLocalChecked(), instance);
24+
}
25+
26+
NODE_MODULE(tree_sitter_html_binding, Init)
27+
28+
} // namespace

0 commit comments

Comments
 (0)