<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0"
   xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback"
   xmlns:ent="http://www.purl.org/NET/ENT/1.0/"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<channel>
<title>Iron Lute</title>
<link>http://www.jerf.org/iri/categories/Iron Lute/</link>
<description>Tracks the development of the Python/Tk outliner, Iron Lute.</description>
<language>en</language>
<copyright>Copyright 2006 Jeremy Bowers</copyright>
<lastBuildDate>Sat, 07 May 2005 16:42:40 GMT</lastBuildDate>
<generator>Python Desktop Server 0.7.2 (http://pyds.muensterland.org/)</generator>
<managingEditor>jerf@jerf.org</managingEditor>
<webMaster>jerf@jerf.org</webMaster>
<category domain="http://www.weblogs.com/rssUpdates/changes.xml">rssUpdates</category>
<skipHours>
<hour>0</hour>
<hour>1</hour>
<hour>2</hour>
<hour>3</hour>
<hour>4</hour>
<hour>5</hour>
<hour>6</hour>
<hour>7</hour>
<hour>8</hour>
<hour>9</hour>
<hour>10</hour>
<hour>11</hour>
<hour>12</hour>
<hour>13</hour>
<hour>14</hour>
<hour>17</hour>
<hour>19</hour>
<hour>20</hour>
<hour>21</hour>
<hour>23</hour>
</skipHours>
<item>
<title>Expanding Brain (ExBr), an outlining blog</title>
<link>http://www.expandingbrain.com/blog/</link>
<description>Blog of interest: Expanding Brain (ExBr), a blog about &quot;Windows outliners, software development and starting a new business&quot;. Also of note is that the author has set up a &lt;a href=&quot;http://www.expandingbrain.com/wiki/doku.php&quot;&gt;wiki&lt;/a&gt; for outliner topics.

&lt;p&gt;The author and I have been exchanging emails, comparing development notes.&lt;/p&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2005/05/07.html#P2472</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Sat, 07 May 2005 16:42:40 GMT</pubDate>
</item>
<item>
<description>I finally have a job, a real job, though I don&apos;t start until May 9th. For a while after that I will have an overlap between my real job and my last contract job, but after that, I hope to finally have some time to spend with a clear conscience on my open source projects that I want to work on, especially Iron Lute which has been seriously neglected (though not quite ignored).

&lt;p&gt;In Iron Lute news, in the intervening years since I last analysed the graphical toolkits for whether I can build an outliner with them, GTK has become possible to use without too much hassle. Since this is about the fifth time I&apos;ve switched major ways of doing business on the GUI front, I&apos;ve got the independent stuff pretty well factored out, and it&apos;s going well. I got TK to a point that was almost satisfactory, but the graphical performance was poor; the node indicators (the thing you see to the left of each node) were getting painted in a seperate pass from the text, so while scrolling or doing other things, it looked horrible. GTK doesn&apos;t have that problem, and at this point I don&apos;t anticipate any other major problems.&lt;/p&gt;

&lt;p&gt;XBLinJS is about ready for a 0.5 release pending me getting off my duff and testing and fixing it up on IE 6, which should happen soonish, but no promises.&lt;/p&gt;

&lt;p&gt;Here&apos;s hoping the job lasts a while.&lt;/p&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2005/04/23.html#P2465</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<category domain="http://www.jerf.org/iri/">XBLinJS</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
<ent:topic ent:id="XBLinJS" ent:href="http://www.jerf.org/iri/categories/XBLinJS/">XBLinJS</ent:topic>
</ent:cloud>
<pubDate>Sat, 23 Apr 2005 17:27:28 GMT</pubDate>
</item>
<item>
<title>Frontier Open Sourcing</title>
<description>&lt;a href=&quot;http://archive.scripting.com/2004/05/17#asGoodATimeAsAny&quot;&gt;Frontier
will apparently be open source in the near future&lt;/a&gt;. I&apos;ve actually
spent a significant time with the product, and I have an interesting
perspective on this issue as &lt;a href=&quot;http://www.jerf.org/iri/categories/Iron%20Lute/2004/01/12.html&quot;&gt;I
have a project started in no small part because of the closed nature
of the Frontier code&lt;/a&gt;. (A project, I might add, that I really,
really, really wish I could get back to, but a guy&apos;s gotta eat.)

&lt;p&gt;So I ask myself, as someone who might be interested in developing
the product, what does an Open Source Frontier bring to the table?&lt;/p&gt;

&lt;p&gt;First, the licensing issue has not been worked out. One thing that
can wipe out all value up front is a restrictive license, such as one
that ends up &lt;i&gt;effectively&lt;/i&gt; only allowing Frontier to be used to run
Manila.root or Radio.root. You&apos;ve got to be able to rip out a chunk
of Frontier and use it to run your own, independent application; I&apos;d
be perfectly fine with the LGPL or the GPL which both require source
code to be provided to users on request, fully Free. I&apos;d suggest the
LGPL; dual-licensing GPL/commercial is another possibility but may or
may not inhibit contributions.&lt;/p&gt;

&lt;p&gt;What does the Frontier kernel bring to the table, and what value
does it have?&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;b&gt;The &quot;Object&quot; Database&lt;/b&gt;: (Since it was named, the word &quot;Object&quot;
has acquired a more technical definition, hence the scare quotes.) The
Object database is a neat piece of code but is somewhat less useful
then it used to be. Metakit in particular seems to have left the ODB
in the dust. I like the interface the ODB offers, but I could create a
very, very thin layer on top of Metakit to provide that functionality
if I cared (especially in pure Python).&lt;br&gt;&gt;&lt;br&gt;

I say the value depends on the quality of the code; get ready to hear
this a lot. If it&apos;s high quality, it might be extensible to handle
other datatypes, correct some of the worrisome bugs that sometimes pop
up, and possibly support more metadata, which might allow for some
more interesting program styles. If it&apos;s low quality, I&apos;d say, the
best thing to do is probably replace it with Metakit or a similar
product underneath. You can easily match the interface that the rest
of Frontier expects, you&apos;ll tap into a robust and current product, and
hopefully the performance wouldn&apos;t be too bad... might even increase,
I don&apos;t know. (The down side is the threading issue; metakit doesn&apos;t
thread well. However, if you serialize access it&apos;s OK, and I wouldn&apos;t
be surprised that&apos;s exactly what Frontier does internally
anyhow.)&lt;br&gt;&gt;&lt;br&gt;

My call: The ODB&apos;s most interesting feature today is it&apos;s interface:
You just can&apos;t beat root.value = 3 for convenience. The
implementation is probably defunct. However, the good news is
replacing the implementation &lt;i&gt;should&lt;/i&gt; be easy, the internal
interface &lt;i&gt;should&lt;/i&gt; be clean. If it isn&apos;t, big strike against
Frontier.&lt;br&gt;&gt;&amp;nbsp;&lt;li&gt;

&lt;li&gt;&lt;b&gt;The library code&lt;/b&gt;: Reasonably solid. Letting third parties
in to extend it is probably a good idea. It has a lot of little bugs
and quirks which Userland simply hasn&apos;t had the man-power to fix; for
instance, Frontier&apos;s XML support continues to be dangerously quirky
and needs a standards-compliance work over. Most of the bugs are
little, but need a lot of testing to validate correctness, and that
some fix didn&apos;t break some other aspect. (Y&apos;all can start by looking
in my Jabber library; there&apos;s some tests there that are clearly
labelled as breaking in the current Frontier, and last time I tried
them around last February they were still broken.) The value here is
again determined by the quality of the code, and how easy it will be
to fix the bugs without breaking other things.&lt;br&gt;&gt;&lt;br&gt;

On that topic, I don&apos;t know what testing methodologies are used in
Frontier, but I strongly suspect the addition of a unit-test-based
test suite is called for. This would largely alleviate the fear Dave
justifiably has of breaking the library code. It also provides a path
for Userland to validate that the open-sourced Frontier continues to
meet their needs; if the unit tests continue to pass, the project
most likely hasn&apos;t broken their code.&lt;br&gt;&gt;&lt;br&gt;

My call: Cleaned up and properly tested, the library code has value. What I
can&apos;t tell you is whether it any longer has a &lt;i&gt;niche&lt;/i&gt;. There&apos;s
hardly a function in Frontier I can think of that doesn&apos;t have a match
in stock Python. (Excepting the outline functions, which I now have a
match for in Iron Lute, so for me personally at least it&apos;s still a
wash ;-) ). Or stock Perl, or easily acquired Java
libraries.&lt;br&gt;&gt;&amp;nbsp;&lt;li&gt;

&lt;li&gt;&lt;b&gt;Development environment&lt;/b&gt;: But one advantage I&apos;d say Frontier
still clearly holds over Python is the development environment. The
debugger is superior to any Free product I&apos;m aware of for Python, and
the windowing system is nice. I intend to treat the outliner
seperately, but the environment makes good use of it.&lt;br&gt;&gt;&amp;nbsp;&lt;li&gt;

&lt;li&gt;&lt;b&gt;Cross-platform-ness&lt;/b&gt;: It&apos;s nice that it works in Windows and
Mac, but I wonder what it would take to get it into Linux. My guess,
honestly, is that it would be a hell of a lot of work, even leveraging
Wine. My call: Marginal, but working on Windows is surprisingly rare, so may be useful.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Outliner&lt;/b&gt;: Ah, something near and dear to my heart, since
the closed-source nature of Frontier is a major component of what
drove me to create Iron Lute in the first place.&lt;br&gt;&gt;&lt;br&gt;

As I&apos;ve pointed out elsewhere, &lt;a href=&quot;http://www.jerf.org/iri/categories/Iron%20Lute/2004/01/12.html&quot;&gt;there
are no usable outliner widgets&lt;/a&gt; in the open source world. As a
result, a lot of my Iron Lute time has been spent hacking and kludging
a workable outline widget out of Tk. One of the things that will be
most interesting to me personally is how flexible and salvagable the
outline widget in Frontier will be.&lt;br&gt;&gt;&lt;br&gt;

On the other hand... the other design objections I&apos;ve had to
Frontier&apos;s outlines will remain intact, and if there&apos;s one thing I&apos;ve
learned as I wrote Iron Lute, it&apos;s that I have &lt;i&gt;zero interest&lt;/i&gt; in
trying to replicate my current outline.py in C. So its value to me
personally is not as great as it would have been a year or two
ago.&lt;br&gt;&gt;&lt;br&gt;

How far other people will be interested in taking it is another
story. Depending on the timing of the Frontier source release and
subsequent community formation, and of when I get a steady enough job
that I feel like I can once against dedicate my time to a hobby rather
then work, the story may change. One interesting possibility is if the
Frontier crowd makes it easier to reach in; perhaps Iron Lute could
become an alternate interface to the Frontier Core, perhaps even
eventually replacing the current one for most people. Or perhaps
they&apos;ll make enough progress that I&apos;ll feel compelled to work with the
Frontier project to improve the current outliner up to the specs I
think a modern outliner should have. Who knows?&lt;br&gt;&gt;&lt;br&gt;

My call: Once again, it depends on the quality and extensibility of the current
code, whether it&apos;s at its end-of-life or not, and how much interest in
shown in the ideas I&apos;ve put forth on my &lt;a href=&quot;http://www.jerf.org/ironlute/&quot;&gt;Iron Lute blog&lt;/a&gt;. We&apos;ll have to
see.&lt;/ul&gt;

&lt;p&gt;I think that largely covers the Frontier Core as it is being
released. My final conclusion: I am positive about its release, but
only cautiously optimistic about its value in the current
environment. If it had been open sourced several years ago, it would
have much more value to attract developers. It&apos;s bringing value to the
table, but also a lot of bugs and work that needs to be done. Quality
of the code is paramount; if it&apos;s undocumented and opaque, I don&apos;t see
it ever collecting enough developers to matter.&lt;/p&gt;

&lt;p&gt;As for what it means to me personally w.r.t. Iron Lute: Iron Lute
is in stasis anyhow, so I can afford to wait and see. However, I don&apos;t
expect that it will be worthwhile for me to try to merge my code back
into an existing project, code that would require a deeper integration
with Python on the Frontier side before it mattered anyhow. I expect
that at best, a look at the Frontier code might teach me something,
but I don&apos;t expect to be terribly surprised by what I see in
there. One of the reasons for starting Iron Lute may be defunct by now
but I&apos;m far enough in that it&apos;s worth just continuing on. Assuming I
can ever get back to it, Iron Lute will continue to offer a lot that
even a retro-fitted Frontier won&apos;t be able to match for a while.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Addendum to initial post&lt;/b&gt;: Looking around, there are two things I forgot to talk about in the original post.&lt;/p&gt;

