diff --git a/src/js/parser/javascript/regexp.js b/src/js/parser/javascript/regexp.js index d63b972..9e2223b 100644 --- a/src/js/parser/javascript/regexp.js +++ b/src/js/parser/javascript/regexp.js @@ -1,15 +1,20 @@ +// Regexp nodes are the entire regular expression. They consist of a collection +// of [Match](./match.html) nodes separated by `|`. + import util from '../../util.js'; import _ from 'lodash'; export default { type: 'regexp', + // Renders the regexp into the currently set container. _render() { var matchContainer = this.container.group() .addClass('regexp-matches') .transform(Snap.matrix() .translate(20, 0)); + // Renders each match into the match container. return Promise.all(_.map(this.matches, match => { return match.render(matchContainer.group()); })) @@ -17,22 +22,30 @@ export default { var containerBox, paths; + // Space matches vertically in the match container. util.spaceVertically(this.matches, { padding: 5 }); containerBox = this.getBBox(); + + // Creates the curves from the side lines for each match. paths = _.map(this.matches, match => { return this.makeCurve(containerBox, match) }); + // Add side lines to the list of paths. paths.push(this.makeSide(containerBox, _.first(this.matches))); paths.push(this.makeSide(containerBox, _.last(this.matches))); + // Render connector paths. this.container.prepend( this.container.path(_(paths).flatten().compact().values().join(''))); containerBox = matchContainer.getBBox(); + + // Create connections from side lines to each match and render into + // the match container. paths = _.map(this.matches, match => { return this.makeConnector(containerBox, match); }); @@ -41,10 +54,18 @@ export default { }); }, + // Returns an array of SVG path strings to draw the vertical lines on the + // left and right of the node. + // + // - __containerBox__ - Bounding box of the container. + // - __match__ - Match node that the line will be drawn to. makeSide(containerBox, match) { var box = match.getBBox(), distance = Math.abs(box.ay - containerBox.cy); + // Only need to draw side lines if the match is more than 15 pixels from + // the vertical center of the rendered regexp. Less that 15 pixels will be + // handled by the curve directly. if (distance >= 15) { let shift = (box.ay > containerBox.cy) ? 10 : -10, edge = box.ay - shift; @@ -56,11 +77,18 @@ export default { } }, + // Returns an array of SVG path strings to draw the curves from the + // sidelines up to the anchor of the match node. + // + // - __containerBox__ - Bounding box of the container. + // - __match__ - Match node that the line will be drawn to. makeCurve(containerBox, match) { var box = match.getBBox(), distance = Math.abs(box.ay - containerBox.cy); if (distance >= 15) { + // For match nodes more than 15 pixels from the center of the regexp, a + // quarter-circle curve is used to connect to the sideline. let curve = (box.ay > containerBox.cy) ? 10 : -10; return [ @@ -68,6 +96,8 @@ export default { `M${containerBox.width + 30},${box.ay - curve}q0,${curve} -10,${curve}` ]; } else { + // For match nodes less than 15 pixels from the center of the regexp, a + // slightly curved line is used to connect to the sideline. let anchor = box.ay - containerBox.cy; return [ @@ -77,6 +107,11 @@ export default { } }, + // Returns an array of SVG path strings to draw the connection from the + // curve to match node. + // + // - __containerBox__ - Bounding box of the container. + // - __match__ - Match node that the line will be drawn to. makeConnector(containerBox, match) { var box = match.getBBox(); @@ -85,8 +120,10 @@ export default { setup() { if (this.properties.alternates.elements.length === 0) { + // When there is only one match node to render, proxy to it. this.proxy = this.properties.match; } else { + // Merge all the match nodes into one array. this.matches = [this.properties.match] .concat(_.map(this.properties.alternates.elements, element => { return element.properties.match;