diff --git a/core/ui/SideBarLists.tid b/core/ui/SideBarLists.tid index bf1e53637..100d6fec8 100644 --- a/core/ui/SideBarLists.tid +++ b/core/ui/SideBarLists.tid @@ -3,7 +3,7 @@ title: $:/core/ui/SideBarLists
[[is|FilterOperator: is]]
, [[has|FilterOperator: has]]
, [[tag|FilterOperator: tag]]
, etc) of specific filtering functions
+* A fieldname on its own implies the keyword `field`
+* An entirely omitted operator defaults to `title`
+
+---
+
+;parameter
+: <$railroad text="""
+( "[" [{/"any character except ]"/}] "]"
+ |
+ "{" [{/"any character except }"/}] "}"
+ |
+ "<" [{/"any character except >"/}] ">"
+)
+"""/>
+* `[`...`]` encloses a literal parameter
+* `{`...`}` encloses a TextReference parameter
+* `<`...`>` encloses a [[variable|Variables]] parameter
+
+---
+
+;whitespace
+: <$railroad text="""
+{( "space" | "tab" | "linefeed" | "return" | "vertical tab" | "formfeed" )}
+"""/>
+* A match for the JavaScript regular expression `\s+`
diff --git a/editions/tw5.com/tiddlers/nodejs/TiddlerFilter Formal Grammar.tid b/editions/tw5.com/tiddlers/nodejs/TiddlerFilter Formal Grammar.tid
deleted file mode 100644
index 24b7501f5..000000000
--- a/editions/tw5.com/tiddlers/nodejs/TiddlerFilter Formal Grammar.tid
+++ /dev/null
@@ -1,61 +0,0 @@
-created: 20140210141217955
-modified: 20140912145655663
-tags: Filters
-title: Filter Formal Grammar
-type: text/vnd.tiddlywiki
-
-[[Filter expressions|Filters]] follow a grammar that is presented here for those who find formal syntax descriptions helpful. However, you can write your own filter expressions without needing to understand this tiddler.
-
-* [//x//] denotes an optional //x//
-* (//x//)... denotes 1 or more instances of //x//
-* Literal characters are `monospaced`
-* Top-level bullets indicate alternative possibilities
-* Second-level bullets are comments and clarifications
-
-;filter
-* ( [//whitespace//] [`+`|`-`] //run// )...
-
-;run
-* `[` (//operation//)... `]`
-* `"` //text// `"`
-** The text can contain anything but `"`
-* `'` //text// `'`
-** The text can contain anything but `'`
-* //text//
-** The text can contain anything but whitespace and `[` and `]`
-** These last three alternatives are short for `[title[text]]`
-
-;operation
-* [`!`] //operator// //operand//
-
-;operator
-* [//keyword//] [`:` //fieldname//]
-** Keywords (`is`, `has`, `tag`, etc) are reserved names that identify filter functions
-** A fieldname on its own implies the keyword `field`
-** An entirely omitted operator defaults to `title`
-
-;operand
-* `[` //text// `]`
-** literal -- the text can contain anything but `]`
-* `{` //text// `}`
-** text reference -- the text can contain anything but `}`
-* `<` //text// `>`
-** variable -- the text can contain anything but `>`
-
-;whitespace
-* One or more spaces, tabs or linefeeds, i.e. a match for the JavaScript regular expression `\s+`
-
-!Evaluation
-
-Each operation returns a set of tiddlers, in the form of a TitleList.
-
-A run evaluates each of the operations it contains, and returns the intersection of the resulting sets.
-
-A sequence of runs is evaluated from left to right, as follows:
-
-|!Sequence |!Interpretation |
-|run1 run2 |union of the sets, i.e. the tiddlers in //either// run1 //or// run2 |
-|run1 -run2 |difference of the sets, i.e. run1 but excluding any tiddlers in run2 |
-|run1 +run2 |run2 takes run1 as its input |
-
-The first run of a sequence takes `[all[tiddlers]]` as its input, i.e. the set of all non-missing tiddlers.
diff --git a/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid b/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid
index 563182bb9..4b1393814 100644
--- a/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/EditTextWidget.tid
@@ -22,6 +22,7 @@ The content of the `<$edit-text>` widget is ignored.
|class |A CSS class to be assigned to the generated HTML editing element |
|placeholder |Placeholder text to be displayed when the edit field is empty |
|focusPopup |Title of a state tiddler for a popup that is displayed when the editing element has focus |
+|focus |Set to "true" to automatically focus the editor after creation |
|tag |Overrides the generated HTML editing element tag. Use `textarea` for a multi-line editor |
|type |Overrides the generated HTML editing element `type` attribute |
|size |The size of the input field (in characters) |
diff --git a/editions/tw5.com/tiddlywiki.info b/editions/tw5.com/tiddlywiki.info
index 4f35332d1..54c0e3948 100644
--- a/editions/tw5.com/tiddlywiki.info
+++ b/editions/tw5.com/tiddlywiki.info
@@ -4,7 +4,8 @@
"tiddlywiki/googleanalytics",
"tiddlywiki/nodewebkitsaver",
"tiddlywiki/github-fork-ribbon",
- "tiddlywiki/browser-sniff"
+ "tiddlywiki/browser-sniff",
+ "tiddlywiki/railroad"
],
"themes": [
"tiddlywiki/vanilla",
diff --git a/plugins/tiddlywiki/filesystem/filesystemadaptor.js b/plugins/tiddlywiki/filesystem/filesystemadaptor.js
index b3e4d8af7..68e951c2b 100644
--- a/plugins/tiddlywiki/filesystem/filesystemadaptor.js
+++ b/plugins/tiddlywiki/filesystem/filesystemadaptor.js
@@ -92,16 +92,17 @@ Given a tiddler title and an array of existing filenames, generate a new legal f
*/
FileSystemAdaptor.prototype.generateTiddlerFilename = function(title,extension,existingFilenames) {
// First remove any of the characters that are illegal in Windows filenames
- var baseFilename = title.replace(/<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g,"_");
+ var baseFilename = transliterate(title.replace(/<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g,"_"));
// Truncate the filename if it is too long
if(baseFilename.length > 200) {
baseFilename = baseFilename.substr(0,200);
}
// Start with the base filename plus the extension
- var filename = transliterate(baseFilename) + extension,
+ var filename = baseFilename + extension,
count = 1;
- // Add a discriminator if we're clashing with an existing filename
- while(existingFilenames.indexOf(filename) !== -1) {
+ // Add a discriminator if we're clashing with an existing filename while
+ // handling case-insensitive filesystems (NTFS, FAT/FAT32, etc.)
+ while(existingFilenames.some(function(value) {return value.toLocaleLowerCase() === filename.toLocaleLowerCase();})) {
filename = baseFilename + " " + (count++) + extension;
}
return filename;
diff --git a/plugins/tiddlywiki/railroad/components.js b/plugins/tiddlywiki/railroad/components.js
new file mode 100644
index 000000000..3001f448c
--- /dev/null
+++ b/plugins/tiddlywiki/railroad/components.js
@@ -0,0 +1,264 @@
+/*\
+title: $:/plugins/tiddlywiki/railroad/components.js
+type: application/javascript
+module-type: library
+
+Components of a railroad diagram.
+
+\*/
+(function(){
+
+/*jslint node: true, browser: true */
+/*global $tw: false */
+"use strict";
+
+var railroad = require("$:/plugins/tiddlywiki/railroad/railroad-diagrams.js");
+
+/////////////////////////// Base component
+
+var Component = function() {
+ this.type = "Component";
+};
+
+// Set up a leaf component
+Component.prototype.initialiseLeaf = function(type,text) {
+ this.type = type;
+ this.text = text;
+};
+
+// Set up a component with a single child
+Component.prototype.initialiseWithChild = function(type,content) {
+ this.type = type;
+ this.child = toSingleChild(content);
+};
+
+// Set up a component with an array of children
+Component.prototype.initialiseWithChildren = function(type,content) {
+ this.type = type;
+ // Force the content to be an array
+ this.children = $tw.utils.isArray(content) ? content : [content];
+}
+
+// Return an array of the SVG strings of an array of children
+Component.prototype.getSvgOfChildren = function() {
+ return this.children.map(function(child) {
+ return child.toSvg();
+ });
+}
+
+Component.prototype.toSvg = function() {
+ return "";
+}
+
+Component.prototype.debug = function(output,indent) {
+ output.push(indent);
+ output.push(this.type);
+ // Add the text of a leaf component
+ if(this.text && this.text !== "") {
+ output.push(": ");
+ output.push(this.text);
+ }
+ // Flag the normal route
+ if(this.normal !== undefined) {
+ if(this.normal === true) {
+ output.push(" (normal)");
+ } else if(this.normal !== false) {
+ output.push(" (normal: ");
+ output.push(this.normal);
+ output.push(")");
+ }
+ }
+ output.push("\n");
+ var contentIndent = indent + " ";
+ // Add the one child
+ if(this.child) {
+ this.child.debug(output,contentIndent);
+ }
+ // Add the array of children
+ if(this.children) {
+ this.debugArray(this.children,output,contentIndent);
+ }
+ // Add the separator if there is one
+ if(this.separator) {
+ output.push(indent);
+ output.push("(separator)\n");
+ this.separator.debug(output,contentIndent);
+ }
+};
+
+Component.prototype.debugArray = function(array,output,indent) {
+ for(var i=0; i"]; + parser.root.debug(output, ""); + output.push(""); + div.innerHTML = output.join(""); + } else { + div.innerHTML = parser.root.toSvg(); + } + } catch(ex) { + div.className = "tc-error"; + div.textContent = ex; + } + // Insert it into the DOM + parent.insertBefore(div,nextSibling); + this.domNodes.push(div); +}; + +RailroadWidget.prototype.refresh = function(changedTiddlers) { + var changedAttributes = this.computeAttributes(); + if(changedAttributes.text) { + this.refreshSelf(); + return true; + } + return false; +}; + +exports.railroad = RailroadWidget; + +})(); \ No newline at end of file