&lt;p&gt;First, Frontier does have good support for non-programmers, especially in the Macintosh world. This is a very legitimate offering and would be an excellent niche for the Frontier kernel to deliberately pursue. Scripting in the Microsoft Windows environment is also largely a wide-open field; I forgot about this one because I&apos;ve been living in the Linux world for so long now, where scripting is largely a given; in fact one must choose from an embarassing profusion of languages.&lt;/p&gt;

&lt;p&gt;Second, the &lt;i&gt;technology&lt;/i&gt; in Frontier, as useful as it is, is at the end of its life, I believe. You can see a hint of that in my ODB description above, where the technology is obsoleted and I think the best course of action would be to replace it with something else. In fact, I think that one of the best things an Open Source Frontier could do is take the plunge, sidle up to Python, and work on becoming a Python application that also happens to run Usertalk.&lt;/p&gt;

&lt;p&gt;Why? First, Python is a sophisticated and developing language that allows for a lot of things that UserTalk doesn&apos;t, but really should. There are a lot of features in  Python that would allow for even simpler APIs for beginning scripters. Second, it opens up a whole new technology world for Frontier with minimal investment; database APIs, real GUIs, and yes, even the possibility of integrated Iron Lute ;-)... but seriously, Frontier would probably be best served by this style of integration because it would benefit from the work of a &lt;i&gt;much&lt;/i&gt; larger community. Nobody in the Frontier world is going to tie into GTK or QT, nobody&apos;s going to integrate with Linux stuff otherwise.&lt;/p&gt;

&lt;p&gt;Frontier&apos;s best hope for continuing relevance is to focus on what it does better then anybody else, being a powerful scripting environment for beginners, and migrating off of its internal proprietary technology as quickly as possible. Honestly, I deeply respect Frontier, because it was literally a decade ahead of its time when it first came out. However, it is now about five years behind the time, and rather then trying to &quot;catch up&quot; with a small community, it would be better served by trying to connect to a modern one.&lt;/p&gt; </description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/05/18.html#P2414</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<category domain="http://www.jerf.org/iri/">Personal Commentary</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
<ent:topic ent:id="Personal Commentary" ent:href="http://www.jerf.org/iri/categories/Personal Commentary/">Personal Commentary</ent:topic>
</ent:cloud>
<pubDate>Tue, 18 May 2004 08:25:36 GMT</pubDate>
</item>
<item>
<title>Iron Lute back burnered</title>
<description>Well, Iron Lute is getting firmly placed on the back burner, &apos;cause I&apos;ve been laid off my job and I need to concentrate on things that will make money. I do intend to get back to it but I have no idea when that will be.</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/04/06.html#P2392</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<category domain="http://www.jerf.org/iri/">Personal Commentary</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
<ent:topic ent:id="Personal Commentary" ent:href="http://www.jerf.org/iri/categories/Personal Commentary/">Personal Commentary</ent:topic>
</ent:cloud>
<pubDate>Tue, 06 Apr 2004 20:39:28 GMT</pubDate>
</item>
<item>
<title>XML Mapping to and from Objects</title>
<description>Today&apos;s post is about one of the little libraries I&apos;m developing as
part of Iron Lute. In the previous posts, I&apos;ve laid out what I believe
were successes; today I highlight what is so far a failure for a
change of pace.

&lt;p&gt;Please note that today&apos;s post is really more of an XML post then an
outliner post; if you&apos;re interested in programming with XML, stay
tuned. If you&apos;re only interested in outlining, you should probably
move on. I&apos;ve tried in the previous posts to be accessible to
interested laymen, but this one may also be only useful to
programmers. Consider yourselves fairly warned.&lt;/p&gt;

XML Marshalling

&lt;p&gt;Assume that we actually know how to use Object Orientation to our
advantage. Suppose we want to transfer data via XML, without 
restriction importing from or exporting data to XML documents.&lt;/p&gt;

&lt;p&gt;As anyone who has worked with this knows, objects do not
automatically map out to XML. There are libraries that help take XML
into objects, like DOM, but you do not get to choose the objects, or
if you do, you are still constrained to the XML format. In the other
direction, you get things like this &lt;a href=&quot;http://gnosis.cx/download/gnosis/xml/pickle/&quot;&gt;module for Python
that will implement the &quot;pickle&quot; module in XML&lt;/a&gt;, but good luck
using such language-specific marshalling in any other environment.&lt;/p&gt;

&lt;p&gt;In OO terms, both styles of library end up causing excessive
coupling, either couple the XML to the object model (to the detriment
of others who would like to read the XML), or coupling the object
model to the XML (which almost inevitably results in serious
compromises to the power, flexibility, and usefulness of the object
model).&lt;/p&gt;

&lt;p&gt;If you want to retain flexibility, you generally need to write a
seperate marshalling layer for your objects, which will manage both
the translation in both directions. Then, your XML format and data
structure may both be optimized for their respective uses with no
compromises, but at the cost of maintaining this extra layer.&lt;/p&gt;

&lt;p&gt;In Iron Lute, which will deal with both XML and non-XML formats,
I&apos;ve implemented this as a &quot;filetype&quot; abstraction, which is a Python
module that keeps track of some metadata and some classes which are
responsible for knowing how to converting the target format to and
from the outline nodes in the memory format I&apos;ve discussed
earlier.&lt;/p&gt;

&lt;p&gt;Quite a lot of those file types are of course XML or XML-like. I
began to conciously recognize something that had been percolating in
my subconcious already: In that middle layer, there is a &lt;i&gt;lot&lt;/i&gt; of
redundency. It is a peculiar kind of &quot;paired&quot; redundency, where the
same &lt;i&gt;pairs&lt;/i&gt; of operations are repeated, over and over again.&lt;/p&gt;

&lt;p&gt;For one common example, it is quite typical to have something like
the HTML element &amp;lt;ul&amp;lt;, which may contain
&amp;lt;li&amp;gt;&apos;s. From the XML into the Object Model, you have
code that switches into some sort of &quot;ul&quot; mode, and reads the
subsequent li&apos;s into a container object. Going the other way,
you iterate over the container object and spit out each of the
li&apos;s into the XML stream.

&lt;p&gt;&lt;img src=&quot;http://www.jerf.org/images/xml.mapping.png&quot; border=&quot;1&quot; align=&quot;left&quot; alt=&quot;&quot;&gt;Because of this similarity, I began the process
of factoring this similarity out. Of all the aspects of Iron Lute,
this is by far the most experimental. Outliners have been done before;
in the end the only truly novel bullet-point feature Iron Lute may end
up with is that it is &quot;quality open source Python&quot;. To my knowlege,
the only other attempt at this sort of XML library is a Java library
called &lt;a href=&quot;http://java.sun.com/xml/jaxb/&quot;&gt;JAXB&lt;/a&gt;, and
truthfully I&apos;m not certain that that library is aiming for 100%
indepedence of the XML and custom objects like I am; rather it still
seems to defer a lot of the structure of the data objects on to the
XML format itself.

Theory: Why Is This A Good Idea? 

&lt;p&gt;XMLMapping (the current name of the library, which is horrid) is
built on the idea that you may have a pre-existing XML format, and a
pre-existing Object Model, and you may not want or even be &lt;i&gt;able&lt;/i&gt;
to bend one to suit the other.&lt;/p&gt;

&lt;p&gt;In theoretical terms, this means that XMLMapping completely
decouples the XML format from the data format. When you put it that
way, I&apos;m surprised that there hasn&apos;t been more work in this area.&lt;/p&gt;

&lt;p&gt;The ideal I&apos;m shooting for is to be able to blur the distinction
between the XML representation and the object, with no compromises on
either the XML representation or the object design. This flexibility
opens a lot of doors, like being able to throw objects into a Jabber
stream, or directly over a socket, with very little difference in
code.&lt;/p&gt;

&lt;p&gt;Theoretically, you get the benefits of a native OO representation
and a native XML representation at the price of writing a description
of a translation layer, which at least in theory should be fairly
redundant between various mappings, and thus I should be able to
provide significant chunks of the transform as library code that can
be pieced together into what you need. (For instance, the
aforementioned Container behavior is very popular, and easy to
abstract into a component, even though that generalized component is
moderately complex.)&lt;/p&gt;

&lt;p&gt;Another way of looking at this is that it is a library for creating
modular and extensible SAX-based XML parsers and a generalized XML
output system, all at once.&lt;/p&gt;

Practice: The failure

&lt;p&gt;In practice, there are two major problems:&lt;/p&gt;

&lt;ol&gt; 
&lt;li&gt;Even the simplest transforms require a lot of information. It&apos;s
&quot;declarative&quot; information, not programming per se, but it&apos;s still a
&lt;i&gt;lot&lt;/i&gt; of typing in Python.&lt;/li&gt;
&lt;li&gt;Getting the library code correct is challenging.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first can (and I believe should) be solved by created a
&quot;mini-language&quot; that allows the use of non-Python syntax to concisely
and efficiently express the transform. The second is only solvable by
continuing to pound on the problem. ;-)&lt;/p&gt;

&lt;p&gt;The second one has been the killer. Basically, you need to have
some sort of concept of &quot;piece of XML&quot; that maps to &quot;piece of an
object&quot;. Perhaps surprisingly, it is the first part that has been
giving me fits. A &quot;piece of an object&quot; can be relatively easily
specified in by a function or pair of functions, so if I want to for
example map the &quot;header&quot; member of some object to the XML, I can
specify the &apos;header&apos; member quite simply as:&lt;/p&gt;

&lt;p&gt;lambda obj: obj.header

&lt;p&gt;and for convenience it is trivial to define well-named helper
functions that make this look ok:&lt;/p&gt;

&lt;pre&gt;def member(memberName):
    return lambda o: getattr(o, memberName)
member(&apos;header&apos;)&lt;/pre&gt;

&lt;p&gt;It is defining a &quot;piece of XML&quot; that has been hard. This
&quot;piece of XML&quot; concept needs to work in two contexts:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;When XML is being read in, the XMLMapping interpreter needs to
process each &quot;piece of XML&quot; in sequence.&lt;/li&gt;
&lt;li&gt;When XML is being generated, each mapping element outputs a &quot;piece
of XML&quot;.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;The tension between these two uses is what is driving me nuts. For
the second concern, the answer is obvious: Just output chunks of XML
as needed, precisely as any conventional XML output system does. The
downside is that that&apos;s not useful to the reader; as one small
example, in isolation, &amp;lt;/integer&amp;gt; is useless. To understand that
chunk of XML, you need the whole thing:
&amp;lt;integer&amp;gt;54&amp;lt;/integer&amp;gt; still needs some context to
be understood but it is certainly plausible that the Python expression
54 adequately captures the meaning of that chunk.

&lt;p&gt;(I know there are some evident solutions to the problem as
described above, but remember that the preceding paragraph is in some
sense a transliteration of a problem in the &lt;i&gt;code&lt;/i&gt;; an English
solution to the English formulation of the problem is not helpful. All
of the simple English solutions I&apos;ve come up with don&apos;t translate into
code, since they all require human discretion to work correctly.)&lt;/p&gt;

&lt;p&gt;I initially started with deciding that a &quot;tag&quot; is the root unit of
XML, but I have encountered several difficulties. First, consider the
OPML format: The body has only one tag name, outline, but we
almost always want to switch based on the nodetype, which is actually
an attribute. So the tag name isn&apos;t sufficient, we need to match on
the whole tag as well.

&lt;p&gt;One can equally well imagine wanting to switch off of contents of a
tag, too.&lt;/p&gt;

&lt;p&gt;I&apos;ve also encountered a wide variety of other potential issues as I
try to use this library. For instance, I found myself wanting to have
a &quot;null wrapper&quot;; an Iron Lute document is currently just a stream of
nodes and links, so to bundle it into an XML document I just need to
wrap them in a root element. The code as written couldn&apos;t handle a &quot;do
nothing&quot; element; it wanted to parse and understand every single
tag. Coding around this required several lines of icky, fiddly
code.&lt;/p&gt;

&lt;p&gt;One can imagine other circumstances where you might want to
ignore entire chunks of a document. For instance, someday one might
want to specify something by an XPath expression and parse just that
chunk of XML.&lt;/p&gt;

&lt;p&gt;I&apos;m still optimistic I can make this work usably, and if I do I
still think it will be quite impressive, and all the more satisfying
for the challenge it was to create. I can see why previous attempts
haven&apos;t been as ambitious though ;-)&lt;/p&gt;

&lt;p&gt;Well, you know what they say, you learn a lot more from failure
then success.&lt;/p&gt;

&lt;p&gt;In development news, I&apos;m getting close to at least a prototype of
the Iron Lute file output format being usable. Some other touch-ups on
the xml mapping code here need to be made, which fortunately will
carry over directly into any future version of the library anyhow so
that&apos;s not time lost. After that we get the GUI going, then just a
couple more pieces of developer support before we get going that I
don&apos;t want to release without and I&apos;ll have myself an alpha
release.&lt;/p&gt;

