diff --git a/editions/tw5.com/tiddlywiki.info b/editions/tw5.com/tiddlywiki.info index cf5dc2a3e..9340dba75 100644 --- a/editions/tw5.com/tiddlywiki.info +++ b/editions/tw5.com/tiddlywiki.info @@ -5,7 +5,7 @@ "tiddlywiki/nodewebkitsaver", "tiddlywiki/github-fork-ribbon", "tiddlywiki/browser-sniff", - "tiddlywiki/railroad" + "tiddlywiki/railroad" ], "themes": [ "tiddlywiki/vanilla", diff --git a/plugins/tiddlywiki/railroad/components.js b/plugins/tiddlywiki/railroad/components.js index 959db3840..85d0d16e2 100644 --- a/plugins/tiddlywiki/railroad/components.js +++ b/plugins/tiddlywiki/railroad/components.js @@ -177,10 +177,11 @@ Optional.prototype.toSvg = function() { return railroad.Optional(this.child.toSvg(), this.normal ? undefined : "skip"); } -var OptionalRepeated = function(content,separator,normal) { +var OptionalRepeated = function(content,separator,normal,wantArrow) { this.initialiseWithChild("OptionalRepeated",content); this.separator = toSingleChild(separator); this.normal = normal; + this.wantArrow = wantArrow; }; OptionalRepeated.prototype = new Component(); @@ -189,12 +190,13 @@ OptionalRepeated.prototype.toSvg = function() { // Call ZeroOrMore(component,separator,"skip") var separatorSvg = this.separator ? this.separator.toSvg() : null; var skip = this.normal ? undefined : "skip"; - return railroad.ZeroOrMore(this.child.toSvg(),separatorSvg,skip); + return railroad.ZeroOrMore(this.child.toSvg(),separatorSvg,skip,this.wantArrow); } -var Repeated = function(content,separator) { +var Repeated = function(content,separator,wantArrow) { this.initialiseWithChild("Repeated",content); this.separator = toSingleChild(separator); + this.wantArrow = wantArrow; }; Repeated.prototype = new Component(); @@ -202,7 +204,7 @@ Repeated.prototype = new Component(); Repeated.prototype.toSvg = function() { // Call OneOrMore(component,separator) var separatorSvg = this.separator ? this.separator.toSvg() : null; - return railroad.OneOrMore(this.child.toSvg(),separatorSvg); + return railroad.OneOrMore(this.child.toSvg(),separatorSvg,this.wantArrow); } var Link = function(content,options) { @@ -234,9 +236,11 @@ var Root = function(content) { Root.prototype = new Component(); -Root.prototype.toSvg = function() { - // Call Diagram(component1,component2,...) - return railroad.Diagram.apply(null, this.getSvgOfChildren()); +Root.prototype.toSvg = function(options) { + var args = this.getSvgOfChildren(); + args.unshift(options); + // Call Diagram(options,component1,component2,...) + return railroad.Diagram.apply(null,args); } var Sequence = function(content) { @@ -247,7 +251,7 @@ Sequence.prototype = new Component(); Sequence.prototype.toSvg = function() { // Call Sequence(component1,component2,...) - return railroad.Sequence.apply(null, this.getSvgOfChildren()); + return railroad.Sequence.apply(null,this.getSvgOfChildren()); } var Choice = function(content,normal) { @@ -264,7 +268,7 @@ Choice.prototype.toSvg = function() { // Call Choice(normal,component1,component2,...) var args = this.getSvgOfChildren(); args.unshift(this.normal); - return railroad.Choice.apply(null, args); + return railroad.Choice.apply(null,args); } /////////////////////////// Exports diff --git a/plugins/tiddlywiki/railroad/doc/example-source.tid b/plugins/tiddlywiki/railroad/doc/example-source.tid index dcca701db..8efc6b536 100644 --- a/plugins/tiddlywiki/railroad/doc/example-source.tid +++ b/plugins/tiddlywiki/railroad/doc/example-source.tid @@ -1,9 +1,9 @@ created: 20150103184022184 -modified: 20150103185522184 +modified: 20150119214125000 tags: title: $:/plugins/tiddlywiki/railroad/example-source -type: text/plain +type: text/vnd.tiddlywiki.railroad ["+"] ({ [[digit|GettingStarted]] } | "#" <'escape sequence'>) -[{("@" name-char | :"--" )}] \ No newline at end of file +[{("@" name-char | :"--" )}] diff --git a/plugins/tiddlywiki/railroad/doc/example.tid b/plugins/tiddlywiki/railroad/doc/example.tid index b64199a44..87161d708 100644 --- a/plugins/tiddlywiki/railroad/doc/example.tid +++ b/plugins/tiddlywiki/railroad/doc/example.tid @@ -1,16 +1,16 @@ created: 20150102165032410 -modified: 20150102172010663 +modified: 20150120090735000 tags: title: $:/plugins/tiddlywiki/railroad/example -<$railroad text={{$:/plugins/tiddlywiki/railroad/example-source}}/> +Notation: -``` -<$railroad text=""" -["+"] -({ [[digit|GettingStarted]] } | "#" <'escape sequence'>) -[{("@" name-char | :"--" )}] -"""/> -``` +
<$text text={{$:/plugins/tiddlywiki/railroad/example-source}}/>
-<$railroad mode="debug" text={{$:/plugins/tiddlywiki/railroad/example-source}}/>
\ No newline at end of file
+Diagram:
+
+{{$:/plugins/tiddlywiki/railroad/example-source}}
+
+Debug mode:
+
+<$railroad debug="yes" text={{$:/plugins/tiddlywiki/railroad/example-source}}/>
diff --git a/plugins/tiddlywiki/railroad/doc/readme.tid b/plugins/tiddlywiki/railroad/doc/readme.tid
index 04536dae9..05a22aeb4 100644
--- a/plugins/tiddlywiki/railroad/doc/readme.tid
+++ b/plugins/tiddlywiki/railroad/doc/readme.tid
@@ -1,19 +1,27 @@
created: 20150102163222184
-modified: 20150102172016663
+modified: 20150119231005000
title: $:/plugins/tiddlywiki/railroad/readme
-This plugin provides a `<$railroad>` widget for generating railroad syntax diagrams as SVG images. It is based on [[a library by Tab Atkins|https://github.com/tabatkins/railroad-diagrams]], and has been extended to allow components of a diagram to function as links.
+This plugin provides a `<$railroad>` widget for generating railroad diagrams as SVG images.
+
+Alternatively, the [[diagram notation|$:/plugins/tiddlywiki/railroad/syntax]] can be stored in a dedicated tiddler with its `type` field set to `text/vnd.tiddlywiki.railroad`, and that tiddler can simply be transcluded to wherever it is needed.
+
+The plugin is based on [[a library by Tab Atkins|https://github.com/tabatkins/railroad-diagrams]], and has been extended to make it more flexible, including allowing components of a diagram to function as links or be transcluded from other tiddlers.
The content of the `<$railroad>` widget is ignored.
-|!Attribute |!Description |
-|text |Text in a special syntax that defines the diagram's layout |
-|mode |If set to `debug`, the diagram will display its internal tree structure. The default mode is `svg` |
+|!Attribute |!Description |!Default |
+|text |Text in a special notation that defines the diagram's layout |-- |
+|arrow |If set to `no`, repeat paths do not have an arrow on them |`yes` |
+|start |Style of the startpoint: `single`, `double`, `none` |`single` |
+|end |Style of the endpoint: `single`, `double`, `none` |`single` |
+|debug |If set to `yes`, the diagram displays its parse tree |`no` |
-The entire `text` can be transcluded from another tiddler:
+These options can also be specified via pragmas in the diagram notation, or globally via a dictionary tiddler called `$:/config/railroad`:
```
-<$railroad tiddler={{diagram}}>
+arrow: yes
+start: single
+end: single
+debug: no
```
-
-Alternatively, the diagram syntax allows specific parts of the `text` to be transcluded from other tiddlers.
\ No newline at end of file
diff --git a/plugins/tiddlywiki/railroad/doc/syntax.tid b/plugins/tiddlywiki/railroad/doc/syntax.tid
index d99e3bb80..fc0d8d87f 100644
--- a/plugins/tiddlywiki/railroad/doc/syntax.tid
+++ b/plugins/tiddlywiki/railroad/doc/syntax.tid
@@ -1,8 +1,8 @@
created: 20150103184022184
-modified: 20150103184022184
+modified: 20150119220342000
title: $:/plugins/tiddlywiki/railroad/syntax
-The railroad widget uses a special ''diagram syntax'' to construct the components defined below.
+The railroad widget uses a special notation to construct the components defined below.
`x` and `y` here stand for any component.
@@ -78,3 +78,22 @@ Names (as opposed to quoted strings) are available when a value starts with a le
; transclusion
: <$railroad text=""" "{{" (name|string) "}}" """/>
* Treats the content of another tiddler as diagram syntax and transcludes it into the current diagram
+
+---
+
+; arrow pragma
+: <$railroad text=""" "\arrow" ("yes" | "no") """/>
+* Controls whether repeat paths have an arrow on them
+* Can be toggled on and off in mid-diagram, if desired
+
+---
+
+; debug pragma
+: <$railroad text=""" "\debug" """/>
+* Causes the diagram to display its parse tree
+
+---
+
+; start/end pragma
+: <$railroad text=""" ("\start" |: "\end") ("none" |: "single" | "double") """/>
+* Controls the style of the diagram's startpoint or endpoint
diff --git a/plugins/tiddlywiki/railroad/files/railroad-diagrams.css b/plugins/tiddlywiki/railroad/files/railroad-diagrams.css
index 4f9ba13b3..20c720a50 100644
--- a/plugins/tiddlywiki/railroad/files/railroad-diagrams.css
+++ b/plugins/tiddlywiki/railroad/files/railroad-diagrams.css
@@ -1,23 +1,32 @@
+/* CSS modified for TiddlyWiki */
svg.railroad-diagram {
- background-color: hsl(30,20%,95%);
+ background-color: hsl(30,20%,98%);
+ border-radius: 5px;
+}
+svg.railroad-diagram:hover {
+ background-color: hsl(30,20%,96%);
+}
+svg.railroad-diagram path,
+svg.railroad-diagram rect {
+ stroke-width: 2;
+ stroke: #333;
}
svg.railroad-diagram path {
- stroke-width: 3;
- stroke: black;
- fill: rgba(0,0,0,0);
-}
-svg.railroad-diagram text {
- font: bold 14px monospace;
- text-anchor: middle;
-}
-svg.railroad-diagram text.label {
- text-anchor: start;
-}
-svg.railroad-diagram text.comment {
- font: italic 12px monospace;
+ fill: rgba(0,0,0,0);
}
svg.railroad-diagram rect {
- stroke-width: 3;
- stroke: black;
- fill: hsl(120,100%,90%);
+ fill: hsl(120,100%,90%);
+}
+svg.railroad-diagram text {
+ font: 14px monospace;
+ text-anchor: middle;
+}
+svg.railroad-diagram text.label {
+ text-anchor: start;
+}
+svg.railroad-diagram text.comment {
+ font: italic 12px monospace;
+}
+svg.railroad-diagram path.arrow {
+ stroke-width: 2;
}
\ No newline at end of file
diff --git a/plugins/tiddlywiki/railroad/files/railroad-diagrams.js b/plugins/tiddlywiki/railroad/files/railroad-diagrams.js
index b5bae739b..dfdcbe7ff 100644
--- a/plugins/tiddlywiki/railroad/files/railroad-diagrams.js
+++ b/plugins/tiddlywiki/railroad/files/railroad-diagrams.js
@@ -111,9 +111,9 @@ var temp = (function(options) {
return str;
}
- function Path(x,y) {
- if(!(this instanceof Path)) return new Path(x,y);
- FakeSVG.call(this, 'path');
+ function Path(x,y,attrs) {
+ if(!(this instanceof Path)) return new Path(x,y,attrs);
+ FakeSVG.call(this, 'path', attrs);
this.attrs.d = "M"+x+' '+y;
}
subclassOf(Path, FakeSVG);
@@ -156,17 +156,23 @@ var temp = (function(options) {
this.attrs.d += 'h.5';
return this;
}
+/* TiddlyWiki: added support for arbitrary straight lines */
+ Path.prototype.line = function(dx,dy) {
+ this.attrs.d += "l"+dx+" "+dy;
+ return this;
+ }
- function Diagram(items) {
- if(!(this instanceof Diagram)) return new Diagram([].slice.call(arguments));
+/* TiddlyWiki: added twOptions parameter, passing it to Start() and End() */
+ function Diagram(twOptions, items) {
+ if(!(this instanceof Diagram)) return new Diagram(twOptions, [].slice.call(arguments,1));
FakeSVG.call(this, 'svg', {class: Diagram.DIAGRAM_CLASS});
this.items = items.map(wrapString);
- this.items.unshift(new Start);
- this.items.push(new End);
+ this.items.unshift(new Start(twOptions.start));
+ this.items.push(new End(twOptions.end));
this.width = this.items.reduce(function(sofar, el) { return sofar + el.width + (el.needsSpace?20:0)}, 0)+1;
this.up = Math.max.apply(null, this.items.map(function (x) { return x.up; }));
this.down = Math.max.apply(null, this.items.map(function (x) { return x.down; }));
- this.formatted = false;
+ this.formatted = false;
}
subclassOf(Diagram, FakeSVG);
for(var option in options) {
@@ -325,15 +331,23 @@ var temp = (function(options) {
throw "Unknown value for Optional()'s 'skip' argument.";
}
- function OneOrMore(item, rep) {
- if(!(this instanceof OneOrMore)) return new OneOrMore(item, rep);
+/* TiddlyWiki: added wantArrow */
+ function OneOrMore(item, rep, wantArrow) {
+ if(!(this instanceof OneOrMore)) return new OneOrMore(item, rep, wantArrow);
FakeSVG.call(this, 'g');
+
+/* TiddlyWiki: code added */
+ this.wantArrow = wantArrow;
+
rep = rep || (new Skip);
this.item = wrapString(item);
this.rep = wrapString(rep);
this.width = Math.max(this.item.width, this.rep.width) + Diagram.ARC_RADIUS*2;
this.up = this.item.up;
this.down = Math.max(Diagram.ARC_RADIUS*2, this.item.down + Diagram.VERTICAL_SEPARATION + this.rep.up + this.rep.down);
+
+/* TiddlyWiki: moved calculation of distanceFromY (of the repeat arc) to here */
+ this.distanceFromY = Math.max(Diagram.ARC_RADIUS*2, this.item.down+Diagram.VERTICAL_SEPARATION+this.rep.up);
}
subclassOf(OneOrMore, FakeSVG);
OneOrMore.prototype.needsSpace = true;
@@ -350,41 +364,70 @@ var temp = (function(options) {
Path(x+this.width-Diagram.ARC_RADIUS,y).right(Diagram.ARC_RADIUS).addTo(this);
// Draw repeat arc
- var distanceFromY = Math.max(Diagram.ARC_RADIUS*2, this.item.down+Diagram.VERTICAL_SEPARATION+this.rep.up);
+/* TiddlyWiki: moved calculation of distanceFromY from here to constructor */
+ var distanceFromY = this.distanceFromY;
+
Path(x+Diagram.ARC_RADIUS,y).arc('nw').down(distanceFromY-Diagram.ARC_RADIUS*2).arc('ws').addTo(this);
this.rep.format(x+Diagram.ARC_RADIUS, y+distanceFromY, this.width - Diagram.ARC_RADIUS*2).addTo(this);
Path(x+this.width-Diagram.ARC_RADIUS, y+distanceFromY).arc('se').up(distanceFromY-Diagram.ARC_RADIUS*2).arc('en').addTo(this);
+
+/* TiddlyWiki: code added */
+ if(this.wantArrow) {
+ var arrowSize = Diagram.ARC_RADIUS/2;
+ // Compensate for the illusion that makes the arrow look unbalanced if it's too close to the curve below it
+ var multiplier = (distanceFromY < arrowSize*5) ? 1.2 : 1;
+ Path(x-arrowSize, y+distanceFromY/2 + arrowSize/2, {class:"arrow"}).
+ line(arrowSize, -arrowSize).line(arrowSize*multiplier, arrowSize).addTo(this);
+ }
return this;
}
- function ZeroOrMore(item, rep, skip) {
- return Optional(OneOrMore(item, rep), skip);
+ function ZeroOrMore(item, rep, skip, wantArrow) {
+ return Optional(OneOrMore(item, rep, wantArrow), skip);
}
- function Start() {
- if(!(this instanceof Start)) return new Start();
+/* TiddlyWiki: added type parameter */
+ function Start(type) {
+ if(!(this instanceof Start)) return new Start(type);
FakeSVG.call(this, 'path');
- this.width = 20;
+ this.type = type || 'single'
+ this.width = (this.type === 'double') ? 20 : 10;
this.up = 10;
this.down = 10;
}
subclassOf(Start, FakeSVG);
Start.prototype.format = function(x,y) {
- this.attrs.d = 'M '+x+' '+(y-10)+' v 20 m 10 -20 v 20 m -10 -10 h 20.5';
+/* TiddlyWiki: added types */
+ if(this.type === 'single') {
+ this.attrs.d = 'M '+x+' '+(y-10)+' v 20 m 0 -10 h 10.5';
+ } else if(this.type === 'double') {
+ this.attrs.d = 'M '+x+' '+(y-10)+' v 20 m 10 -20 v 20 m -10 -10 h 20.5';
+ } else { // 'none'
+ this.attrs.d = 'M '+x+' '+y+' h 10.5';
+ }
return this;
}
- function End() {
- if(!(this instanceof End)) return new End();
+/* TiddlyWiki: added type parameter */
+ function End(type) {
+ if(!(this instanceof End)) return new End(type);
FakeSVG.call(this, 'path');
- this.width = 20;
+ this.type = type || 'double';
+ this.width = (this.type === 'double') ? 20 : 10;
this.up = 10;
this.down = 10;
}
subclassOf(End, FakeSVG);
End.prototype.format = function(x,y) {
- this.attrs.d = 'M '+x+' '+y+' h 20 m -10 -10 v 20 m 10 -20 v 20';
+/* TiddlyWiki: added types */
+ if(this.type === 'single') {
+ this.attrs.d = 'M '+x+' '+y+' h 10 m 0 -10 v 20';
+ } else if(this.type === 'double') {
+ this.attrs.d = 'M '+x+' '+y+' h 20 m -10 -10 v 20 m 10 -20 v 20';
+ } else { // 'none'
+ this.attrs.d = 'M '+x+' '+y+' h 10';
+ }
return this;
}
diff --git a/plugins/tiddlywiki/railroad/parser.js b/plugins/tiddlywiki/railroad/parser.js
index 1dfd50d29..bb55b57b8 100644
--- a/plugins/tiddlywiki/railroad/parser.js
+++ b/plugins/tiddlywiki/railroad/parser.js
@@ -26,6 +26,12 @@ x y z sequence
"x" can also be written 'x' or """x"""
+pragmas:
+ \arrow yes|no
+ \debug yes|no
+ \start single|double|none
+ \end single|double|none
+
\*/
(function(){
@@ -35,9 +41,10 @@ x y z sequence
var components = require("$:/plugins/tiddlywiki/railroad/components.js").components;
-var Parser = function(widget,source) {
+var Parser = function(widget,source,options) {
this.widget = widget;
this.source = source;
+ this.options = options;
this.tokens = this.tokenise(source);
this.tokenPos = 0;
this.advance();
@@ -56,7 +63,9 @@ Parser.prototype.parseContent = function() {
if(!component) {
break;
}
- content.push(component);
+ if(!component.isPragma) {
+ content.push(component);
+ }
}
return content;
};
@@ -68,6 +77,8 @@ Parser.prototype.parseComponent = function() {
component = this.parseTerminal();
} else if(this.at("name")) {
component = this.parseName();
+ } else if(this.at("pragma")) {
+ component = this.parsePragma();
} else {
switch(this.token.value) {
case "[":
@@ -182,6 +193,7 @@ Parser.prototype.parseNonterminal = function() {
};
Parser.prototype.parseOptional = function() {
+ var wantArrow = this.options.arrow;
// Consume the [
this.advance();
// Consume the { if there is one
@@ -201,10 +213,12 @@ Parser.prototype.parseOptional = function() {
}
this.close("]");
// Create a component
- return repeated ? new components.OptionalRepeated(content,separator,normal) : new components.Optional(content,normal);
+ return repeated ? new components.OptionalRepeated(content,separator,normal,wantArrow)
+ : new components.Optional(content,normal);
};
Parser.prototype.parseRepeated = function() {
+ var wantArrow = this.options.arrow;
// Consume the {
this.advance();
// Parse the content
@@ -217,7 +231,7 @@ Parser.prototype.parseRepeated = function() {
// Consume the closing bracket
this.close("}");
// Create a component
- return new components.Repeated(content,separator);
+ return new components.Repeated(content,separator,wantArrow);
};
Parser.prototype.parseSequence = function() {
@@ -253,6 +267,44 @@ Parser.prototype.parseTransclusion = function() {
return new components.Transclusion(content);
};
+/////////////////////////// Pragmas
+
+Parser.prototype.parsePragma = function() {
+ // Create a dummy component
+ var component = { isPragma: true };
+ // Consume the pragma
+ var pragma = this.token.value;
+ this.advance();
+ // Apply the setting
+ if(pragma === "arrow") {
+ this.options.arrow = this.parseYesNo(pragma);
+ } else if(pragma === "debug") {
+ this.options.debug = true;
+ } else if(pragma === "start") {
+ this.options.start = this.parseTerminusStyle(pragma);
+ } else if(pragma === "end") {
+ this.options.end = this.parseTerminusStyle(pragma);
+ } else {
+ throw "Invalid pragma";
+ }
+ return component;
+};
+
+Parser.prototype.parseYesNo = function(pragma) {
+ return this.parseSetting(["yes","no"],pragma) === "yes";
+}
+
+Parser.prototype.parseTerminusStyle = function(pragma) {
+ return this.parseSetting(["single","double","none"],pragma);
+}
+
+Parser.prototype.parseSetting = function(options,pragma) {
+ if(this.at("name") && options.indexOf(this.token.value) !== -1) {
+ return this.tokenValueEaten();
+ }
+ throw options.join(" or ") + " expected after \\" + pragma;
+}
+
/////////////////////////// Token manipulation
Parser.prototype.advance = function() {
@@ -274,7 +326,7 @@ Parser.prototype.eat = function(token) {
return at;
};
-Parser.prototype.tokenValue = function() {
+Parser.prototype.tokenValueEaten = function() {
var output = this.token.value;
this.advance();
return output;
@@ -303,12 +355,12 @@ Parser.prototype.expectString = function(context,token) {
token = token || "String";
throw token + " expected " + context;
}
- return this.tokenValue();
+ return this.tokenValueEaten();
};
Parser.prototype.expectNameOrString = function(context) {
if(this.at("name")) {
- return this.tokenValue();
+ return this.tokenValueEaten();
}
return this.expectString(context,"Name or string");
};
@@ -351,6 +403,9 @@ Parser.prototype.tokenise = function(source) {
} else if(c.match(/[a-zA-Z]/)) {
// Name
token = this.readName(source,pos);
+ } else if(c.match(/\\/)) {
+ // Pragma
+ token = this.readPragma(source,pos);
} else {
throw "Syntax error at " + c;
}
@@ -378,6 +433,18 @@ Parser.prototype.readName = function(source,pos) {
}
};
+Parser.prototype.readPragma = function(source,pos) {
+ var re = /([a-z]+)/g;
+ pos++;
+ re.lastIndex = pos;
+ var match = re.exec(source);
+ if(match && match.index === pos) {
+ return {type: "pragma", value: match[1], start: pos, end: pos+match[1].length};
+ } else {
+ throw "Invalid pragma";
+ }
+};
+
/////////////////////////// Exports
exports.parser = Parser;
diff --git a/plugins/tiddlywiki/railroad/typed-parser.js b/plugins/tiddlywiki/railroad/typed-parser.js
new file mode 100644
index 000000000..c956ff09b
--- /dev/null
+++ b/plugins/tiddlywiki/railroad/typed-parser.js
@@ -0,0 +1,28 @@
+/*\
+title: $:/plugins/tiddlywiki/railroad/typed-parser.js
+type: application/javascript
+module-type: parser
+
+This parser wraps unadorned railroad syntax into a railroad widget
+
+\*/
+(function(){
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var RailroadParser = function(type,text,options) {
+ var element = {
+ type: "railroad",
+ tag: "$railroad",
+ text: text
+ };
+ this.tree = [element];
+console.log(text);
+};
+
+exports["text/vnd.tiddlywiki.railroad"] = RailroadParser;
+
+})();
+
diff --git a/plugins/tiddlywiki/railroad/wrapper.js b/plugins/tiddlywiki/railroad/wrapper.js
index a4e8c7032..ca1c18e6b 100644
--- a/plugins/tiddlywiki/railroad/wrapper.js
+++ b/plugins/tiddlywiki/railroad/wrapper.js
@@ -19,6 +19,8 @@ var RailroadWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
+var RAILROAD_OPTIONS = "$:/config/railroad";
+
/*
Inherit from the base widget class
*/
@@ -37,10 +39,18 @@ RailroadWidget.prototype.render = function(parent,nextSibling) {
// Create a div to contain the SVG or error message
var div = this.document.createElement("div");
try {
+ // Initialise options from the config tiddler or widget attributes
+ var config = $tw.wiki.getTiddlerData(RAILROAD_OPTIONS,{});
+ var options = {
+ arrow: this.getAttribute("arrow", config.arrow || "yes") === "yes",
+ debug: this.getAttribute("debug", config.debug || "no") === "yes",
+ start: this.getAttribute("start", config.start || "single"),
+ end: this.getAttribute("end", config.end || "single")
+ };
// Parse the source
- var parser = new Parser(this,source);
+ var parser = new Parser(this,source,options);
// Generate content into the div
- if(this.getAttribute("mode","svg") === "debug") {
+ if(parser.options.debug) {
this.renderDebug(parser,div);
} else {
this.renderSvg(parser,div);
@@ -63,7 +73,7 @@ RailroadWidget.prototype.renderDebug = function(parser,div) {
RailroadWidget.prototype.renderSvg = function(parser,div) {
// Generate a model of the diagram
- var fakeSvg = parser.root.toSvg();
+ var fakeSvg = parser.root.toSvg(parser.options);
// Render the model into a tree of SVG DOM nodes
var svg = fakeSvg.toSVG();
// Fill in the remaining attributes of any link nodes
@@ -107,7 +117,7 @@ RailroadWidget.prototype.patchLinks = function(node) {
RailroadWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
- if(changedAttributes.text) {
+ if(changedAttributes.text || changedTiddlers[RAILROAD_OPTIONS]) {
this.refreshSelf();
return true;
}