From 7d84669536ccea8ef3dc891c4ca11076cec796c6 Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Tue, 2 Dec 2014 21:02:48 -0500 Subject: [PATCH] First cut of rendering match elements This is currently broken, but a starting point for further work. --- src/js/main.js | 2 +- src/js/parser/javascript.js | 6 +++ src/js/parser/javascript/charset.js | 6 +++ src/js/parser/javascript/grammar.peg | 6 +-- src/js/parser/javascript/match.js | 72 ++++++++++++++++++++++++++++ src/js/parser/javascript/subexp.js | 6 +++ src/js/parser/javascript/terminal.js | 6 +++ 7 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/js/parser/javascript/charset.js create mode 100644 src/js/parser/javascript/subexp.js create mode 100644 src/js/parser/javascript/terminal.js diff --git a/src/js/main.js b/src/js/main.js index 3f4bcca..6c25f0e 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -3,7 +3,7 @@ import Snap from 'snapsvg'; // Testing code (function() { - var result = parser.parse('test expr|other expr|foo'), + var result = parser.parse('^test?(foo)[a-z]asdf$'), svg = Snap('#regexp-render svg'), container; diff --git a/src/js/parser/javascript.js b/src/js/parser/javascript.js index b61f939..969c8d4 100644 --- a/src/js/parser/javascript.js +++ b/src/js/parser/javascript.js @@ -3,9 +3,15 @@ import parser from './javascript/grammar.peg'; import Root from './javascript/root.js'; import Regexp from './javascript/regexp.js'; import Match from './javascript/match.js'; +import Subexp from './javascript/subexp.js'; +import Charset from './javascript/charset.js'; +import Terminal from './javascript/terminal.js'; parser.Parser.Root = Root; parser.Parser.Regexp = Regexp; parser.Parser.Match = Match; +parser.Parser.Subexp = Subexp; +parser.Parser.Charset = Charset; +parser.Parser.Terminal = Terminal; export default parser; diff --git a/src/js/parser/javascript/charset.js b/src/js/parser/javascript/charset.js new file mode 100644 index 0000000..bafe595 --- /dev/null +++ b/src/js/parser/javascript/charset.js @@ -0,0 +1,6 @@ +import _ from 'lodash'; +import Base from './base.js'; + +export default _.extend({}, Base, { + type: 'charset' +}); diff --git a/src/js/parser/javascript/grammar.peg b/src/js/parser/javascript/grammar.peg index f0eb426..b606839 100644 --- a/src/js/parser/javascript/grammar.peg +++ b/src/js/parser/javascript/grammar.peg @@ -15,11 +15,11 @@ grammar JavascriptRegexp / "{" [0-9]+ ",}" / "{" [0-9]+ "}" repeat_greedy <- "?" - subexp <- "(" ( subexp_no_capture / subexp_positive_lookahead / subexp_negative_lookahead )? regexp ")" + subexp <- "(" ( subexp_no_capture / subexp_positive_lookahead / subexp_negative_lookahead )? regexp ")" subexp_no_capture <- "?:" subexp_positive_lookahead <- "?=" subexp_negative_lookahead <- "?!" - charset <- "[" "^"? ( charset_range / charset_terminal )* "]" + charset <- "[" "^"? ( charset_range / charset_terminal )* "]" charset_range <- charset_terminal "-" charset_terminal charset_terminal <- charset_escape / charset_literal charset_escape <- ( backspace_esc @@ -41,7 +41,7 @@ grammar JavascriptRegexp / null_esc / literal_esc ) charset_literal <- [^\\\]] - terminal <- any_character / escape / literal + terminal <- any_character / escape / literal any_character <- "." escape <- ( word_boundary_esc / non_word_boundary_esc diff --git a/src/js/parser/javascript/match.js b/src/js/parser/javascript/match.js index 442de8f..62620ac 100644 --- a/src/js/parser/javascript/match.js +++ b/src/js/parser/javascript/match.js @@ -3,4 +3,76 @@ import Base from './base.js'; export default _.extend({}, Base, { type: 'match', + + render(container) { + console.log('anchor_start:', this.anchor_start()); + console.log('anchor_end:', this.anchor_end()); + console.log('parts:', this.parts()); + + this.contents = {}; + + if (this.anchor_start()) { + this.contents.anchor_start = this.render_label(container, 'Start of line'); + } + + this.contents.parts = _.map(this.parts(), function(part) { + var content = container.group(); + part.elements[0].render(content); + return { content, part }; + }); + + if (this.anchor_end()) { + this.contents.anchor_end = this.render_label(container, 'End of line'); + } + }, + + position() { + var offset = 0; + + if (this.anchor_start()) { + this.position_label(this.contents.anchor_start); + offset += this.contents.anchor_start.getBBox().width; + } + + _.each(this.contents.parts, function(thing) { + thing.part.elements[0].position(); + thing.content.transform(Snap.matrix() + .translate(offset, 0)); + offset += thing.content.getBBox().width; + }); + + if (this.anchor_end()) { + this.position_label(this.contents.anchor_end); + this.contents.anchor_end.transform(Snap.matrix() + .translate(offset, 0)); + } + }, + + anchor_start() { + return this._anchor_start.textValue !== ''; + }, + + anchor_end() { + return this._anchor_end.textValue !== ''; + }, + + parts() { + return _.reduce(this._parts.elements, function(result, node) { + var last = result.pop(); + + if (last) { + if (node.elements[0].type === 'terminal' && last.elements[0].type === 'terminal' && last.elements[1].textValue === '') { + last.textValue += node.textValue; + last.elements[0].textValue += node.elements[0].textValue; + last.elements[1] = node.elements[1]; + node = last; + } else { + result.push(last); + } + } + + result.push(_.clone(node, true)); + return result; + }, []); + } }); diff --git a/src/js/parser/javascript/subexp.js b/src/js/parser/javascript/subexp.js new file mode 100644 index 0000000..8e7a429 --- /dev/null +++ b/src/js/parser/javascript/subexp.js @@ -0,0 +1,6 @@ +import _ from 'lodash'; +import Base from './base.js'; + +export default _.extend({}, Base, { + type: 'subexp' +}); diff --git a/src/js/parser/javascript/terminal.js b/src/js/parser/javascript/terminal.js new file mode 100644 index 0000000..a9024a2 --- /dev/null +++ b/src/js/parser/javascript/terminal.js @@ -0,0 +1,6 @@ +import _ from 'lodash'; +import Base from './base.js'; + +export default _.extend({}, Base, { + type: 'terminal' +});