&lt;p&gt;Unfortunately, due to unavoidable life issues development may be
slowing down on Iron Lute for a long period of time; my development
time needs to go elsewhere. I&apos;ll work what I can in, but it&apos;s no
longer my highest development priority. The new #1 priority is much
less fun, but, well, life doesn&apos;t always go as we plan.&lt;/p&gt;&lt;/img&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/04/05.html#P2391</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Mon, 05 Apr 2004 16:42:40 GMT</pubDate>
</item>
<item>
<title>&quot;Distractions&quot; post on Iron Lute</title>
<link>http://corky.net/dotan/log/2004/03/iron_lute.html</link>
<description>Dotan Dimet has some comments on Iron Lute, which I think contains some misunderstandings about Iron Lute that mostly stem from the developer-centric view of Iron Lute y&apos;all have seen so far. I posted a comment containing some follow-up on his post, and I replicate it here for posterity and RSS readers. Note it contains links to some of the actual code which I posted to provide evidence of how hard it will be to provide bi-directional text support in Iron Lute, so if you want to see  some of my actual code, now&apos;s your chance. Comment I posted follows:

&lt;blockquote&gt;&amp;quot;Iron Lute, on the other hand, looks like another case of someone
falling in love with the technology....&amp;quot;

&lt;p&gt;I strongly disagree. Iron Lute is being created because there is no
good platform to create LEO on. LEO is, with all due respect, a hack
with regard to outlines, in the sense I can&apos;t build anything
interesting on top of that, other then LEO. I don&apos;t care about outlines
intrinsically and I look forward to the day I can actually do things
with them. If a good platform existed (in a reasonable, non-Java
language) I would have used it in a heartbeat. Unfortunately, no such
open platform exists.&lt;/p&gt;

&lt;p&gt;I think you&apos;ll see that even in the initial alpha release, the user
focus will be on &amp;quot;what you can do&amp;quot; with Iron Lute, and not just &amp;quot;the
outliner&amp;quot; aspect of it. Remember what you&apos;re reading now is developer
documentation, not user documentation. That&apos;s waiting until closer to
the release.&lt;/p&gt;

&lt;p&gt;&amp;quot;Pity he&apos;s making the same mistake (well, &amp;quot;short sighted
decision&amp;quot;) made in Leo by choosing a GUI toolkit that doesn&apos;t support
BiDi.&amp;quot;&lt;/p&gt;

&lt;p&gt;Only Tk has had the flexibility to do what I need. Text
widgets that support BiDi don&apos;t support other things I absolutely need
(like &amp;quot;how big is this text, wrapped?&amp;quot;) so unfortunately they are not
on the table. Tk would have been nearly my last choice, but it&apos;s the
only one that worked.&lt;/p&gt;

&lt;p&gt;(At least Tk supports Unicode!)&lt;/p&gt;

&lt;p&gt;Even the Tk widgets aren&apos;t ideal and need a lot of massaging to work right. How much massaging? Let me show you ;-) Here&apos;s the &lt;a href=&quot;http://www.jerf.org/ironlute/textnodewidget.py&quot;&gt;code for each node in the outliner&lt;/a&gt;, and here&apos;s &lt;a href=&quot;http://www.jerf.org/ironlute/outlineframe.py&quot;&gt;code for the outline frame that ties them together into an outline&lt;/a&gt;.
That&apos;s 70 KB of Python code (using a conservative *3 for C/C++ code,
that&apos;s 210KB, bigger then many novels), and it&apos;s still incomplete.&lt;/p&gt;

&lt;p&gt;The GUI is abstracted from the code so if GTK or QT ever get
their act together relative to my needs it would be relatively little
work to get the support in there. (I actually started some wxWidgets
work on Windows but I couldn&apos;t make it work without intolerable
flashing, even after I hacked on the C++ code of wxWindows itself. But
it was far enough to show the separation works.)&lt;p&gt;
The other problem is that I have to do all the geometry
management of the nodes myself, so BiDi and other issues are going to
require a lot more code then in most projects. A lot of very, very
sensitive code. See that stuff in outlineframe.py, like the
syncWithDocument method or moveCursorToWidget? All very touchy, all
needing to be modified for BiDi. Unfortunately, and I really mean that,
it&apos;s not just flipping a switch in the code, even if GTK gives me what
I need :-(, it&apos;s a massive and bug-prone re-write of the GUI guts of
the project.&lt;/p&gt;

&lt;p&gt;The good news is that it should at least be possible someday.&lt;/p&gt;

&lt;p&gt;I&apos;m going to link to this on my &apos;blog, as long as I&apos;ve decided to share some of the code might as well do it for everyone ;-)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which I did.&lt;/p&gt;

&lt;p&gt;Thanks for the commentary and feedback. I hope this doesn&apos;t sound hostile, because misunderstandings about the nature of Iron Lute are entirely my fault, until it is released and can be actually used, so I don&apos;t &quot;blame&quot; Dotan Dimet for anything and actually value the chance to explain myself more clearly.&lt;/p&gt;

&lt;p&gt;A stronger focus on &quot;what can we do with the outliner?&quot; will become evident when I start talking about how I&apos;ve abstracted saving and loading from various formats and various file-like things, and it will become more clear how Iron Lute&apos;s focus is on the user, not the technology. (It&apos;s just that you can&apos;t skip the technology step, unfortunately.) The power of loading and saving OPML(or any other supported format) to various sources, not just files, will be clear. (For example, I already support loading and saving OPML to and from Manila sites, just to make sure the support was working and useful.)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Minor update&lt;/b&gt;: It occurs to me that it is worth mentioning why I tried wxWidgets on Windows. It turns out that only Windows has a rich text widget that you can ask, &quot;Given the width you currently have and the formatted text you currently have, how much vertical screen space do you need to completely display the text?&quot; This is very useful in many circumstances. Unfortunately, the rich text widgets had too many other flaws for what I needed to be useful, including but not limited to excessive flashing that I couldn&apos;t stop (even after trying every permutation of &quot;double buffering&quot; flags the widget supports), fears of massive incompatibilities due to there being at least 4 distinct versions of the Rich Text widget with no way for me to ship the one I need, and inability to control or even detect certain keypresses that are built-in to the widget (for example, I couldn&apos;t detect a &quot;CTRL-+&quot;, which increases the size of every font in the widget, which in the outliner would require re-sizing the text widget itself; I&apos;d either want to catch that event or prevent it, but I couldn&apos;t do either). Any one of them was a stopper; together they led me to believe Iron Lute isn&apos;t ever going to be feasible in Windows without writing a complete text widget from scratch, which isn&apos;t worth it to me. (Note that Tk &lt;i&gt;is&lt;/i&gt; a complete text widget from scratch, it doesn&apos;t use Windows code to draw except for font rendering, and I&apos;ve had perfect luck so far programming in Linux and having it work perfectly in Windows. Windows even looks better since it gets anti-aliasing the Linux Tk does not.)&lt;/p&gt;

&lt;p&gt;As far as I can see, neither the Windows rich text editor, nor the Macintosh rich text widget, nor QT, GTK, FLTK, wxWidgets, or the Fox toolkit can do what I need them to do. If Tk couldn&apos;t do it, there&apos;d be no Iron Lute (or perhaps I would have dived into console-only, but that would not be fun). I&apos;ve analysed each of them for what I need, even the very latest of QT and GTK, and they are all lacking in almost the exact same ways: I can&apos;t talk about formatted text in the widgets, I can&apos;t (usually) get the screen coordinates of the cursor, and there&apos;s no way to klude what I need.&lt;/p&gt;

&lt;p&gt;(I need those things because I absolutely &lt;i&gt;insist&lt;/i&gt; that when you press the &quot;up&quot; key on the top line of a given node, that you go to the bottom line of the next node up, and that you go to the roughly correct column in that widget... just like every other professional outliner I&apos;ve ever seen. Anything less will not be usable. Without the ability to get the screen coordinates of the cursor, and set the cursor to other screen coordinates, this feature is impossible. And laying the nodes out on screen without being able to ask the toolkit &quot;how big is this text&quot; is really hard; I ended up re-implementing the Tk layout algorithm in Python, or at least something close to it, but if it changes or if I&apos;m wrong, wierd and bad things happen on the screen. I&apos;d rather not have to match it...)&lt;/p&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/03/24.html#P2382</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Wed, 24 Mar 2004 16:44:48 GMT</pubDate>
</item>
<item>
<description>I have a case of the multi-disciplinary writer&apos;s block. 

&lt;p&gt;I&apos;m having a hard time writing the outline saving code in Iron Lute. I have an essay I want to post here, but it is obstinately refusing to go into focus. (I may yet just post it in a nebulous state, as I&apos;m not convinced it&apos;s &lt;i&gt;ever&lt;/i&gt; going to focus, by its very nature, but I think it&apos;s important that I write it.) I also have a technical post on the inner workings of Iron Lute which I&apos;m having a hard time writing; I&apos;ve mostly written it, but it&apos;s quite dull.&lt;/p&gt;

&lt;p&gt;Yes, that&apos;s right, even &lt;i&gt;more&lt;/i&gt; dull then the existing postings! I figure someone ought to be interested in those because I would be, but I wouldn&apos;t want to read this posting as written.&lt;/p&gt;

&lt;p&gt;Going backwards, I know why the Iron Lute essay is dull, though I am surprised. For a change of pace, I was going to show a failure I&apos;ve experienced, to contrast the successes I&apos;ve mentioned to date. I&apos;ve been able to explain why it should have been a success, but explaining why it is a failure has proven difficult. (Perhaps this is because the only &lt;i&gt;real&lt;/i&gt; failure is that it is too difficult to use, not that it &quot;doesn&apos;t work&quot;, and it&apos;s hard to show in prose why that is. You really have to try to use it yourself to understand why it is hard to use.) I am intrigued by how this is almost exactly the opposite of conventional journalism, where disaster stories write themselves (assisted with a heavy helping of cliches and standard idioms) but good news is hard to write.&lt;/p&gt;

&lt;p&gt;I haven&apos;t been able to work on the code out of lack of motivation. I&apos;m sure it will come back, it always does, but that&apos;s one of the &lt;i&gt;major&lt;/i&gt; downsides of Free Software; it gets released when I&apos;m good and ready and if that means I want to take a month off to play video games, well, that&apos;s what I&apos;m gonna do. ;-) (OK, it&apos;s only been the last week, but it has been quite relaxing and rejuvanating. I&apos;m sure the code-monkey will get back on my back here soon.)&lt;/p&gt;

&lt;p&gt;Finally, the essay has been just plain, ole&apos; fashioned hard to write. It&apos;s about negativity in weblogs and journalism, and how it is affecting me, and I believe others, emotionally, but I&apos;ve had a hard time keeping a strong thesis in it, mostly because the emotional effects are quite diverse. Hopefully it will come together, because I feel quite strongly we need to start critically exploring the new media world we are building to see how we fit in as humans, and indeed, &lt;i&gt;whether&lt;/i&gt; we fit in as humans.&lt;/p&gt;

&lt;p&gt;Here&apos;s hoping at least one of the blocks breaks soon.&lt;/p&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/03/23.html#P2380</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<category domain="http://www.jerf.org/iri/">Personal Commentary</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
<ent:topic ent:id="Personal Commentary" ent:href="http://www.jerf.org/iri/categories/Personal Commentary/">Personal Commentary</ent:topic>
</ent:cloud>
<pubDate>Tue, 23 Mar 2004 15:19:28 GMT</pubDate>
</item>
<item>
<title>Iron Lute progress update</title>
<description>Just a quick note: I&apos;m still working on the XML save format for Iron Lute outlines. I&apos;m trying to use a library I&apos;ve put together for XML serialization and it&apos;s not going so well right now. I think it still has potential but I may need to re-work it into a &quot;version 2&quot;, because version 1 is sucking pretty badly.</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/03/15.html#P2379</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Mon, 15 Mar 2004 21:32:48 GMT</pubDate>
</item>
<item>
<title>Outlines, Part 6</title>
<description>In my previous post, I discussed the practical matter of how to
hold the outline structure we&apos;ve built so far together. Having created
a strong base, it is now fruitful to consider how to extend the data
structure to handle the wide variety of outline structures I want Iron
Lute to be able to manipulate.

Node Types

&lt;p&gt;One of the most interesting possibilities inherent in this
structure is to formally recognize that there are a &lt;i&gt;lot&lt;/i&gt; of
potential different types of nodes that can be built.&lt;/p&gt;

&lt;p&gt;Every outliner I&apos;ve seen has at least some informal idea that there are
different types of nodes; in pre-Node Type Frontier, the menus were
implemented as extensions of outlines, in many other outliners they
use attributes to try to declare some limited idea of node type (like
&quot;isComment=&apos;1&apos;&quot; and such things). But formal recognition of the fact
that we want lots of different types of nodes allows us to formally
support them, define them, and allow paths to extend them.&lt;/p&gt;

