Sofu for Javascript/JScript/ECMAscript
SofuJS is a somewhat cut down version of SofuD for Javascript
It does not support (as of now):
- SofuML (Will come some day, (Input from a document tree, output to text))
- BinarySofu (No real encoding support and binary conversion operations in JavaScript/JScript)
- Reading and writing files (Not allowed)
There are some things however it is good for:
- AJAX (more like AJAS)
- It can read and parse incoming sofu files while they are coming in (if your XMLHttpRequest implementation supports it)
- It can parse strings and output strings again.
- It can convert Sofu objects to Javascript notation (so the interface to the data will look just like JSONs interface)
- It can convert JavaScript Object trees to Sofu Objects
The Interface is the same as the interface to SofuD, except in Javascript there is no overloading of the for() keyword.
How to get it
Download the latest SofuJS with the Online Editor example
The Sofu Namespace:
All Sofu Stuff is in a single Object called Sofu:
Sofu.loadFile(string) or Sofu.loadString(string)
This is the same function, but its called Sofu.loadFile() because its called the same in SofuD
But Sofu.loadString() is clearer.
Parses String into Sofu Objects:
var myfile = Sofu.loadString("Text = \"Hello World\"\nonetwothree = (10 20 30)\nmm={foo=bar}"); alert(myfile.value("Text").toString()); //Alerts "Hello World"; alert(myfile.list("onetwothree").value(1)); // Alerts(10) myfile.list("onetwothree").opApply(function(value) {alert(value.toString())}); // Alerts 10 and then 20 and then 30 alert(myfile.map("mm").value("foo").toString()); //Alerts "bar"
Sofu.readFile(string) or Sofu.readStrong(string)
This function is SofuJS specific (but there are similar functions in other sofu parsers)
It parses "string" into javscript objects
This interface is easier and more like JSONs or other interfaces, but some things like Sofu Comments will be lost.
var myfile = Sofu.readString("Text = \"Hello World\"\nonetwothree = (10 20 30)\nmm={foo=bar}"); alert(myfile.Text); //Alerts "Hello World"; alert(myfile.onetwothree[1]); // Alerts(10) for (var i in myfile.onetwothree) { alert(myfile.onetwothree[i]); // Alerts 10 and then 20 and then 30 } myfile.list("onetwothree").opApply(function(value) {alert(value.toString())}); // Alerts 10 and then 20 and then 30 alert(myfile.mm.foo); //Alerts "bar"
Sofu.Value(content)
Class for a Sofu Value
var val = new Sofu.Value("foobar"); alert(val.toString()); //Alerts foobar;
Sofu.Undefined()
Class for a Sofu Undefined
Undefined in Sofu is more like a null in Javascript
var und = new Sofu.Undefined(); alert(und.write()); //alerts the resulting Sofu file contents (Value=UNDEF)
Sofu.Map()
Class for a Sofu Map. All Sofu Files contain a map a the first element (the root element).
It contains other Sofu Objects referenced by a key.
var x = new Sofu.Map(); x.setAttribute("foo",new Sofu.Value("bar")); x.setAttribute("hello",new Sofu.Value("World")); alert(x.write());
Sofu.List()
Class for a Sofu List, It contains other Sofu Objects in a specific order.
var x = new Sofu.List(); x.appendElement(x); // Append this List (will be converted into a reference during output) x.appendElement(new Sofu.Value(100)); x.appendElement(new Sofu.Value(300)); alert(x.write()); // Resulting Sofu File.
Sofu.Reference()
References are a Sofu Construct to avoid bad recursion, every object appear more than one time will be converted into a Reference.
References are transparent, so you won't notice if you are working on a reference or on the real object.
Just don't care about them. Sofu will handle it for you.
Please consult other Sofu documentations for examples and explanations on the bahaviour of the Sofu Objects.
http://sofu.sourceforge.net/sofu.net/index.html is quite good, but beware all the methods in SofuJS start with a lower case char (not upper like in .net)
SofuJS Specific documentation will soon be placed here. (I swear)
Hacking SofuJS:
The Sofu functions are in the Sofu_Sofu_ space, and some of them are meant to be overwritten.
Custom Warnings
If you need your own error message from sofu, overwrite the Sofu_Sofu_Warn function:
Sofu_Sofu_Warn = function(param) { alert("===========\nSofu Error:\n-----------\n"+param+"\n==========="); throw param; }
Object under the Cursor
With this you can find out which object the user is pointing at in the sofu source code, I don't know who needs this, I tried to use it in the Sofu Editor but gave up cause you can't get the (text)cursor position in a textarea in IE.
Set Sofu_Sofu_Cursor to something, run the parser and get the Object in Sofu_Sofu_Cursor_Object;
(This only works for loadFile()/loadString() for now, you can get Sofu_Sofu_Convert_Ref_Cache[Sofu_Sofu_Cursor_Object.getId()] to get the Javascript object when reading readString()
Sofu_Sofu_Cursor = 10; var myfile = Sofu.loadString("Text = \"Hello World\"\nonetwothree = (10 20 30)\nmm={foo=bar}"); if (Sofu_Sofu_Cursor_Object == myfile.value("Text")) { alert("You are pointing at "+myfile.value("Text").toString()); }
Piece parser
The piece parser calls a function as soon he is out of sofu source code to parse, this might be usefull if you didn't get all the code at once and only in pieces.
(AJAX comes to mind here)
var nextpiece = "\nNext = Piece"; Sofu_Sofu_Wait_Next_Piece = function() { if (nextpiece) { Sofu_Sofu_Set_Next_Piece(nextpiece); nextpiece=""; return true; } else { throw "EOF" // You must throw something here to tell sofu the file is at the end. return false; } }
Note: there are also other functions you can call in Sofu_Sofu_Wait_Next_Piece:
All funcions will throw "EOF" if there is no new code at all.
- Sofu_Sofu_Set_Next_Piece(piece): assumes piece is the next piece and only the next piece (nothing of the code before is included). You can't use this one if you are detecting the cursor position as well, use Sofu_Sofu_Expand_With_Piece().
- Sofu_Sofu_Expand_With_Piece(piece): Expands the current source with the next piece. This one can be used with "Object under cursor" detection. But it might me slower.
- Sofu_Sofu_Expand_To(code): If you have not only the new piece but the whole code you can use this function. It is also works Object under cursor" detection.
Demo:
You can see an online/offline SofuEditor written purely in Javascript here:
http://sofu.sourceforge.net/SofuJS/Editor.html