Browse files

resolve conflicts with head

  • Loading branch information...
2 parents 9c9d062 + a43a623 commit fe2ff118ff5244a855ba31904271aebf5ca73896 @tabatkins committed Nov 16, 2012
Showing with 58 additions and 42 deletions.
  1. +1 −2 README.md
  2. +28 −28 example.html
  3. +29 −12 railroad-diagrams.js
View
3 README.md
@@ -21,7 +21,7 @@ Its arguments are the components of the diagram (Diagram is a special form of Se
Components are either leaves or containers.
The leaves:
-* Terminal(text) - represents literal text
+* Terminal(text) or a bare string - represents literal text
* NonTerminal(text) - represents an instruction or another production
* Comment(text) - a comment
* Skip() - an empty line
@@ -59,4 +59,3 @@ Caveats
At this early stage, the generator is feature-complete and works as intended, but still has several TODOs:
* The font-sizes are hard-coded right now, and the font handling in general is very dumb - I'm just guessing at some metrics that are probably "good enough" rather than measuring things properly.
-* I'd like to allow plain strings as children, and automatically upgrade them into Terminal objects.
View
56 example.html
@@ -14,49 +14,49 @@
<h1 id='ident'>IDENT</h1>
<script>
Diagram(
- Choice(0, Skip(), Terminal('-')),
+ Choice(0, Skip(), '-'),
Choice(0, NonTerminal('name-start char'), NonTerminal('escape')),
ZeroOrMore(
Choice(0, NonTerminal('name char'), NonTerminal('escape')))).addTo();
</script>
<h1 id='function'>FUNCTION</h1>
<script>
-Diagram(NonTerminal('IDENT'), Terminal('(')).addTo();
+Diagram(NonTerminal('IDENT'), '(').addTo();
</script>
<h1 id='at-keyword'>AT-KEYWORD</h1>
<script>
-Diagram(Terminal('@'), NonTerminal('IDENT')).addTo();
+Diagram('@', NonTerminal('IDENT')).addTo();
</script>
<h1 id='hash'>HASH</h1>
<script>
-Diagram(Terminal('#'), NonTerminal('IDENT')).addTo();
+Diagram('#', NonTerminal('IDENT')).addTo();
</script>
<h1 id='string'>STRING</h1>
<script>
Diagram(
Choice(0,
Sequence(
- Terminal('"'),
+ '"',
ZeroOrMore(
Choice(0,
NonTerminal('not " or \\'),
NonTerminal('escape'))),
- Terminal('"')),
+ '"'),
Sequence(
- Terminal("'"),
+ "'",
ZeroOrMore(
Choice(0,
NonTerminal("not ' or \\"),
NonTerminal('escape'))),
- Terminal("'")))).addTo();
+ "'"))).addTo();
</script>
<h1 id='url'>URL</h1>
<script>
Diagram(
- Choice(0, Terminal('u'), Terminal('U')),
- Choice(0, Terminal('r'), Terminal('R')),
- Choice(0, Terminal('l'), Terminal('L')),
- Terminal('('),
+ Choice(0, 'u', 'U'),
+ Choice(0, 'r', 'R'),
+ Choice(0, 'l', 'L'),
+ '(',
Choice(1,
Optional(NonTerminal('WS')),
Sequence(
@@ -70,26 +70,26 @@ <h1 id='url'>URL</h1>
NonTerminal('not " \' ( ) WS or NPC'),
NonTerminal('escape'))),
Optional(NonTerminal('WS')))),
- Terminal(')')).addTo();
+ ')').addTo();
</script>
<h1>NUMBER</h1>
<script>
Diagram(
- Choice(1, Terminal('+'), Skip(), Terminal('-')),
+ Choice(1, '+', Skip(), '-'),
Choice(0,
Sequence(
OneOrMore(NonTerminal('digit')),
- Terminal('.'),
+ '.',
OneOrMore(NonTerminal('digit'))),
OneOrMore(NonTerminal('digit')),
Sequence(
- Terminal('.'),
+ '.',
OneOrMore(NonTerminal('digit')))),
Choice(0,
Skip(),
Sequence(
- Choice(0, Terminal('e'), Terminal('E')),
- Choice(1, Terminal('+'), Skip(), Terminal('-')),
+ Choice(0, 'e', 'E'),
+ Choice(1, '+', Skip(), '-'),
OneOrMore(NonTerminal('digit'))))).addTo();
</script>
<h1>DIMENSION</h1>
@@ -98,38 +98,38 @@ <h1 id='url'>URL</h1>
</script>
<h1>PERCENTAGE</h1>
<script>
-Diagram(NonTerminal('NUMBER'), Terminal('%')).addTo();
+Diagram(NonTerminal('NUMBER'), '%').addTo();
</script>
<h1>UNICODE-RANGE</h1>
<script>
Diagram(
Choice(0,
- Terminal('U'),
- Terminal('u')),
- Terminal('+'),
+ 'U',
+ 'u'),
+ '+',
Choice(0,
Sequence(OneOrMore(NonTerminal('hex digit'), Comment('1-6 times'))),
Sequence(
ZeroOrMore(NonTerminal('hex digit'), Comment('1-5 times')),
- OneOrMore(Terminal('?'), Comment('1 to (6 - digits) times'))),
+ OneOrMore('?', Comment('1 to (6 - digits) times'))),
Sequence(
OneOrMore(NonTerminal('hex digit'), Comment('1-6 times')),
- Terminal('-'),
+ '-',
OneOrMore(NonTerminal('hex digit'), Comment('1-6 times'))))).addTo();
</script>
<h1>COMMENT</h1>
<script>
Diagram(
- Terminal('/*'),
+ '/*',
ZeroOrMore(
NonTerminal("anything but * followed by /")),
- Terminal('*/')).addTo();
+ '*/').addTo();
</script>
<h1>CDO</h1>
<script>
-Diagram(Terminal("<" + "!--")).addTo();
+Diagram("<" + "!--").addTo();
</script>
<h1>CDC</h1>
<script>
-Diagram(Terminal("-->")).addTo();
+Diagram("-->").addTo();
</script>
View
41 railroad-diagrams.js
@@ -113,15 +113,20 @@ function unnull(/* children */) {
return [].slice.call(arguments).reduce(function(sofar, x) { return sofar !== undefined ? sofar : x; });
}
+function wrapString(value) {
+ return ((typeof value) == 'string') ? new Terminal(value) : value;
+}
+
function Diagram(items) {
if(!(this instanceof Diagram)) return new Diagram([].slice.call(arguments));
FakeSVG.call(this, 'svg', {class: DIAGRAM_CLASS});
- this.items = items;
+ this.items = items.map(wrapString);
this.items.unshift(new Start);
this.items.push(new End);
this.width = this.items.reduce(function(sofar, el) { return sofar + el.width + (el.needsSpace?20:0)}, 0)+1;
this.up = this.items.reduce(function(sofar,el) { return Math.max(sofar, el.up)}, 0);
this.down = this.items.reduce(function(sofar,el) { return Math.max(sofar, el.down)}, 0);
+ this.formatted = false;
}
Diagram.prototype = Object.create(FakeSVG.prototype);
Diagram.prototype.format = function(paddingt, paddingr, paddingb, paddingl) {
@@ -149,25 +154,37 @@ Diagram.prototype.format = function(paddingt, paddingr, paddingb, paddingl) {
this.attrs.width = this.width + paddingl + paddingr;
this.attrs.height = this.up + this.down + paddingt + paddingb;
g.addTo(this);
+ this.formatted = true;
return this;
}
Diagram.prototype.addTo = function(parent) {
parent = parent || document.body;
FakeSVG.prototype.addTo.call(this, parent);
}
+Diagram.prototype.toSVG = function() {
+ if (!this.formatted) {
+ this.format();
+ }
+ return FakeSVG.prototype.toSVG.call(this);
+}
+Diagram.prototype.toString = function() {
+ if (!this.formatted) {
+ this.format();
+ }
+ FakeSVG.prototype.toString.call(this);
+}
function Sequence(items) {
if(!(this instanceof Sequence)) return new Sequence([].slice.call(arguments));
FakeSVG.call(this, 'g');
- this.items = items;
+ this.items = items.map(wrapString);
this.width = this.items.reduce(function(sofar, el) { return sofar + el.width + (el.needsSpace?20:0)}, 0);
this.up = this.items.reduce(function(sofar,el) { return Math.max(sofar, el.up)}, 0);
this.down = this.items.reduce(function(sofar,el) { return Math.max(sofar, el.down)}, 0);
}
Sequence.prototype = Object.create(FakeSVG.prototype);
Sequence.prototype.format = function(x,y,width) {
var diff = width - this.width;
- var g = SVG('g');
Path(x,y).h(diff/2).addTo(this);
x += diff/2;
for(var i = 0; i < this.items.length; i++) {
@@ -184,18 +201,18 @@ Sequence.prototype.format = function(x,y,width) {
}
}
Path(x,y).h(diff/2).addTo(this);
- return g;
+ return this;
}
function Choice(normal, items) {
if(!(this instanceof Choice)) return new Choice(normal, [].slice.call(arguments,1));
FakeSVG.call(this, 'g');
this.normal = normal;
- this.items = items;
+ this.items = items.map(wrapString);
this.width = this.items.reduce(function(sofar, el){return Math.max(sofar, el.width)},0) + ARC_RADIUS*4;
this.up = this.down = 0;
- for(var i = 0; i < items.length; i++) {
- var item = items[i];
+ for(var i = 0; i < this.items.length; i++) {
+ var item = this.items[i];
if(i < normal) { this.up += Math.max(ARC_RADIUS,item.up + item.down + VERTICAL_SEPARATION); }
if(i == normal) { this.up += Math.max(ARC_RADIUS, item.up); this.down += Math.max(ARC_RADIUS, item.down); }
if(i > normal) { this.down += Math.max(ARC_RADIUS,VERTICAL_SEPARATION + item.up + item.down); }
@@ -252,11 +269,11 @@ function OneOrMore(item, rep) {
if(!(this instanceof OneOrMore)) return new OneOrMore(item, rep);
FakeSVG.call(this, 'g');
rep = rep || (new Skip);
- this.item = item;
- this.rep = rep;
- this.width = Math.max(item.width, rep.width) + ARC_RADIUS*2;
- this.up = item.up;
- this.down = Math.max(ARC_RADIUS*2, item.down + VERTICAL_SEPARATION + rep.up + rep.down);
+ this.item = wrapString(item);
+ this.rep = wrapString(rep);
+ this.width = Math.max(this.item.width, this.rep.width) + ARC_RADIUS*2;
+ this.up = this.item.up;
+ this.down = Math.max(ARC_RADIUS*2, this.item.down + VERTICAL_SEPARATION + this.rep.up + this.rep.down);
}
OneOrMore.prototype = Object.create(FakeSVG.prototype);
OneOrMore.prototype.needsSpace = true;

0 comments on commit fe2ff11

Please sign in to comment.