&lt;p&gt;As an existing example, implemented in Radio Userland and Iron
Lute, is the OPML Transclusion node. In Radio Userland, it is
expressed as a node type of &quot;link&quot;, in Iron Lute, I have an
&quot;OPMLTranscluder&quot; (to seperate the OPML-specific semantics from other
potential transclusion types, and because OPML is just one particular
format to Iron Lute, it&apos;s not built on it).&lt;/p&gt;

&lt;p&gt;What does that mean? It means that the node can bundle certain
actions along with it, and carry data with it. In other words, it
almost exactly parallels the &quot;class&quot; idea in OO, so in Iron Lute we
actually build it on classes.&lt;/p&gt;

&lt;p&gt;An OPMLTranscluder node knows to load a remote OPML file if it is
opened. Many other type of nodes can be imagined, each carrying their
own verbs with them whereever they may go. A lot of things can be
expressed as Node Types that you might not initially realize.&lt;/p&gt;

&lt;p&gt;For instance, I envision a web site based on outlines, instead of
files and database entries. (Kinda like Channel Z, but &lt;i&gt;really&lt;/i&gt;
deeply outline oriented; I&apos;ve recently been impressed with how
HTML::Mason works in Perl and I think it&apos;ll end up looking like that
with &quot;outlines&quot; in place of &quot;components&quot;.) &quot;Comment Entry Field&quot; can
itself be a particular node. Expanding it might let you view the
comments made to date. Each comment would itself be a Comment type
node, and might know who made the comment. The comment would carry
commands with it, so you might be able to right-click and select &quot;Ban
User/IP&quot;.&lt;/p&gt;

&lt;p&gt;Removing a comment would be as easy as just deleting it. You could
edit/censor the comment if you were the site owner, re-order the
comments, or do any of the other outline manipulations and it would
all work. If you decided you didn&apos;t want any comments at all, you
could delete the entire Comment node from the posting, and all the
comments, plus the ability to add new ones, would disappear. So you
could easily allow comments on a post-by-post basis.&lt;/p&gt;

&lt;p&gt;Moreover, it&apos;s just a node. You could allow multiple distinct
comment fields per posting, or move the comment field to another post,
move comments from post to post, have the exact same comment field
show up in multiple places (different pages of one article), etc. I
see a very flexible and interactive web site developing from this,
with a different content philosophy then modern web sites.&lt;/p&gt;

&lt;p&gt;The website itself will be viewed as HTML by running the engine
part of Iron Lute on the web server and rendering things as HTML. Of
course, templates and such can already be represented as outlines;
that&apos;s proven technology.&lt;/p&gt;

&lt;p&gt;This is just one small instance of how much fun it might be to have
such a clear, consistent, and powerful interface to data available to
us. Replicating any of this in current architectures is of course
possible, but with outlines and an outliner, the capabilities are
clean, cheap, and extend well.&lt;/p&gt;

&lt;p&gt;There&apos;s also some internal uses; I&apos;ve implemented the menus as
outlines (though as of this writing they don&apos;t cascade, that&apos;s only
because I haven&apos;t needed it yet), and later internal configuration
will be available in an outline form, with nodes holding
preferences.&lt;/p&gt;

&lt;p&gt;Node types are, as I&apos;ve mentioned earlier, the fundamental Good
Idea that drove me to write Iron Lute. I&apos;m still excited by the
prospect of having this stuff to play with; I only wish I was already
done with the &quot;hard work&quot; to get here.&lt;/p&gt;

&lt;p&gt;I don&apos;t have access to all of the closed-source outliners so I&apos;d
like to explicitly disclaim the possibility that they may have a
wonderfully clear abstraction, since many of them do seem to have a
relatively rich set of things that look a lot like Node Types. Without
a developer API that can tap into that power, though, who cares?&lt;/p&gt;

Document Types

&lt;p&gt;Every document can have a &lt;i&gt;document type&lt;/i&gt;, which can also
define behaviors and commands for every node it contains. For
instance, in the web system I allude to above, whenever you are
editing a document, you&apos;ll have a command in the Document menu to
insert a new comment area. (You can see the Document menu in &lt;a href=&quot;http://www.jerf.org/images/ironlute.png&quot;&gt;screen shot&lt;/a&gt;, dimmed
out because I haven&apos;t come up with any reasonable &quot;document commands&quot;
for the default, neutral document that aren&apos;t really generally useful
commands that belong in the main menus.)&lt;/p&gt;

&lt;p&gt;Another useful aspect in the general case is &quot;embedded document&quot; or
&quot;composite document&quot;. Imagine editing a Perl program, and having an
HTML &quot;here&quot; document in it. Iron Lute will be able to provide full
HTML support inside of the &quot;here&quot; document while still providing full
Perl support in the normal document, with no &quot;hacks&quot; necessary. This
comes up surprisingly often, and the ability to do it cleanly will
bring forth even more applications when one document is &quot;embedded&quot; in
another.&lt;/p&gt;

&lt;p&gt;One thing I&apos;m planning on is to segregate the keyboard commands
based on whether they are &quot;node&quot; or &quot;document&quot; commands; I&apos;m planning
on reserving &quot;ALT&quot; for document commands, whereas I want to leave CTRL
(w/ or w/o SHIFT) for node commands. (The user can re-configure this
away if they like but I wouldn&apos;t recommend it.)&lt;/p&gt;

More Structured Node Text

&lt;p&gt;Most outliners have some capability of supporting at least
formatted text. I want to take the next step, and support smarter
formatting.&lt;/p&gt;

&lt;p&gt;Radio Userland already supports at least one special case of this;
IIRC correctly, you can click an HTML link and follow it. Most, if not
all, outliners allow formatted text. I want to generalize this, so
that you can declare &quot;tags&quot; and decorate text with them (just as you
decorate text with &quot;bold&quot; and &quot;italic&quot;), and allow the text itself to
carry any useful commands, formatting, intelligence, etc. that it
needs to.&lt;/p&gt;

&lt;p&gt;Of course you can build the standard &quot;bold&quot; and &quot;italic&quot; on top of
this, but you would then easily be able to build other things on top
of it too, like an &quot;HTML link&quot;. An &quot;HTML Link&quot; is a tag that turns the
tagged text blue, underlines it, and when right-clicked, presents (at
least) two choices: Edit the link destination, or open a browser on
that link. In some ways it&apos;s &lt;i&gt;easier&lt;/i&gt; to define the generic
capability then build the simple things on top of it.&lt;/p&gt;

&lt;p&gt;The spell-checker will tap into this; a spellchecker watches the
words in a node, and marks misspelled words with a tag that changes
the formatting and when selected, gives the usual correction options.&lt;/p&gt;

&lt;p&gt;As of this writing, I&apos;m not entirely certain how this is going to
be done, but I am fairly certain you will be able to define your own
tag types and provide them with context-specific commands in a clean
manner.&lt;/p&gt;

Synthesis

&lt;p&gt;All added up, this provides a rich, robust system for representing
a wide variety of outline type data structures, documents and
otherwise.&lt;/p&gt;

&lt;p&gt;It&apos;s not a panacea; perhaps in some other posting I&apos;ll talk about
the indicators that an outliner is &lt;i&gt;not&lt;/i&gt; an appropriate
interface. For now, that&apos;s only written up in the developer&apos;s manual,
and still a work very much in progress. It also depends on some of the
precise aspects of the outline structure that I have not discussed,
such as its interaction with the Commands the user runs on the
outline, and the hitherto-unmentioned Undo/Redo system, so I can&apos;t
meaningfully describe all of the indicators right now.&lt;/p&gt;

&lt;p&gt;It&apos;s worth reviewing for a moment what I&apos;ve done. Starting from a
monolithic idea of what a node is, I broke the node up into:&lt;ol&gt;&lt;li&gt;A
structural piece (original node class)&lt;/li&gt;&lt;li&gt;how the structural
nodes are connected (links)&lt;/li&gt;&lt;li&gt;a &apos;projected&apos; outline on top of a
graph (handles)&lt;/li&gt;&lt;li&gt;Where the node gets its data from (data
sources)&lt;/li&gt;&lt;li&gt;what kind of node/document it is (node
types)&lt;/li&gt;&lt;li&gt;what document the node belongs to&lt;/li&gt;&lt;/ol&gt;that&apos;s six
distinct &quot;aspects&quot; of a node that I can manipulate, or even replace,
independently of the others. (This is why writing outline code in
other outliners feel so constraining to me; things natural under this
model are complex, error-prone, or even impossible under the
&quot;monolithic node&quot; model.) Despite that, it&apos;s only marginally more
difficult to manipulate, and often easier because it asks you to jump
through fewer hoops.&lt;/p&gt;

&lt;p&gt;For reference, the final Python code that implements this structure
is significantly shorter then just this discussion. Approx. 50
kilobytes of code sustained about 90kilobytes of discussion; and this
discussion was just the high-level discussion, and the 50 kilobyte
count includes a lot of documentation. While not all code is written
with this level of deliberation, a lot of it is.&lt;/p&gt;

&lt;p&gt;For you non-developers who may have slogged through this, I hope
this opens your eyes to the amount of work represented in every
program you use, including huge quantities of code you aren&apos;t even
aware of at the OS layer and other layers you can&apos;t see. And even in
the case of Iron Lute, which remains a relatively small, unreleased
program, this is only a fraction of the total code in that program; as
of this writing there are 700 kilobytes of Python code, including
testing, documentation, and at least one dead branch of code. (While
this is a very carefully considered and designed part, there are at
least four or five other things in the code worthy of equal care; some
I may yet write about here, some I probably won&apos;t.)&lt;/p&gt;



&lt;p&gt;This should be the last bit exclusively regarding outlines, though of course further discussion will all be predicated on the outline model for obvious reasons.&lt;/p&gt;

&lt;p&gt;Last night, I &apos;finished&apos; the part of Iron Lute that reconstructs outlines based on the pieces as described in &lt;a href=&quot;http://www.jerf.org/ironlute/2004/02/25.html#P2369&quot;&gt;this post&lt;/a&gt;; finished gets scare quotes because it needs more tests written for it, which it gets tonight. However, it already correctly handles the case of A-&gt;B, which pretty much is &lt;i&gt;the&lt;/i&gt; fundamental thing it has to get right; everything else (except maybe A-&gt;A) is built on that. After that I need to write the XML converter for the parts, and start testing the dickens out of it, then I can swing back to the GUI.

&lt;p&gt;After more thought, I&apos;m strongly considering releasing an alpha version at that point, even though I&apos;m not &quot;done&quot; yet, for testing and feedback. There are several large ideas still left to go in, but in the long run it might be better to have it out there, getting used and getting feedback, then to get all the ideas in there at first. My primary issue is I don&apos;t want developers to get too attached to the current way of doing things which may change later, but this sort of project generally takes time to come up to speed, if it indeed ever does, so perhaps that&apos;s a phantom concern.&lt;/p&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/03/08.html#P2374</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Mon, 08 Mar 2004 16:23:28 GMT</pubDate>
</item>
<item>
<title>On Holding Together This Structure</title>
<description>In my previous posts, I&apos;ve answered the question &quot;What Is An
Outline?&quot; from the point of view of Iron Lute. The resulting data
structures are somewhat complicated. These data structures are at the
heart of Iron Lute; if they fail, the entire program can come crashing
down. Moreover, if nobody is capable of correctly using the data
structures, they are still useless. It&apos;s worth discussing

Theory to Practice: How Do We Hold This Together?

&lt;p&gt;especially in light of the fact I&apos;d like to see this become a
self-sustaining open source project or potentially a commercially
viable product; if I&apos;m the only person who can write or maintain Iron
Lute code then that&apos;s a hopeless endeavor. The answer to that comes in
many parts.&lt;/p&gt;

Easy Interfaces For Easy Tasks

&lt;p&gt;For all the complexity in the data structure itself, the vast
majority of operations can be specified very well as a small local
operation involving one, two, or at most three nodes. (An example of
the latter is a &quot;swap nodes&quot; functionality, which involves the two
nodes to be swapped and the parent; an example of this in use is the
&quot;Move Node Up&quot; command.) And most of those operations do not
intrinsically care whether or not the graph is a pure tree-based
outline, a graph, or anything else.&lt;/p&gt;

&lt;p&gt;For instance, adding a node, a common operation, doesn&apos;t mean you
have to create a node, create a link, and connect the link
manually. Assuming A is a node, it suffices to say

&lt;pre&gt;A.addNewChild()&lt;/pre&gt;

&lt;p&gt;By default, that method adds a new BasicNode (the simplest type) to
the end of the children of A; various parameters allow one to override
pretty much every clause in that sentence as desired. The
&quot;addNewChild&quot; method handles all that.&lt;/p&gt;

