- 1
- 2
- 21
- 211
- 22
- 21
- 3
- 4
- 41
- 42
- 43
- 431
- 4311
- 431
- 5
An HTML list that came out of GeekWeaver, when I called this recursive function :
::rec
.<ul>
:for x,, #__
.<li>
${x/=}
:hasChild x
:rec ++ #x__
on a chunk of OPML.
That's pretty much how it's going to look, folks.
::rec defines the recursive block (or function)
.<ul> creates the UL tag
:for x,, #__
is creating a loop through all the anonymous (unlabelled) children of the tree which is being passed to the call. (This list is represented by the symbol __)
Note that I'm trying to keep GeekWeaver as functional as possible so there's no real "assignment". x is scoped so that it only exists inside the block of the for-loop, it's bound once before the block is evaluated, but can't be updated after that.
${x/=}
This is the new way of accessing variables. x is actually bound to a sub-tree (Almost everything in GeekWeaver is a sub-tree, except a couple of weird cases like __ which is a list.)
Although a simple $x still works if you want the whole of a tree flattened into a string, ${} expressions give you a way to pull data from a single path in the tree. In this case we're just getting the text content of the root node of x.
But it's also possible to write stuff like this : ${company/employees/__3/name} which means from the symbol "company" get the labelled child "employees" from which get the non-labelled 3rd child, from which get the child labelled "name".
:hasChild, like :for, is a build-in function. If the tree in x has any children, it evaluates the body of the :hasChild tree. If not, it returns nothing. This tests for our "base-case" when we've hit a leaf of the tree we're recursing through.
The final line :
:rec ++ #x__
is the one which I've been struggling with for the last three months, ever since I started trying to figure out how to support recursion. I'm still not 100% happy with the solution I've come up with, but it's getting there.
:rec is calling the recursive block again. And obviously I need to pass the children of x as arguments. However the way the function is written, it is working on the anonymous children (inside the default variable __)
How am I going to get the children of x into the __ variable inside the next call of :rec? That's what ++ does. Not sure what I'm going to call this, I may call it a "pivot" although that may confuse as much as help. It captures something of the idea that I need to swing the anonymous children of x (#x__) around so that they can go into the next call of :rec as though they were children of the calling node
Like I say, don't know if I like this name or the ++ symbol being used for it. So consider both as provisional for now.
OK, I'm too tired to make the build with this stuff working tonight. I'll try to get a build together in the next couple of days, but meanwhile, if this looks interesting to you and you can't contain yourself, send me an email (interstarATgmail.com), say hello and I'll see what I can do.
2 comments:
All very ingenious, but I'd like to see more about the kind of web site for which the Geekweaver functionality would be appropriate.
A lot of sites are created visually using authoring packages like Dreamweaver; others use a CMS, giving more scope for automating the process but less for individually crafted pages.
Geekweaver appears to move further along that spectrum, but it isn't obvious how dynamic the resulting site would be. To change the text of one page, for instance, would it be necessary to change the input file and then re-create the whole site?
I think you should make a site, preferably for a client, to demonstrate Geekweaver's functionality in a concrete way, and show that the effort of learning its fairly idiosyncratic (not to say cryptic) notation would pay off.
Hi myname (whoever you are)
thanks for the comments.
GeekWeaver started because I needed to create a bunch of similar static web-pages in a place where I *didn't* have access to a CMS. (Corporate documentation on a private intranet so I can't link, unfortunately.)
Obviously, in a lot of cases, when you do have a CMS running then that would be more appropriate.
As you intuit, the big issue for GW is that you have to regenerate the whole site each time you make a change, which is a pain. (Though I have some ideas for this ...)
The biggest publicly visible site created with GW is http://giselazevedo.com/ - and note that I make no claims to be a good visual web-designer or have CSS skills; I certainly need to improve the templates on the next revision. :-)
Nevertheless, that site was considerably easier to make with GW than if I'd simply made and maintained the HTML pages by hand in a text editor.
One of the nicest things about GW, from my perspective, is that a multiple file site is kept in a single source file. So, apart from the images, that artist's site is kept in a single OPML outline. (If it wasn't clear, the GeekWeaver source-code is OPML and meant to be edited in an outliner. The plain-text version is useful for quick examples, and to illustrate but you'd be unlikely to do serious work with it.)
Because of this, I believe that the value of GeekWeaver is that it's going to help bring a unity to the diversity of languages that are currently needed to make interesting dynamic web-sites.
Even the smallest dynamic site can involve juggling several PHP files, external CSS and Javacript libraries, perhaps XML configuration files, or SQL to set-up the tables in the database.)
With GeekWeaver you can bring all these together into a single outline; and rely on a common way of defining reusable abstractions that can cover more than one language the same time. So, for example, a single parameterizable block can be defined which, when evaluated, produces a table definition, a PHP5 class definition, and a separate javascript object constructor. All in separate files and directories.
In a way, you can see GW as being a generic macro pre-processor / code-generation tool for all the other languages you are going to use in creating your dynamic web-site - or any other software project. I'm hoping GW + outliner eventually becomes a kind of cheap "language workbench" where it's easy to knock up your own external Domain Specific Languages. The languages you define will be restricted, but as they'll all be variants on "define a tree of data with labelled subtrees" I think they'll be convenient enough for a lot of purposes.
Post a Comment