diff --git a/src/index.html b/src/index.html
index b89817c..d46f663 100644
--- a/src/index.html
+++ b/src/index.html
@@ -60,6 +60,10 @@
fill: #dae9e5;
}
+ .charset .charset-box {
+ fill: #cbcbba;
+ }
+
.placeholder text {
fill: #fff;
font-weight: bold;
diff --git a/src/js/parser/javascript.js b/src/js/parser/javascript.js
index 1ca0c4a..7679bb2 100644
--- a/src/js/parser/javascript.js
+++ b/src/js/parser/javascript.js
@@ -6,6 +6,9 @@ import Match from './javascript/match.js';
import MatchFragment from './javascript/match_fragment.js';
import Subexp from './javascript/subexp.js';
import Charset from './javascript/charset.js';
+import CharsetLiteral from './javascript/charset_literal.js';
+import CharsetEscape from './javascript/charset_escape.js';
+import CharsetRange from './javascript/charset_range.js';
import Literal from './javascript/literal.js';
import Escape from './javascript/escape.js';
import AnyCharacter from './javascript/any_character.js';
@@ -21,6 +24,9 @@ parser.Parser.Match = Match;
parser.Parser.MatchFragment = MatchFragment;
parser.Parser.Subexp = Subexp;
parser.Parser.Charset = Charset;
+parser.Parser.CharsetLiteral = CharsetLiteral;
+parser.Parser.CharsetEscape = CharsetEscape;
+parser.Parser.CharsetRange = CharsetRange;
parser.Parser.Literal = Literal;
parser.Parser.Escape = Escape;
parser.Parser.AnyCharacter = AnyCharacter;
diff --git a/src/js/parser/javascript/charset.js b/src/js/parser/javascript/charset.js
index bafe595..b0661ff 100644
--- a/src/js/parser/javascript/charset.js
+++ b/src/js/parser/javascript/charset.js
@@ -2,5 +2,69 @@ import _ from 'lodash';
import Base from './base.js';
export default _.extend({}, Base, {
- type: 'charset'
+ type: 'charset',
+
+ render() {
+ this.container.addClass('charset');
+
+ this.label = this.container.text()
+ .attr({
+ text: this.invert() ? 'None of:' : 'One of:'
+ })
+ .transform(Snap.matrix()
+ .translate(0, 0));
+
+ this.box = this.container.rect()
+ .addClass('charset-box')
+ .attr({
+ rx: 3,
+ ry: 3
+ });
+
+ this.partContainer = this.container.group();
+
+ _.each(this.parts.elements, ((part) => {
+ part.container = this.partContainer.group();
+ part.render();
+ }).bind(this));
+ },
+
+ position() {
+ var box, offset = 0;
+
+ _.each(this.parts.elements, ((part) => {
+ var box;
+
+ part.position();
+
+ part.container.transform(Snap.matrix()
+ .translate(0, offset));
+
+ box = part.container.getBBox();
+
+ offset += box.height + 5;
+ }).bind(this));
+
+ box = this.partContainer.getBBox();
+
+ _.each(this.parts.elements, ((part) => {
+ var partBox = part.container.getBBox();
+
+ part.container.transform(Snap.matrix()
+ .add(part.container.transform().localMatrix)
+ .translate(box.cx - partBox.cx, 0));
+ }).bind(this));
+
+ this.box.attr({
+ width: box.width + 10,
+ height: box.height + 10
+ });
+
+ this.partContainer.transform(Snap.matrix()
+ .translate(5, 5));
+ },
+
+ invert() {
+ return this._invert.textValue !== '';
+ }
});
diff --git a/src/js/parser/javascript/charset_escape.js b/src/js/parser/javascript/charset_escape.js
new file mode 100644
index 0000000..331f678
--- /dev/null
+++ b/src/js/parser/javascript/charset_escape.js
@@ -0,0 +1,10 @@
+import _ from 'lodash';
+import Escape from './escape.js';
+
+export default _.extend({}, Escape, {
+ type: 'charset_escape',
+
+ codeMap: _.extend({}, Escape.codeMap, {
+ b: 'backspace'
+ })
+});
diff --git a/src/js/parser/javascript/charset_literal.js b/src/js/parser/javascript/charset_literal.js
new file mode 100644
index 0000000..a418d1b
--- /dev/null
+++ b/src/js/parser/javascript/charset_literal.js
@@ -0,0 +1,6 @@
+import _ from 'lodash';
+import Literal from './literal.js';
+
+export default _.extend({}, Literal, {
+ type: 'literal'
+});
diff --git a/src/js/parser/javascript/charset_range.js b/src/js/parser/javascript/charset_range.js
new file mode 100644
index 0000000..160983c
--- /dev/null
+++ b/src/js/parser/javascript/charset_range.js
@@ -0,0 +1,6 @@
+import _ from 'lodash';
+import Base from './base.js';
+
+export default _.extend({}, Base, {
+ type: 'charset_range'
+});
diff --git a/src/js/parser/javascript/grammar.peg b/src/js/parser/javascript/grammar.peg
index 1646db6..490d844 100644
--- a/src/js/parser/javascript/grammar.peg
+++ b/src/js/parser/javascript/grammar.peg
@@ -20,15 +20,16 @@ grammar JavascriptRegexp
subexp_no_capture <- "?:"
subexp_positive_lookahead <- "?="
subexp_negative_lookahead <- "?!"
- charset <- "[" "^"? ( charset_range / charset_terminal )* "]"
- charset_range <- charset_terminal "-" charset_terminal
- charset_terminal <- charset_escape / charset_literal
+ charset <- "[" _invert:"^"? parts:( charset_range / charset_terminal )* "]"
+ charset_range <- first:charset_terminal "-" last:charset_terminal
+ charset_terminal <- charset_escape
+ / charset_literal
charset_escape <- "\\" esc:(
code:[bdDfnrsStvwW] arg:""?
/ code:"0" arg:[0-7]+
/ code:"x" arg:( [0-9a-fA-F] [0-9a-fA-F] )
/ code:"u" arg:( [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] ) )
- charset_literal <- [^\\\]] / ( "\\" . )
+ charset_literal <- ( ""? literal:[^\\\]] ) / ( "\\" literal:. )
terminal <- any_character
/ escape
/ literal
diff --git a/src/js/parser/javascript/match_fragment.js b/src/js/parser/javascript/match_fragment.js
index d1d01d9..0b19f3a 100644
--- a/src/js/parser/javascript/match_fragment.js
+++ b/src/js/parser/javascript/match_fragment.js
@@ -44,6 +44,6 @@ export default _.extend({}, Base, {
.translate(0, 0));
}
- this.render_bbox(this.container, this.container.getBBox());
+ //this.render_bbox(this.container, this.container.getBBox());
}
});