diff --git a/src/index.html b/src/index.html
index 4a45731..54aa1bd 100644
--- a/src/index.html
+++ b/src/index.html
@@ -64,7 +64,9 @@
fill: #cbcbba;
}
- .subexp .subexp-label, .charset .charset-label {
+ .subexp .subexp-label,
+ .charset .charset-label,
+ .match-fragment .repeat-label {
font-size: 10px;
}
diff --git a/src/js/parser/javascript/match_fragment.js b/src/js/parser/javascript/match_fragment.js
index b88d4da..f2b1329 100644
--- a/src/js/parser/javascript/match_fragment.js
+++ b/src/js/parser/javascript/match_fragment.js
@@ -35,6 +35,21 @@ export default _.extend({}, Base, {
this.container.prepend(
this.container.path(paths.join('')));
}
+ }).bind(this))
+ .then((() => {
+ var labelStr = this._repeat.label(),
+ label,
+ labelBox,
+ labelShift = (this._repeat.hasSkip() ? 5 : 0),
+ box = this.getBBox();
+
+ if (labelStr) {
+ label = this.container.text(0, 0, labelStr)
+ .addClass('repeat-label');
+ labelBox = label.getBBox();
+ label.transform(Snap.matrix()
+ .translate(box.x2 - labelBox.width - labelShift, box.y2 + labelBox.height));
+ }
}).bind(this));
}
},
diff --git a/src/js/parser/javascript/repeat.js b/src/js/parser/javascript/repeat.js
index 259f66c..961f168 100644
--- a/src/js/parser/javascript/repeat.js
+++ b/src/js/parser/javascript/repeat.js
@@ -32,5 +32,29 @@ export default {
}
return Snap.matrix().translate(x, y);
+ },
+
+ label() {
+ var maximum = this.maximum(),
+ minimum = this.minimum(),
+ formatTimes = times => {
+ if (times === 1) {
+ return 'once';
+ } else {
+ return times + ' times';
+ }
+ };
+
+ if (minimum >= 2 && maximum === -1) {
+ return (minimum - 1) + '+ times';
+ } else if (minimum <= 1 && maximum >= 2) {
+ return 'at most ' + formatTimes(maximum - 1);
+ } else if (minimum >= 2 && maximum >= 2) {
+ if (minimum === maximum) {
+ return formatTimes(minimum - 1);
+ } else {
+ return (minimum - 1) + '...' + formatTimes(maximum - 1);
+ }
+ }
}
}