&lt;p&gt;In most common cases of traditional outline algorithms, the best
way to use the outline is to grab a handle and do all access to the
outline via that handle. The handle itself passes through node
operations to the node that is the destination of the handled link,
which means that one can often simply write algorithms in terms of
node handles and have work without futzing around with anything else
in the data structure. For instance, a simple find-and-replace
algorithm to replace &quot;Hello&quot; with &quot;Goodbye&quot; in all nodes reachable
from the current node, assuming handleA is a handle for node
A, can be implemented as:

&lt;pre&gt;for handle in handleA.depthFirst():
    data = handle.getData()
    data = data.replace(&quot;Hello&quot;, &quot;Goodbye&quot;)
    handle.setData(data)&lt;/pre&gt;

&lt;p&gt;Note the programmer doesn&apos;t need to concern themselves with the
details of the data structure, including even the issues involved with
handling true graphs, rather then outlines. (Depth-first of course
refers to the depth-first traversal as also discussed in &lt;a href=&quot;http://www.jerf.org/ironlute/2004/02/25.html#P2369&quot;&gt;Storing my
Outlines&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Despite the complexity of the underlying data representation, the
vast majority of operations a programmer may wish to perform are very
simple; only a very few cases, mostly extending Iron Lute&apos;s commands
in new ways, require mucking with the internals directly. Even more of
those cases can and should end up being refactored into core
capabilities, so that ideally nothing except the internals of Iron
Lute ever need to much with those things.&lt;/p&gt;

&lt;p&gt;The only moderately complicated thing is that you can not be sure
if a given node will exist when you reach for it, if it&apos;s a remote
node, but generally, this only occurs explicitly and people can
explicitly plan for it. The Iron Lute core needs to be a bit more
robust to handle these cases in general, but generally, people
extending the core will not need to deal with that issue unless they
deliberately choose to create a design where they might need to.&lt;/p&gt;

&lt;p&gt;Thus, programming in Iron Lute is about as easy as it can be, and I
do not think this will be a major concern. Keeping it this simple in
principle, even when multiple people or processes are working on an
outline at one time will be challenging but I am still optimistic it
can be done.&lt;/p&gt;

Getting It Right, And Keeping It That Way

&lt;p&gt;If the outline data structure has a flaw, the whole of Iron Lute
has a flaw. Yet the number of possible
interactions in the data structure is fairly large. How can I be sure
I&apos;ve caught the majority of the importent bugs?&lt;/p&gt;

&lt;p&gt;The answer is &lt;a href=&quot;http://www.c2.com/cgi/wiki?UnitTest&quot;&gt;Unit
Testing&lt;/a&gt;, or more generally, a truly systematic testing framework,
built in from Day One, that is specifically meant to cover all aspects
of how outline nodes should behave in the system. For this outline
data structure, I&apos;ve written almost as much testing code as I have
data structure code (with comments and documentation removed from
both), and as bugs are found, that ratio will tip in favor of
testing.&lt;/p&gt;

&lt;p&gt;It sounds simple but it is not generally practiced, often because
the benefits of pervasive, fine-grained testing is not understood in
general. For instance, there are by my count 16 things you can do to a
Link, just regarding the settings of the source and destination: For a
link with 4 possible settings for whether it has a source or
destination (no/no, yes/no, no/yes, yes/yes), you can either set a
(new) destination, unset the destination, set a (new) source, or unset
the source. By writing a test for those scenarios (which only required
4 loops in the testing code; there are some natural categories those
break down into), I found a bug that only manifests itself in the
yes/yes situation when resetting the destination. It failed to fire an
event it should have, which itself is a subtle issue that would have
taken a while to resolve, but is exactly the sort of thing that
contributes generally to instability in the final product, when a
couple hundred of these kinds of tiny bugs add up.&lt;/p&gt;

&lt;p&gt;Even more interesting, my count was wrong. Creating a link and
setting it, then unsetting the destination and unsetting the source is
a distinct act vs. unsetting the source then the destination, as
evidenced by the fact that I had a bug that only manifested itself
when deleting an existing link by unsetting the destination and then
the source. I found this bug not in the outline unit tests, but in the
unit test that examined the Delete Node command. Without the unit
tests, it would have been much harder to track that bug down, or even
detect it, since as it happens the node still correctly deletes, it
just leaves the link in an inconsistent state.&lt;/p&gt;

&lt;p&gt;But the mere testing of correctness is not the only, or even the
most interesting, benefit. As I mentioned at the outset, I&apos;ve actually
had various versions of Iron Lute already running with each of these
four major versions of &quot;outlines&quot; at some point. Taking even a small
program like Iron Lute through that kind of intensive refactoring
tends to tear the program apart. It can be demoralizing to see your
program reduced to a seething mass of unidentifiable bugs with no road
plan on how to identify or fix them, except by groveling over the code
by hand. For a hobby project, that means either death, or the
sub-optimal choice of dodging the issues in the first place by leaving
the poor design decisions in place.&lt;/p&gt; 

&lt;p&gt;The ability to test has helped hold the program together, even as
the interfaces between the parts evolve. The basic commands, such as
&quot;Indent&quot;, have changed in implementation several times now, but since
I have a unit test written for it, I can easily check whether it&apos;s
still working with a single command. (In fact, the Unit Test for the
Indent GUI command hasn&apos;t changed since I refactored the &quot;indent&quot;
operation into the LinkHandle class around version 2, even as the
&quot;indent&quot; method has undergone at least three major changes.) In a
GUI-based program like Iron Lute, it&apos;s important to take the time to
implement such things because even if you had the discipline to create
a check-list to run through, it would still quickly fall into disuse,
since a complete checking of the GUI functionality of the product
would quickly grow to take hours, or even days. (The latter is not
merely hyperbole; a full testing would need to test every node with
every command in several circumstances in every time &lt;/p&gt;

&lt;p&gt;Unit tests are almost &lt;i&gt;more&lt;/i&gt; useful in their capacity to hold
developing programs together, and thereby &lt;i&gt;facilitate&lt;/i&gt; such
development, then they are as correctness testers.&lt;/p&gt;

&lt;p&gt;It boggles my mind how many people build large systems without this
sort of testing, even though I was one of them just a couple of years
ago. Having used them, I loath being forced to give them up at
work. (I intend to bring them in someday but right now we are in the
middle of a transition from an old system to a much newer version of
it, so there&apos;s little point in writing the tests against a very
different interface.) They actually &lt;i&gt;accelerate&lt;/i&gt; development
because of the power they give you to tear into &quot;sacred&quot; parts of the
program and clear them up, secure in the knowlege that you stand a
tolerable chance of not breaking anything. Experienced but
non-test-using programmers tend to develop an instictive fear of
touching any part of a program that is critical and
embedded. Unit-testing support largely removes that fear. While there
is still a degree of risk when refactoring code, the resulting gains
from cleaning up the crufty parts of the code, and the subsequent more
robust code that can then be extended even more, more then offsets
that risk and the minimal cost of writing the testing code.&lt;/p&gt;

&lt;p&gt;(After all, you &lt;i&gt;will&lt;/i&gt; write testing code, and you &lt;i&gt;will&lt;/i&gt;
need to debug your code. Do you keep your testing code around in a
systemized fasion, and use them to direct your debugging, or do you
toss quick, unprincipled little test cases at your code, lean on
debugging to &quot;fix&quot; the problems, and assume at the end on quite
incomplete evidence that the code is &quot;correct&quot; without the ability to
run those tests again?)&lt;/p&gt;

&lt;p&gt;If you are a developer, this was my attempt to get you &lt;a href=&quot;http://www.c2.com/cgi/wiki?TestInfected&quot;&gt;Test
Infected&lt;/a&gt;. Please do not resist. Join us. Do not be afraid. It is
so much happier over here...&lt;/p&gt;

Strong Code

&lt;p&gt;I can&apos;t guarentee the code is bug free, even now. I can&apos;t guarentee
that it won&apos;t need some even more fundamental extension later (though
I&apos;m pretty confident now the basic structure is correct). But I am
confident that it handles a lot, handles it correctly, and is about as
easy to use as you could ask for.&lt;/p&gt;

&lt;p&gt;It isn&apos;t necessarily perfect code, but it&apos;s very strong code, and
I&apos;m confident it&apos;s strong enough to build Iron Lute on top of. Where
it is not up to the task, I&apos;m confident it can be improved on.&lt;/p&gt;

&lt;p&gt;The next posting will explore the extensions of this data structure
that will make Iron Lute the richest extensible outlining program
around.&lt;/p&gt;

&lt;p&gt;In other news, I continue to work on the serialization of the outlines. Work has been stressful so I&apos;ve been doing more relaxing at home then coding. It&apos;s looking better so I hope to get more coding in.&lt;/p&gt;
</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/03/02.html#P2370</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Tue, 02 Mar 2004 15:28:00 GMT</pubDate>
</item>
<item>
<title>Storing My Outlines</title>
<description>One significant advantage a more conventional outline has over the
outline structure I&apos;ve built up here is that it is much easier to
store the traditional outline in a file. Using XML, traditional
outlines are almost trivial to store:

&lt;pre&gt;&amp;lt;node text=&quot;A&quot;&amp;gt;
  &amp;lt;node text=&quot;B&quot; /&amp;gt;
  &amp;lt;node text=&quot;C&quot; attribute=&quot;D&quot; /&amp;gt;
  &amp;lt;/node&amp;gt;&lt;/pre&gt;

&lt;p&gt;Even if you don&apos;t read XML, you can quickly learn to read this
format. About the only difference between what I just wrote and the
official OPML specification is that OPML adds a &amp;lt;head&amp;gt; section that
includes some metadata about the outline, and uses &quot;outline&quot; instead
of &quot;node&quot;.&lt;/p&gt;

&lt;p&gt;Right now I&apos;m working on how I&apos;m storing my outlines &quot;natively&quot; in
Iron Lute. First of all, using that simple style is not an option,
because it doesn&apos;t allow for anything but a strict tree. There are two
basic other choices that I can see. Both require the addition of node
ids, since both will require the ability to refer to previous nodes
(and possibly nodes that come &lt;i&gt;later&lt;/i&gt; in the file):&lt;/p&gt;

&lt;pre&gt;&amp;lt;node text=&quot;A&quot; id=&quot;1&quot;&amp;gt;
  &amp;lt;node text=&quot;B&quot; id=&quot;2&quot; /&amp;gt;
  &amp;lt;node text=&quot;C&quot; attribute=&quot;D&quot; id=&quot;CWQ!&quot; /&amp;gt;
  &amp;lt;/node&amp;gt;&lt;/pre&gt;

IDs

&lt;p&gt;On the subject of IDs, for the IDs, I face two choices: Do I want
them to be globally unique, or just unique within a given file?&lt;/p&gt;

&lt;p&gt;Globally unique IDs have some advantages in that they make
excellent link targets and having a GUID can preserve the identity of
a node, even if you move it from one document to another. But I faced
an issue with ensuring that the GUIDs would be truly &lt;i&gt;globally&lt;/i&gt;
unique, and I couldn&apos;t come up with a solution I found
satisfactory. (I&apos;m not overly concerned about speed, but all the
attempts I tried really slowed Iron Lute down, even with the trivial
outline sizes I&apos;m currently dealing in.)&lt;/p&gt;

&lt;p&gt;For the purposes I need, it suffices that IDs are unique within a
file/stream, and that&apos;s much easier to guarentee. I only use these ids
in the context of the file itself, so they don&apos;t even have to stay
constant. Other &apos;anchors&apos; will be created if we want to link into an
outline later.&lt;/p&gt;

The Two Basic Choices

&lt;p&gt;Now, let us say that I am representing an outline that looks like
A-&amp;gt;B-&amp;gt;A. The two basic choices I see for representing that
outline look like this:

&lt;ol&gt;&lt;li&gt;&lt;pre&gt;&amp;lt;node text=&quot;A&quot; id=&quot;1&quot;&amp;gt;
  &amp;lt;node text=&quot;B&quot; id=&quot;2&quot;&amp;gt;
    &amp;lt;noderef targetid=&quot;1&quot; /&amp;gt;
    &amp;lt;/node&amp;gt;
  &amp;lt;/node&amp;gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&amp;lt;node text=&quot;A&quot; id=&quot;1&quot; root=&quot;true&quot; /&amp;gt;
&amp;lt;node text=&quot;B&quot; id=&quot;2&quot; /&amp;gt;
&amp;lt;link from=&quot;1&quot; to=&quot;2&quot; /&amp;gt;
&amp;lt;link from=&quot;2&quot; to=&quot;1&quot; /&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;The first one preserves the current natural representation of
outlines, and uses some sort of placeholder element for nodes that
already exist in the file and are re-appearing later. The second one
gives up the natural hierarchy in XML and just lists the nodes, the
links, and how they correspond; re-assembling them is still fairly
easy, though slightly less intuitive.&lt;/p&gt;

&lt;p&gt;The first example has the benefit of being more human
readable... but since I anticipate supporting a lot of formats
natively in Iron Lute, and already natively support OPML, for
instance, I&apos;m actually not so concerned about &quot;human readability&quot; for
the &quot;native&quot; format of Iron Lute. Iron Lute&apos;s native format needs to
be powerful enough to handle everything anybody can throw at it, and
human readability just isn&apos;t in the cards for that.&lt;/p&gt;

&lt;p&gt;The second format also has an intriguing possibility to it. Right
now, I&apos;m assuming that the order matters, so when the first &amp;lt;link&amp;gt;
element comes along, the code that is re-assembling the
outline(/graph) structure just &quot;knows&quot; that that is the first child of
the node with id=&quot;1&quot;. If we were willing to specify the order
explicitly, we get an interesting property:&lt;/p&gt;

&lt;pre&gt;&amp;lt;node text=&quot;A&quot; id=&quot;1&quot; root=&quot;true&quot; /&amp;gt;
&amp;lt;node text=&quot;B&quot; id=&quot;2&quot; /&amp;gt;
&amp;lt;link from=&quot;1&quot; to=&quot;2&quot; child=&quot;0&quot; /&amp;gt;
&amp;lt;link from=&quot;2&quot; to=&quot;1&quot; child=&quot;0&quot; /&amp;gt;&lt;/pre&gt;

&lt;p&gt;What&apos;s interesting about this list is that the elements can be
arbitrarily re-ordered, and the final assembled product (assuming a
correctly written assembler) is the same. The above is exactly the
same as&lt;/p&gt;

&lt;pre&gt;&amp;lt;link from=&quot;1&quot; to=&quot;2&quot; child=&quot;0&quot; /&amp;gt;
&amp;lt;node text=&quot;B&quot; id=&quot;2&quot; /&amp;gt;
&amp;lt;link from=&quot;2&quot; to=&quot;1&quot; child=&quot;0&quot; /&amp;gt;
&amp;lt;node text=&quot;A&quot; id=&quot;1&quot; root=&quot;true&quot; /&amp;gt;&lt;/pre&gt;

&lt;p&gt;and is exactly the same as all the other 22 orderings of those four
things.&lt;/p&gt;

&lt;p&gt;(Actually, in the final Iron Lute file format, the nodes will carry
a list of link ids in them, rather then the link specifying what child
it is. The advantage is that once you have a node, you can know how
many children it has, and by extension, whether it has children at
all, but sticking it in the link has only the advantage of looking
nicer. Showing the links in the node requires something like
&amp;lt;links&amp;gt;&amp;lt;link id=&quot;4&quot;/&amp;gt;&amp;lt;link id=&quot;5&quot;/&amp;gt;&amp;lt;/links&amp;gt;. Since this is a
discussion, not code, that&apos;s why I show the child indicators in the
link right now.)

&lt;p&gt;This intrinsically only has the &quot;advantage&quot; of making the
re-assembly process a bit more complicated, since in addition to
understanding backward references (references to already-existing
nodes), you must now understand forward references (references to
nodes or links that haven&apos;t arrived yet), but that is a relatively
minor point in general, especially as this is code that will not be
modified by many people.&lt;/p&gt;

&lt;p&gt;What is &lt;i&gt;really&lt;/i&gt; interesting is the secondary effects that you
can get from playing with the order an outline is saved in. Let us
imagine some relatively complicated outline with a few hundred nodes,
but the last child of the root node has no children. Now, imagine what
happens as the outliner reads in that outline, specified in format #1
above. The last child of the root node is the last node to be
seen.&lt;/p&gt;

&lt;p&gt;What the implies is that the outliner can never be sure that it has
all the children of even the root node until the entire file is
loaded. Therefore, the program really can&apos;t display the outline until
the entire outline has been loaded. In theoretical terms, this is
because the outline is stored by using a &lt;a href=&quot;http://en.wikipedia.org/wiki/Depth-first_search&quot;&gt;depth-first
traversal&lt;/a&gt;. Re-ordering the file is not an option since the order
in the file directly reflects the order in the outline.&lt;/p&gt;

&lt;p&gt;But what if we&apos;re not tied to that order? What if I use the second
style of file, and choose the order the nodes are dumped out to use &lt;a href=&quot;http://en.wikipedia.org/wiki/Breadth-first_search&quot;&gt;breadth-first
traversal&lt;/a&gt;? Then, we &lt;i&gt;can&lt;/i&gt; know whether or not we&apos;ve seen all
the children of a given node. We could then go ahead and display the
outline to the user, and allow it to keep loading in the
background.&lt;/p&gt;

&lt;p&gt;Breadth-first loading here has the advantage that unless the user
immediately dives deeply into the outline, or immediately issues an
&quot;Expand All&quot; command, we can most likely allow the user to immediately
begin using the outline, even if only a fraction of it is
loaded. (Iron Lute already weakens &quot;Expand All&quot; anyhow, because of the
possibility of looping paths in the outline.)&lt;/p&gt;

&lt;p&gt;This appeals to me because the most important thing about a program
is not its raw speed, but its responsiveness to human demands. Even if
I take ten times longer to read in an outline then some other program
(which is not impossible, since they may be written in C and Python,
whatever other virtues it has, is not the fastest language), if I
display the outline and allow the user to use it ten times faster, my
program &lt;i&gt;looks&lt;/i&gt; and &lt;i&gt;feels&lt;/i&gt; faster, and will make the user
happier. This isn&apos;t an issue for most normal-sized outlines stored on
disk, but if we want to pull outlines from a remote source over a slow
link, this can become a huge advantage.&lt;/p&gt;

&lt;p&gt;In the ultimate case, I visualize someday having full Co-Outlining
implemented in Iron Lute, with Iron Lute connected to another instance
of Iron Lute. Even at dial-up speeds, connecting to another Iron Lute
outline would allow you to start manipulating the outline within
seconds of the request to connect, even if the outline you&apos;ve
connected to is many megabytes in size (as long as it doesn&apos;t have too
many top-level nodes, which if you want dial-up users to use your
outline you will avoid). If you do open something that isn&apos;t loaded
yet, your Iron Lute could send a request to the remote Iron Lute to
start loading those nodes first, minimizing the time it takes to
manipulate those nodes.&lt;/p&gt;

&lt;p&gt;Another interesting but subtle property of this file format is that
it turns the file format into a series of commands. In the above
example, it is better to think of the &amp;lt;link&amp;gt; and &amp;lt;node&amp;gt; elements as
commands to &quot;add a link&quot; or &quot;add a node&quot;, rather then trying to puzzle
them out as some kind of structure. Once you start thinking of it that
way, you can later in the file add a new node with the same id, and
interpret that as &quot;replace the old node with this one&quot;, or you can add
simple delete commands to remove old nodes or links.&lt;/p&gt;

&lt;p&gt;Why is this interesting? For one thing, I intend to use this as
Iron Lute&apos;s emergency backup technique; Iron Lute can always append to
the file rather then re-write it from scratch, so you won&apos;t get that
massive pause every time the program does an automatic backup, like
I&apos;ve seen in Microsoft Word. The backup time is proportional to the
changes you made since the last save, not the size of the document
itself. (Every once in a while, Iron Lute might save it from scratch
to avoid filling the disk, but a human would not be able to generate
too many events so in the common case it would be a long time before
the user used a significant proportion of the disk.)&lt;/p&gt;

&lt;p&gt;Another thing I&apos;m not sure about yet, but... I&apos;m thinking that the
co-outlining will be implementable as exactly the same stream as the
file storage system uses; as long as Iron Lute understands &quot;stream
still in progress&quot; and has some system for generating stream updates, it
should work. A central participant in the co-outlining will be
responsible for collating the incoming events, and for resolving
resulting conflicts (two people modifying the same node at roughly the
same time, one person modifying a node the other has deleted, etc.),
and I think that&apos;s nearly all that will be necessary for a first-cut,
but functional, outline sharing. This is one design goal I haven&apos;t
talked about but it is affecting my decisions; I don&apos;t want to lock
myself out of this possibility inadvertantly.&lt;/p&gt;

&lt;p&gt;My current plans for Iron Lute at the moment are that I want to get
this file saving working correctly, then I want to swing back to the
GUI and make it usable as at least a simple outliner. I would then
have a project that could theoretically be released at any time, and
the decision about when to release it would be driven by whether or
not it did anything &lt;i&gt;useful&lt;/i&gt; yet, and how much I would mind
having others build on top of it yet. It is my guestimate that
completing the file saving/loading and GUI work I want to do will be
at least three months, so we&apos;ll see where to go from there.&lt;/p&gt;
</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/02/25.html#P2369</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Thu, 26 Feb 2004 01:33:52 GMT</pubDate>
</item>
<item>
<description>I just had pretty much the worst week ever at work, which accounts for
my not posting anything this week. How bad? I just finally noticed
today that I didn&apos;t post my Monday Iron Lute post. 

&lt;p&gt;I can only hope this week is better. Unfortunately, it doesn&apos;t show
any particular signs of improving, so posts may be slowed up this week
too.&lt;/p&gt;

&lt;p&gt;This week instead of continuing on with my outline series of posts,
I think I may jump ahead and discuss the file format for my outline
model, which is what I&apos;m working on right now. Designing a file format
to hold the data hasn&apos;t been too hard, but it&apos;s been a bit of a brain
bender trying to figure out the &lt;i&gt;best&lt;/i&gt; way to implement it. There
are a few interesting things you can do with an outline structure you
can&apos;t do with a conventional flat file, and I want to make sure that
those things are possible. What day this will get posted, I don&apos;t
know, since I still have to write it.&lt;/p&gt;</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/02/22.html#P2367</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<category domain="http://www.jerf.org/iri/">Personal Notes</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
<ent:topic ent:id="Personal Notes" ent:href="http://www.jerf.org/iri/categories/Personal Notes/">Personal Notes</ent:topic>
</ent:cloud>
<pubDate>Sun, 22 Feb 2004 18:16:32 GMT</pubDate>
</item>
<item>
<title>What is an Outline, Part 4</title>
<description>In my last post, I dissociated the concept of &quot;outlineness&quot; from a
graph, and showed at least the skeleton of a data structure that allows
the power of graphs while preserving the nature of an outline.

&lt;p&gt;In this post, we will fix a flaw in the model built up to that
point, which is that there is no way to obtain a list of parents,
given a node, only a list of children. For various reasons, this is
necessary to building an outliner, so this flaw &lt;i&gt;must&lt;/i&gt; be fixed.&lt;/p&gt;

&lt;p&gt;Terminology note: A &quot;link&quot; connects one node to another. In a
graph, it&apos;s a &quot;edge&quot;, but in my mind, it behaves more like a link, so
that&apos;s the name it gets. Right now, we can only follow links from
parents to children; we want to be able to follow them back, too.&lt;/p&gt;

&lt;p&gt;Again the consequences are subtle, so I&apos;ll spread the Pros and Cons
of various decisions out with the discussion. First:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Issue&lt;/b&gt;: How we will enable the ability to follow parent links
of nodes while sacrificing as little as possible?&lt;/p&gt;

&lt;p&gt;Once again, we will start out with...&lt;/p&gt;

The Obvious Solution: Record Incoming Links In Nodes

&lt;p&gt;The obvious solution is to simply add a list of nodes that have
incoming links to a given node, and update it as it changes.&lt;/p&gt;

&lt;p&gt;One obvious &lt;b&gt;Pro&lt;/b&gt; is that it is simple. And for once, the
obvious simple solution has the virtue of not being completely
wrong. However, it does have two &lt;b&gt;Cons&lt;/b&gt; that are worth thinking
about to see if we can do something about them:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;b&gt;Con&lt;/b&gt;: Suppose you have a node that has the &lt;i&gt;same&lt;/i&gt;
node twice as a child. An A node with two children, both the
same B. What does in the incoming list look like? Well, if
you have A&apos;s child list look like this: [B, B], and
B&apos;s incoming link list look like this: [A, A], you have a
problem: You can&apos;t disambiguate which link is which, since both are
A-&gt;B. This causes some uncomfortable problems in code which
tends to assume that they are distinct, such as link removal
code. (For instance, if I have a child list of [B, C, B], and
I am instructed to remove the link to B, which one is it? It
matters.)

&lt;p&gt;One viable solution is simply to ban this, since it&apos;s hard to think
of a solution where this could be a good thing. It is often the case
that these sort of edge cases are best handled by banning them. But
let&apos;s consider the whole problem before committing to a
solution...&lt;/p&gt;

&lt;li&gt;&lt;b&gt;Con&lt;/b&gt;: Done naively, this now means that whenever somebody&apos;s
child list is manipulated, they must &lt;i&gt;also&lt;/i&gt; manipulate the parent
list for the appropriate node. Since this is going to be the same sort
of thing every time we do it, it&apos;ll be best to centralize
it.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;&lt;i&gt;Technical Python note&lt;/i&gt;: There is a third problem, which is
that strong bi-directional links weaken the garbage collector; it can
handle it but it&apos;s not as good as ref-count garbage collection. We&apos;d
prefer to do away with the strong child-&gt;parent references, but
forcing everyone to maintain the weak links themselves is even more
complexity (and potential errors by programmers who really shouldn&apos;t
need to understand weak links to correctly use this data structure,
this should be pushed under the hood).&lt;/p&gt;

&lt;p&gt;We need to abstract this handling into some kind of easy
functionality, preferably transparently integrated as appropriate (so
ideally, &lt;i&gt;nobody&lt;/i&gt; has to deal with this other then me). We could
just create some functions, but we actually do benefit from creating a
&lt;b&gt;Link&lt;/b&gt; class, because it turns out to be really nice to refer to
instances of the Link class (&quot;links&quot;).&lt;/p&gt;

&quot;Links&quot; As A First-Order Concept

&lt;p&gt;A &quot;Link&quot; can be though of as a staple, where the nodes are little
pieces of paper. Each link can be attached to two nodes, a &quot;source&quot;
and a &quot;destination&quot;, where the source is the parent and the
destination is the child. (It is not technically correct to refer to a
Link&apos;s &quot;parent&quot; or &quot;child&quot;, because a link does not have either of
those things. It has a source and a destination, so that&apos;s the terms I
use. A link &lt;i&gt;defines&lt;/i&gt; a parent-child relationship, it does not
have one itself.)&lt;/p&gt;

&lt;p&gt;We can actually instantiate a link without knowing either the link
or the destination right away. You can envision that as a staple that
hasn&apos;t been used yet, so both ends are unbent. As we connect it to
nodes, we wrap the ends around the nodes. Of course, since this is a
software staple, we can also &quot;unbend&quot; the links and reconnect them to
different nodes without penalty. In my implementation, you can
accomplish this with code like the following. If A and
B are nodes, that we&apos;re going to connect like A-&gt;B,
you can do the following:

&lt;pre&gt;l = Link()
l.source = A
l.dest = B&lt;/pre&gt;

&lt;p&gt;(As a shortcut, you could also do l = Link(A, B), but I
wanted to emphasize how you could manipulate the ends of the
link indepedently.)

&lt;p&gt;As a practical matter, the link only actually connects when you
give it both a valid source and destination, so technically, in the
code example, nothing happens to either A or B until
the last line executes. It will also disconnect from both nodes
immediately if you invalidate one of the ends. (In Python terms, you
rebind either source or dest to None,
although source and dest are actually properties so
that&apos;s not quite right terminology either... you can del them
too if you prefer.)&lt;p&gt;

&lt;p&gt;We bundle into the Link class the intelligence necessary to update the
child and parent lists of the node appropriately. Instead of links to
the nodes, we actually store the relevant link objects. Of course, we
still present easy access to the programmer by following the link as
appropriate, so if they write code with A[0], they still get
B without having to manually write
A.data.outgoing[0].dest. (data is the data source
for A; remember that? outgoing is the list of
outgoing links. [0] gets the actual link, and finally,
dest returns the actual node the link points to.)

&lt;p&gt;This is a minor OO violation, in that there are data structures in
the Node class (the incoming list of links) and the DataSource class
(the children list) that the Link class is responsible for
handling. Factoring this out isn&apos;t worth the pain right now, although
it will be later; in the current-as-of-this-writing version of this
datastructure, there actually is a special IncomingLink data structure
that mediates between the link and the node for the incoming links.&lt;/p&gt;

&lt;p&gt;While I have no use for it at the moment, we can actually
now load other data onto the link as appropriate. Generally, in
documents, this is not useful, but there are some data structures that
this may be useful with. We&apos;re not paying anything for this, or
letting it affect the design, so it&apos;s not a &lt;a href=&quot;http://c2.com/cgi/wiki?YouArentGonnaNeedIt&quot;&gt;YAGNI&lt;/a&gt;
violation.&lt;/p&gt;

&lt;p&gt;I think there may be later uses for this link as well, but as I&apos;ve
not thought through this part of the design yet I can&apos;t say much about
it. Luckily, it&apos;s a cleanly-seperated part of the data model, so I can
replace how links work later and it will have minimal (ideally, no)
impact on the rest of Iron Lute.&lt;/p&gt;

&lt;p&gt;(For instance, I visualize a web template system that tracks links
made to other internal documents and thus tracks which parts of which
documents are dependent on others, re-rendering things only when
necessary. If we replaced all Links in such documents with Links that
also reported to the central repository when they link to external
documents, then we could easily implement this repository with very
little code, and the Iron Lute GUI would need no changes at all.)&lt;/p&gt;

Interconnecting Outlines

&lt;p&gt;Up to this point, I have gone quite far in resolving the &quot;What Is
An Outline?&quot; question in the conventional case. It&apos;s an outline tree
structure overlaid on top of a graph structure. In a conventional
outliner, the underlying data structure is never allowed to &lt;i&gt;be&lt;/i&gt;
anything but a tree, which makes it even easier. If we only opened one
document at a time and never allowed them to interlink directly, we&apos;d
effectively be done now.&lt;/p&gt;

&lt;p&gt;But earlier, I mentioned that one of fundamental design goals is to
have multiple documents truly interacting in the outliner. When I&apos;m in
one document and I choose &quot;Save&quot;, I need to save only that document,
not all the nodes I have in memory.&lt;/p&gt;

Terminology and Assumptions

&lt;p&gt;For our representational convenience, let us define a node
T that is a &quot;transcluder&quot;; it has a data source that loads
an outline from the web. The document it loads will use numbers for
the nodes, as in: 1-&gt;2-&gt;3, which allows us to easily
distinguish those other nodes. The number document may also contain a
#T, which transcludes back to the original document.

&lt;p&gt;So imagine that we have two documents, A-&gt;B-&gt;T and
1-&gt;2-&gt;#T. When we load the first, we only display
A. When we expand B and then T, we then
load the other document. Finally, when we expand #T, we get
the original document transcluded, so the display now shows
A-&gt;B-&gt;T-&gt;1-&gt;2-&gt;#T-&gt;A. This has a cycle if we have both a
T and a #T node.

&lt;p&gt;For the moment, let&apos;s suppose we have write access to both the
documents and that Iron Lute knows how to save to even the remote
document, so we have total freedom to manipulate both documents. (How
this is accomplished cleanly internally is the subject of a later
posting.)&lt;/p&gt;

What is an Outline Document?

&lt;p&gt;It&apos;s time to ask ourselves what it means to have an &quot;outline
&lt;i&gt;document&lt;/i&gt;&quot;, with the emphasis placed on the word &quot;document&quot;. Why
do we care about what constitutes a &quot;document&quot;? Well, abstractly,
we&apos;re just dealing with a seething mass of nodes and links, existing
with no particular relation to each other beyond their links. This is
the traditional conception of a &apos;graph&apos;. However, this program exists
in the real world, where users like to do things like hit the &quot;Save&quot;
button and close the program, expecting that their data has been
saved.&lt;/p&gt;

&lt;p&gt;In a strict tree outline, it&apos;s easy to declare the root node of the
tree as corresponding to the &quot;document&quot;. Saving a representation of
that particular node, along with all of its children, will result in
the entire document being saved; starting from any other node is
guarenteed to miss something.&lt;/p&gt;

&lt;p&gt;For our purposes, the first attribute is worth saving, while the
second attribute is to be discarded. There must be &lt;i&gt;a&lt;/i&gt; path to
the root node, but it may not be unique and it may require careful
choice of which parent links are followed. We can specify that from a
&quot;root node&quot; of a document, all children that we consider to &quot;belong
to&quot; that document should be reachable by following the children. In a
full graph, therefore, there may be multiple nodes that are a
candidate for being the &quot;document&quot;.&lt;/p&gt;

&lt;p&gt;We&apos;re going to use what document a node is in all over the place in
Iron Lute. For instance, if the node is part of an HTML document, we
will present the user with HTML-based commands for manipulating the
text, whereas if we&apos;re in a LaTeX document, we&apos;ll present LaTeX-based
commands. Given a node, we need to be able to determine a unique
document that that node belongs to for these purposes. Also, for cases
like OPML transclusion, we need to be able to distinguish between a
&quot;link node&quot; and its &quot;transcluded document&quot;; since the link node will
belong to the original document, but the children will belong to the
newly transcluded document, we know not to insert the transcluded
nodes into a saved representation of the original document.&lt;/p&gt;

&lt;p&gt;At the moment, the data we have to work with is:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;There exists some nodes that are defined to be the Document
nodes. For instance, if we load in an OPML file, the &quot;root node&quot; of
the OPML is &lt;i&gt;defined&lt;/i&gt; as the Document for that OPML
file.&lt;/li&gt;&lt;li&gt;Each node has a list of incoming links.&lt;/li&gt;&lt;li&gt;Each
node has a list of outgoing links.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;And let me give a hypothetical that seems to largely capture the
spirit of the problems we need to address:&lt;/p&gt;

&lt;blockquote&gt;Suppose you have three documents, A-&gt;B-&gt;C,
D-&gt;E-&gt;F, and G-&gt;H-&gt;I. The first is completely out of
your control and is dynamically changing. You load them all into your
outliner, and you copy C and paste it as a link under both
F and I. C now has &lt;i&gt;three&lt;/i&gt; incoming
links, one from each document. Now, suppose the remote user deletes C
from the original document. What should happen?&lt;/blockquote&gt;

&lt;p&gt;You have three basic choices:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Delete the node from all documents. (Or &quot;invalidate the link&quot;,
which has much the same effect for any reasonable definition of
&quot;invalidate&quot; I can think of.)&lt;/li&gt; 

&lt;li&gt;Leave the C as one node for both remaining documents
(i.e., a change to one continues to be a change to the other), and
pick a new &quot;home document&quot; for the node. 

&lt;li&gt;Allow the original node to be be destroyed, and put two need
&lt;i&gt;copies&lt;/i&gt; of C into the two remaining documents.&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;It is not obvious what to do from here; there are pros and cons to
each. However, one thing is clear: In the general case, only the first
one is practical. To consider an analogous case, consider linking to a
remote web page on the web. If a link is broken, it is broken, and you
can do nothing to fix the brokeness on the target end, since you only
control the source end.&lt;/p&gt;

&lt;p&gt;If you control all the documents, you may be able to do something
more clever. This says to me that there may be room to change which
behavior is used depending on circumstances, but that we must be
prepared to implement and handle the first case if
necessary. Sometimes we may not even be aware the link is broken until
transclusion time. Therefore, that is what we will start with, adding
other behaviors later as they are called for in the UI.&lt;/p&gt;

&lt;p&gt;This is sad, in that we&apos;d like to maintain integrity of the node
structure, but if we learn anything from the World Wide Web and
Xanadu, the gyrations necessary to try to do so are not worth it in
the general case.&lt;/p&gt;

&lt;p&gt;With this discussion in mind, let&apos;s get more detailed about what it
means to determine what document a node belongs to.&lt;/p&gt;

What Document Is A Node In?

&lt;p&gt;Suppose I give you a node, which as described above has some
incoming links, some outgoing links, and some data. How can you tell
me what document this belongs to?&lt;/p&gt;

&lt;p&gt;I&apos;d like to try to do this without extra information, to save
memory and to prevent situations where the extra information gets out
of sync with the rest of the structure of the outline.&lt;/p&gt;

&lt;p&gt;Can you do it?&lt;/p&gt;

&lt;p&gt;Almost. The reason why not is so subtle it took me a couple of
weeks to notice it.&lt;/p&gt;

&quot;Primary&quot; Links?

&lt;p&gt;An equivalent definition of a directed tree (given that the graph
is fully connected) is that each node has precisely one parent, except
one root node that has 0. Any (fully-connected) graph that meets this
constraint is a tree; the proof is trivial enough to be assigned as a
very simple homework problem in a graph theory course. (It is
sometimes even used &lt;i&gt;as&lt;/i&gt; the definition; there are several
different definitions of &quot;tree&quot; that look different on paper but are
equivalent mathematically.)&lt;/p&gt;

&lt;p&gt;We have an ordered list of incoming links; we can give the first
one special prominence and call it the &quot;primary link&quot;. It is also easy
to show that if you enforce a couple of simple restrictions, that you
can always reach a Document node by following the primary
parent. Thus, we can define a node&apos;s document as &quot;The document I find
if I follow the primary links until I reach the first document.&quot;&lt;/p&gt;

&lt;p&gt;Conceptually, we are projecting a tree on top of our graph. We end
up with a tree, as defined by the first incoming link for a given
node, that is extendable into a graph by adding more primary
links.&lt;/p&gt;

&lt;p&gt;This answers the questions posed about about what happens if a node
is deleted from a document when there&apos;s another document that has a
link to it; the &quot;primary link&quot; is removed, and the next link in line
automatically becomes the next &quot;primary link&quot; with no fuss.&lt;/p&gt;

&lt;p&gt;This is very simple, and you can actually get quite far with
it. It is conceptually well-defined and you don&apos;t seem to hit any
problems with ambiguities; the moving of a node from one document into
another can be handled with a bit of work, mostly just notifying the
new parent that it has been changed.&lt;/p&gt;

&lt;p&gt;Unfortunately, as appealingly simple (in execution, if not in
concept if you&apos;re not used to thinking in graphs) as this is, it does
not work.&lt;/p&gt;

Conceptual Impurity

&lt;p&gt;There are two equally valid ways of expressing why this doesn&apos;t
work, one couched in theoretical terms and one in purely practical
terms.&lt;/p&gt;

&lt;p&gt;In theoretical terms, this violates the &lt;a href=&quot;http://www.c2.com/cgi/wiki?ConceptualIntegrity&quot;&gt;Conceptual
Integrity&lt;/a&gt; of the design. We now have two distinct &quot;outline&quot;
overlays on top of our graph structure, the &quot;Link Handles&quot; and the
&quot;Primary Link&quot;. Each of these overlays behaves very differently, and
have different purposes in life. This is a bad thing.&lt;/p&gt;

&lt;p&gt;Practically, this results in a lot of problems that stem from the
fact that we are highly dependent on both the order and the existance
of the incoming links. This also reveals a theoretical flaw, our
dependence on knowing all of the incoming links, even though we can&apos;t
necessarily know them.&lt;/p&gt;

&lt;p&gt;When we remove a primary link, we need to know what the next link
is in order to know what will be promoted. In order to maintain
behavior between saves, we need to save all of the incoming links,
&lt;i&gt;in order&lt;/i&gt;; if you miss even one link, that &lt;i&gt;might&lt;/i&gt; have
been the one that should have promoted. Since we can&apos;t even assume we
know what all of them are, this is impractical.&lt;/p&gt;

&lt;p&gt;A lot of practical problems arise as a result. We can&apos;t save
documents. We can&apos;t load documents. We need the entirity of the
Outline Web accessible to determine what will happen if we delete a
primary link. We need access to the foreign documents to move copies
of the node into them if they are the next &quot;primary link&quot;.&lt;/p&gt;

&lt;p&gt;Basically, the &quot;primary link&quot; abstraction just works as long as the
outline nodes are all in memory, and they can all be saved and loaded
like a memory snapshot, not like files. This is an unacceptable
limitation.&lt;/p&gt;

&lt;p&gt;The solution is for nodes to actually keep track of what document
they belong to, and for the nodes to keep track of what incoming links
are coming in on a document-by-document basis. (Actually, it suffices
to track &quot;from my document&quot; vs. &quot;not from my document&quot;, but it&apos;s
convenient and cheap to partition them based on document; that way,
if the node changes documents (cut &amp; paste), we don&apos;t need to
recompute anything.)&lt;/p&gt;

&lt;p&gt;Interestingly, just as much as we need to keep track of the order
of the outgoing links, we do &lt;i&gt;not&lt;/i&gt; want to give order to the
incoming links.&lt;/p&gt;

The End - For Now

&lt;p&gt;We&apos;ve now built an outline data structure, that with one small
penalty (remote links may be broken, which is something we can&apos;t do
much about anyhow), allows the flexibility of graphs with the
ease-of-programming of outlines. On top of this structure, we can
build an outliner that will be robust and flexible.&lt;/p&gt;

&lt;p&gt;Next, I will explore some misc. practical issues brought up by this
discussion.&lt;/p&gt;
</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/02/10.html#P2357</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Tue, 10 Feb 2004 18:08:00 GMT</pubDate>
</item>
<item>
<title>Leo and Iron Lute</title>
<link>http://www.executableabstractions.com/weblog/Outlining/2004/02/03.html#P12</link>
<description>Rand Anderson  &lt;a href=&quot;http://www.executableabstractions.com/weblog/Outlining/2004/02/03.html#P12&quot;&gt;blogs
about Iron Lute and his preferred outliner Leo&lt;/a&gt;:

&lt;blockquote&gt;Seems he&apos;s aware of &lt;a href=&quot;http://webpages.charter.net/edreamleo/front.html&quot;&gt;Leo&lt;/a&gt; (my
outliner of choice) but wants an outliner that allows the use of the
outline structure for all content (as opposed to having a body for
free text associated with each tree node, as Leo does). 

&lt;p&gt;I&apos;m pretty committed to Leo and it&apos;s author&apos;s vision for Leo going
forward, but Iron Lute is worth keeping an eye on.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;First, thanks for the nice comment (&quot;worth keeping an eye on&quot;).&lt;/p&gt;

&lt;p&gt;Since someone&apos;s interested, I thought I&apos;d talk more about why I
didn&apos;t start by extending Leo.&lt;/p&gt;

&lt;p&gt;(Protocol note: When starting an Open Source project, the &lt;i&gt;first
responsibility&lt;/i&gt; of the starter is to determine why existing
projects aren&apos;t worth building off of, so I believe it is necessary
for me to justify why I don&apos;t start with existing projects.)&lt;/p&gt;

&lt;p&gt;Basically, my &quot;problem&quot; with Leo (as in, &quot;the reason I didn&apos;t just
build on that instead of writing my own stuff&quot;, not an actual
&quot;problem&quot;) is Leo is really an &lt;i&gt;application&lt;/i&gt; of an outliner, not
an outliner itself. Leo is &lt;i&gt;using&lt;/i&gt; an outliner to track the
little fiddly bits that constitute the pieces of whatever it is
building (program, website, etc), but you can&apos;t actually use the
outliner to write text in the &quot;outliner&quot; itself.&lt;/p&gt;

&lt;p&gt;By &quot;outliner&quot; here I &lt;i&gt;specifically&lt;/i&gt; mean just the part of Leo
in the &lt;a href=&quot;http://webpages.charter.net/edreamleo/intro.html#screenShot&quot;&gt;upper
left window&lt;/a&gt;, &lt;i&gt;not&lt;/i&gt; the program as a whole; you might think of
it as the outline widget only. I think the reason for this is the
aforementioned difficulty of writing an outline widget with open
source widget sets, and Leo&apos;s author is more interested in Leo
&lt;i&gt;qua&lt;/i&gt; Leo then the outliner itself (which I respect completely),
so Leo&apos;s outliner is highly focused, gets the job done with relatively
minimal attention to outlining (as compared to the gyrations I&apos;m
undertaking, not saying that it was trivial to write per se), and not
usable in the general case. For instance, try to write an essay in the
upper-left window alone; it&apos;s not convenient.&lt;/p&gt;

&lt;p&gt;In programmer parlance, Iron Lute and Leo are almost completely
&lt;i&gt;&lt;a href=&quot;http://www.catb.org/~esr/jargon/html/O/orthogonal.html&quot;&gt;orthogonal&lt;/a&gt;&lt;/i&gt;.
Despite the surface similarity they are actually quite different
projects that share little in common.&lt;/p&gt;

&lt;p&gt;Forgive my splitting hairs like this (&quot;outliner&quot; vs. &quot;using an
outliner&quot;) but it&apos;s an important ability for a programmer.&lt;/p&gt;

&lt;p&gt;As I further develop the outline model you&apos;ll see why it&apos;s a very
different beast then Leo. In the far future (year+), I hope someday
that Leo can use Iron Lute as a display library for their outlines, as
I mentioned on that page. Then Leo can get for free/cheap all the
other stuff I&apos;m talking about, and other exciting things I will talk
about later that I&apos;m sure Leo would just love to have in place.&lt;/p&gt;

&lt;p&gt;It should be very easy to put them together; both are
Python/Tk. Leo&apos;s use of Tk didn&apos;t really enter into my decision to use
Tk, but I consider it a happy side-effect. Ideally, you need not lose
your &quot;commitment&quot; to Leo to continue to be interested in Iron Lute. It
is an explicit design goal to make anything doable with outlines
possible with Iron Lute, so I will have no objection to Leo
specializing Iron Lute in whatever manner is necessary to maintain
Leo&apos;s conceptual integrity; I&apos;m fairly confident that the structure
I&apos;m building will be flexible enough to accomodate what I&apos;ve seen of
Leo with no compromises on Leo&apos;s side.&lt;/p&gt;

&lt;p&gt;I haven&apos;t contacted Leo&apos;s author about any of this because let&apos;s
face it, right now Iron Lute is vaporware to everyone but me. When I
have an actual release it might be worth discussing. In the meantime
it&apos;s not worth bothering him with unless he finds it himself.&lt;/p&gt;

&lt;p&gt;Disclaimer: This may sound presumptuous, as if I&apos;m &quot;planning&quot;
something for somebody elses project. First, I&apos;d like to disclaim
that, this is just something I see that could be beneficial for both
parties. Secondly, integration with Leo would constitute a
&quot;significant contribution&quot; to Iron Lute that would allow it to get to
Open Source status under the license rules I posted earlier, and as
both would then be Open Source projects under compatible licenses,
anybody could do it without &quot;permission&quot;.&lt;/p&gt;
</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/02/04.html#P2269</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Wed, 04 Feb 2004 22:15:28 GMT</pubDate>
</item>
<item>
<title>Iron Lute License</title>
<description>I want to be able to discuss Iron Lute&apos;s planned license in a posting
in response to somebody&apos;s blog here, but first I need to discuss
it. So here are the licensing plans I have for Iron Lute. I&apos;m very
interested in feedback on this.

&lt;p&gt;I&apos;d would like Iron Lute to be open source, likely GPL with
explicit exclusion of plug-ins (i.e., you are explicitly allowed to
create new Node Types, etc., and release them under any license you
like). (This is not &lt;i&gt;quite&lt;/i&gt; the LGPL because you still can not
take Iron Lute and build another application around it; limiting as I
will means you can &quot;connect&quot; Iron Lute to your application but that
you can not just pick up Iron Lute and make it &lt;i&gt;be&lt;/i&gt; your
application.) But that depends on the usage and support pattern it
receives.&lt;/p&gt;

&lt;p&gt;If nobody uses it and nobody helps me with it, then eventually,
I&apos;ll stop supporting it. (No surprise there.) I&apos;ll keep it online and
quite possibly continue using it in my own personal projects, but
unless somebody else shows an interest, no public sign of development
will continue.&lt;/p&gt;

&lt;p&gt;(Truthfully, call me arrogant but I do not consider this likely. I
think there&apos;s a definate niche in the Open Source world for what I am
creating here, partially because of the lack of an outlining widget
that I mentioned in my original post.)&lt;/p&gt;

&lt;p&gt;If I get significant contributions from other developers and other
people (including documentation, help, community helping each other
out a lot, etc.), I&apos;ll make it the aforementioned limited GPL. The
threshold for this is &quot;if I had to remove all contributions other then
mine to date, how painful would that be?&quot; If it can be done swiftly
and painlessly, then I may go to the third option.&lt;/p&gt;

&lt;p&gt;The third option is &quot;a lot of people use it and like it, but nobody
is helping with the development&quot;. In that case I&apos;ll do an analysis,
and either stop development, or try to take it commercial, depending
on feedback.&lt;/p&gt;

&lt;p&gt;I&apos;m thinking of a cut-off date of a year after the initial &quot;stable&quot;
release, which would be some months after the first public release, of
course, so we&apos;re talking about at least a year and a half window,
practically.&lt;/p&gt;

&lt;p&gt;I&apos;d like to say up front that I &lt;i&gt;want&lt;/i&gt; this to be open
source. I want to experience new features of Iron Lute that I didn&apos;t
have to write myself. However, I do not want to tie my hands by
committing to a license &quot;come hell or high water&quot;; the condition above
is not intended as a &quot;loophole I can jump through&quot; so much as a way of
pointing out that two pages of docs and a node type do &lt;i&gt;not&lt;/i&gt;
constitute &quot;significant contributions&quot; in the sense I am
mentioning. Believe me, I will err on the side of &quot;open source&quot; if
anybody gives me the chance.&lt;/p&gt;

&lt;p&gt;So, what license this is released under is at least partially up to
you.&lt;/p&gt;

&lt;p&gt;I will make this commitment though: I will not pull the rug out
from underneath you. Should I end up going commercial, the last &quot;free&quot;
version will be clearly marked, never crippled, and will never
expire. You just won&apos;t get updates and improvements.&lt;/p&gt;
</description>
<guid>http://www.jerf.org/iri/categories/Iron Lute/2004/02/04.html#P2268</guid>
<category domain="http://www.jerf.org/iri/">Iron Lute</category>
<ent:cloud ent:href="http://www.jerf.org/iri/">
<ent:topic ent:id="Iron Lute" ent:href="http://www.jerf.org/iri/categories/Iron Lute/">Iron Lute</ent:topic>
</ent:cloud>
<pubDate>Wed, 04 Feb 2004 22:09:04 GMT</pubDate>
</item>
</channel>
</rss>
