Skip to content
This repository has been archived by the owner on Jan 26, 2023. It is now read-only.

Commit

Permalink
Feat: Enhance parser rules
Browse files Browse the repository at this point in the history
- Multi line pipe blocks support
- wrapped tags: div: div Foo
- inline JS (non Multiline)
- Added vue-attributes
- refac rules
  • Loading branch information
zealot128 committed Jul 13, 2021
1 parent 5cdbbac commit c068c0b
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 105 deletions.
122 changes: 70 additions & 52 deletions grammar.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,72 @@
module.exports = grammar({
name: 'pug',
externals: $ => [
$._newline,
$._indent,
$._dedent
],
name: "pug",
externals: ($) => [$._newline, $._indent, $._dedent],
rules: {
source_file: $ => repeat(choice($.comment, $.tag)),
tag: $ => seq(
choice($.tag_name, $.id, $.class),
optional(repeat(choice($.id, $.class))),
optional($.attributes),
optional(seq(' ', $.content)),
$._newline,
optional($.children),
),
attributes: $ => seq(
'(',
repeat(seq(
$.attribute,
choice(',', ' ')
)),
optional($.attribute),
')',
),
attribute: $ => seq(
$.attribute_name,
optional(seq(
'=',
$.quoted_attribute_value
))
),
children: $ => choice(
seq($._indent, repeat($.tag), $._dedent),
),
comment: $ => seq(
'//',
optional($._comment_content),
$._newline,
optional(seq($._indent, repeat(seq($._comment_content, $._newline)), $._dedent))
),
tag_name: $ => /\w(?:[-:\w]*\w)?/,
class: $ => /\.[_a-z0-9\-]*[_a-z][_a-z0-9\-]*/i,
id: $ => /#[\w-]+/,
attribute_name: $ => /[\w@\-:]+/,
quoted_attribute_value: $ => choice(
seq("'", optional(alias(/[^']+/, $.attribute_value)), "'"),
seq('"', optional(alias(/[^"]+/, $.attribute_value)), '"')
),
content: $ => /[^\n]+/,
_comment_content: $ => /[^ ][^\n]*/
}
})
source_file: ($) => repeat(choice($.comment, $.tag)),
pipe_content: ($) =>
seq(
"|",
optional($._content_or_javascript),
$._newline,
),
tag: ($) =>
seq(
choice($.tag_name, $.id, $.class),
optional(repeat1(choice($.id, $.class))),
optional($.attributes),
choice(
seq(":", $.tag),
seq(
optional(seq(" ", $._content_or_javascript)),
$._newline,
optional($.children)
)
)
),
attributes: ($) =>
seq(
"(",
repeat(seq($.attribute, choice(",", " "))),
optional($.attribute),
")"
),
attribute: ($) =>
seq(
$.attribute_name,
optional(repeat1(seq(
".",
alias(/[\w@\-:]+/, $.attribute_modifier)
))),
optional(seq("=", $.quoted_attribute_value))
),
children: $ => seq($._indent, repeat1($._children_choice), $._dedent),
_children_choice: ($) =>
choice(
$.pipe_content,
$.tag,
),
comment: ($) =>
seq(
"//",
optional($._comment_content),
$._newline,
optional(
seq($._indent, repeat(seq($._comment_content, $._newline)), $._dedent)
)
),
tag_name: ($) => /\w(?:[-:\w]*\w)?/,
class: ($) => /\.[_a-z0-9\-]*[_a-z][_a-z0-9\-]*/i,
id: ($) => /#[\w-]+/,
attribute_name: ($) => /[\w@\-:]+/,
quoted_attribute_value: ($) =>
choice(
seq("'", optional(alias(/[^']+/, $.attribute_value)), "'"),
seq('"', optional(alias(/[^"]+/, $.attribute_value)), '"')
),
javascript: ($) => /[^\n}]+/,
content: ($) => /[^\n\{]+/,
_content_or_javascript: ($) =>
repeat1(choice(seq("{{", $.javascript, "}}"), $.content)),
_comment_content: ($) => /[^ ][^\n]*/,
},
});
68 changes: 66 additions & 2 deletions src/node-types.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"multiple": true,
"required": true,
"types": [
{
"type": "attribute_modifier",
"named": true
},
{
"type": "attribute_name",
"named": true
Expand All @@ -18,6 +22,11 @@
]
}
},
{
"type": "attribute_name",
"named": true,
"fields": {}
},
{
"type": "attributes",
"named": true,
Expand All @@ -39,8 +48,12 @@
"fields": {},
"children": {
"multiple": true,
"required": false,
"required": true,
"types": [
{
"type": "pipe_content",
"named": true
},
{
"type": "tag",
"named": true
Expand All @@ -53,6 +66,25 @@
"named": true,
"fields": {}
},
{
"type": "pipe_content",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "content",
"named": true
},
{
"type": "javascript",
"named": true
}
]
}
},
{
"type": "quoted_attribute_value",
"named": true,
Expand Down Expand Up @@ -115,6 +147,14 @@
"type": "id",
"named": true
},
{
"type": "javascript",
"named": true
},
{
"type": "tag",
"named": true
},
{
"type": "tag_name",
"named": true
Expand Down Expand Up @@ -146,16 +186,24 @@
"type": ",",
"named": false
},
{
"type": ".",
"named": false
},
{
"type": "//",
"named": false
},
{
"type": ":",
"named": false
},
{
"type": "=",
"named": false
},
{
"type": "attribute_name",
"type": "attribute_modifier",
"named": true
},
{
Expand All @@ -174,8 +222,24 @@
"type": "id",
"named": true
},
{
"type": "javascript",
"named": true
},
{
"type": "tag_name",
"named": true
},
{
"type": "{{",
"named": false
},
{
"type": "|",
"named": false
},
{
"type": "}}",
"named": false
}
]
26 changes: 26 additions & 0 deletions test/corpus/comment.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
========================
Comment
========================

// Some comment that is

---

(source_file
(comment))


========================
Multiline comment
========================

// Some comment
with nested line that
are still commented

---

(source_file
(comment))


34 changes: 34 additions & 0 deletions test/corpus/complex.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
========================
Mixed example
========================

// some comment
some-tag.class-one(attr) the content
sub-tag.some-slass
sub-sub-tag content
other-subtag#with-id.and-class(and-attr)

---

(source_file
(comment)
(tag
(tag_name)
(class)
(attributes
(attribute (attribute_name)))
(content)
(children
(tag
(tag_name)
(class)
(children
(tag
(tag_name)
(content))))
(tag
(tag_name)
(id)
(class)
(attributes
(attribute (attribute_name)))))))
74 changes: 74 additions & 0 deletions test/corpus/pipe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
========================
Tag with piped content
=========================

div
|Content here

---

(source_file
(tag
(tag_name)
(children
(pipe_content (content)))))

========================
Tag with blank piped content + tag
=========================

div
|
| Content here
|
div

---

(source_file
(tag
(tag_name)
(children
(pipe_content)
(pipe_content (content))
(pipe_content)
(tag (tag_name))
)
))


========================
Tag with multi-line piped content
=========================

div
|Content here
|more
| content here,

---

(source_file
(tag
(tag_name)
(children
(pipe_content (content))
(pipe_content (content))
(pipe_content (content))
)))

========================
Content Javascript
=========================

div
|Content {{ some JS code here }} Content

---

(source_file
(tag
(tag_name)
(children
(pipe_content (content) (javascript) (content)))))

Loading

0 comments on commit c068c0b

Please sign in to comment.