Omnioutliner to BBCode conversion - my php script
Thom Brooks
omni_groupie at unithom.com
Thu Jul 13 01:06:18 PDT 2006
Is there an SDK for developing OmniOutliner export plugins? If so, or if
not, would there be sufficient interest in creating a BBCode export option
from OmniOutliner? Just throwing it out there.
I ask, because I was asked to post some notes I took in OmniOutliner Pro... on
a web discussion forum where they use BBCode instead of regular HTML to
format stuff.
Embedded lists in BBCode look like this:
[list]Item 1
[list]Item 1a
Item 1b[/list]
Item 2
Item 3
[list]Item 3a
Item 3b[/list]
Item 4
The above would produce this output:
Item 1
Item 1a
Item 1b
Item 2
Item 3
Item 3a
Item 3b
Item 4
Fairly simple and straightforward, but I was kind of racking my brain as to
how to get my OmniOutliner document into this format. So I wrote this PHP
script, called 'convert.' In my example below, I copied this script into my
Documents -> planning folder, where I'm keeping the rest of my files.
---------------------------------convert----------------------
#!/usr/bin/php
<?php
// Take first command line argument as the filename
$fa = file($_SERVER["argv"][1]);
$prevtabs = 0;
$ent_table = array("-" => "−", " " => " ", "+" => "√");
// test it out first -- first ten lines only!
// for ($i=0; $i < 10; $i++)
for ($i=0; $i < count($fa); $i++)
{
$match_array = array();
$itworked = preg_match("#^([\t]{0,})(- \[[+\- ]\] )(.*)$#", $fa[$i], $match_array);
if ($itworked)
{
$curtabs = strlen($match_array[1]);
$thediff = $curtabs - $prevtabs;
if ($thediff > 0) // means we indented inwards.
{
if ($i > 0) // not on the very first line
{
print "∇ " . $prev_line;
}
print str_repeat("[list]", $thediff);
}
else if ($thediff < 0)
{
if ($i > 0) // not on the very first line
{
print "• " . $prev_line;
}
print str_repeat("[/list]", $thediff * -1);
}
else // same, no change
{
if ($i > 0) // not on the very first line
{
print "• " . $prev_line;
}
}
// set this as the previous line amount now
$prevtabs = $curtabs;
$prev_line = "[" . $ent_table[$match_array[2][3]]. "] " . $match_array[3] . "\n";
}
else
{
// The match failed, so err on the side of caution,
// and print the previous line with a bullet,
// then set the new 'previous line' to be the whole line we
// couldn't match
if ($i > 0) // not on the very first line
{
print "• " . $prev_line;
}
$prev_line = $fa[$i];
}
}
// last line has no children, by definition, so:
print "• " . $prev_line;
// close out any indents
if ($prevtabs > 0)
{
print str_repeat("[/list]", $prevtabs);
}
?>
-------------------------------------------------------------------
Usage:
Export your OmniOutliner document as tab-separated values (a .tsv file. Except
OmniOutliner's export insists on making it end in .txt. Ugh. Can we please get
a 'Hide file extension' checkbox to uncheck, and then override the default?)
In the Terminal, change directories to the folder containing this script, and
your TSV file.
unixprompt> cd ~/Documents/planning
I called my exported file, planning_notes.txt
And I want my output file called, 'output.txt':
unixprompt> ./convert planning_notes.txt > output.txt
If it doesn't work - remember to make the script executable first:
unixprompt> chmod 755 convert
If you don't redirect the output into a file, it will just print right in the
terminal window, which may be preferred:
unixprompt> ./convert planning_notes.txt
[b]∇ [ ] Intro[/b]
[list][b]∇ [ ] Who are we[/b]
[list][b]• [ ] and what are our goals while we're here?[/b]
[/list]∇ [ ] Thom
[list]• [ ] Tech Team Director
• [ ] How can tech team help?
[/list]
[/list]
etc.
* * *
Some notes about the code and formatting -
I chose to use the • entity, whose code is • for all of the 'leaf'
items, and I decided to use the ∇ (∇) entity, the downward
pointing triangle, to represent 'branches' (rows with children).
I did this by not printing each line immediately; instead I saved it until the
next time through the loop, where I could see whether the next line indented
further. Based on this, I knew whether to make it a bullet or an open
'disclosure triangle.' ;)
After either the triangle or bullet, I kept the square brackets containing
either a space (unchecked), a 'minus' entity (−) or a "√" (which
is √), for a 'checked off' item. The conversion table is near the top,
in the $ent_table array.
Note that I commented out a 'first ten lines only' version of my for-loop --
I'd used that earlier so I could test and see if it would work, before turning
it loose on my whole document!
One frustrating thing was, choosing to start from the tab separated values
format didn't give me any style information. So I still ended up going through
my document once it had been exported and converted, and [b]re-bolding[/b]
certain lines after the fact. This is obviously not the most ideal
solution, but it's a solution. (I made a custom BBEdit Glossary folder called
'BBCode' with a 'bold' file in it, simply containing [b]#select#[/b] and I
assigned that to a key. Then I selected each line I wanted to bold and hit my
hotkey.)
I started out with a much simpler version of this script, but then I fell
victim to 'feature creep' and I kept making it better... and now I'm really
happy with the results.
Anyway, hope this script is of use to someone out there.
Thom Brooks
Chicago, IL
More information about the OmniOutliner-Users
mailing list