Monday, November 08, 2010 at 12:02 AM.
system.verbs.builtins.Frontier.tools.data.windowTypes.outlinerFile.open
on open (f, adr=nil, flHidden=false, adrButtonTable=nil, windowTitle=nil) {
<<Changes:
<<7/2/05; 11:43:21 AM by DW
<<Comment window.update call, avoid unnecessary flash.
<<6/13/05; 3:19:06 AM by DW
<<Add optional title that allows the caller to set the window title.
<<6/10/05; 12:55:40 PM by DW
<<Add optional parameter that allows a button bar to be provided.
<<5/24/02; 4:52:44 PM by JES
<<When preserving comments at the top of the file, don't save the "OPML generated by" comment. Prevents it from being added again when the file is saved.
<<10/11/01; 3:04:49 AM by JES
<<If the file is already opened, bring its window to the front, instead of opening a new window.
<<8/9/01; 1:15:13 AM by JES
<<Replace line ending characters with CR's. Prevents UNIX (MacOS X) files from opening on a single outline headline.
bundle { //if the window is already open, bring it to the front
local (t); new (tableType, @t);
local (adrtype = parentOf (this^));
t.type = "outlinerFile";
t.f = f;
local (adrwindow);
if Frontier.tools.windowTypes.findWindowWithMatchingAtts (@t, @adrwindow) {
local (title, flReadOnly = false);
window.attributes.getOne ("title", @title, adrwindow);
window.attributes.getOne ("flReadOnly", @flReadOnly, adrwindow);
if not flHidden {
edit (adrwindow, title, flReadOnly, adrButtonTable);
return (true)}}};
local (outlinerSuffixes = {"xml", "opml", "txt", "html", "htm", "py"});
on isOutlinerFile () {
if string.lower (file.type (f)) == "opml" { //PBS 09/26/00: might be lower on Windows, upper on Macs
return (true)};
local (lowerSuffix = string.lower (string.nthField (f, ".", string.countFields (f, "."))));
if outlinerSuffixes contains lowerSuffix {
return (true)};
if system.environment.isMac { //all text files on Macs
if file.type (f) == 'TEXT' {
local (objectSuffixes = {"fat", "2clk", "card", "fatp", "ftds", "ftmb", "ftop", "ftsc", "fttb", "ftwp", "osas", "osax", "rsrc", "stak", "ucmd"});
if not (objectSuffixes contains lowerSuffix) {
return (true)}}};
return (false)};
on isOPML (s) { //is this an OPML file?
if string.lower (f) endsWith ".opml" and s == "" { //05/15/2001 JES: empty files are empty OPML documents, if the extension is .opml
return (true)};
s = string.replaceAll (s, "\r\n", "\r");
s = string.replaceAll (s, "\n", "\r"); //support unix text files
s = string.trimWhiteSpace (s); //05/15/2001 JES
if s beginsWith "<?xml " {
local (startByte = sizeOf (s) - 200);
if startByte < 1 {
startByte = 1};
local (last200bytes = string.mid (s, startByte, infinity));
last200bytes = string.lower (string.trimWhiteSpace (last200bytes));
if last200bytes endsWith "</outlinedocument>" {
return (true)};
if last200bytes endsWith "</opml>" {
return (true)}};
if s beginsWith "<opml " or s beginsWith "<outlineDocument " {
return (true)};
return (false)};
if isOutlinerFile () { //we get to handle it
if adr == nil { //it's a new window -- get one
adr = Frontier.tools.windowTypes.newWindow ("outlinerFile", true)};
local (title = file.fileFromPath (f));
if windowTitle != nil { //6/13/05; 3:20:47 AM by DW
title = windowTitle};
local (timeCreated = file.created (f));
local (timeModified = file.modified (f));
local (s = file.readWholeFile (f));
bundle { //set attributes
local (t); new (tableType, @t);
t.f = f;
t.timeCreated = timeCreated;
t.lastSaved = timeModified;
t.title = title;
if system.environment.isMac { //remember the type and creator
t.fileType = file.type (f);
t.fileCreator = file.creator (f)};
bundle { //determine line-ending, convert text
local (ix = 1);
while ix < sizeOf (s) { //find the first line ending and determine whether it's Windows, Mac, or UNIX
case s[ix] {
'\n' {
t.lineEnding = "\n";
break};
'\r' {
if s[ix+1] == '\n' {
t.lineEnding = "\r\n"}
else {
t.lineEnding = "\r"};
break}};
ix++};
if defined (t.lineEnding) {
s = string.replaceAll (s, t.lineEnding, "\r")}};
window.attributes.addGroup (@t, adr)};
if isOPML (s) {
if system.environment.isMac { //12/31/00 JES: convert to Mac text.
s = string.latinToMac (s)};
s = string.replaceAll (s, "\r\n", "\r");
s = string.replaceAll (s, "\n", "\r"); //support unix text files
bundle { //01/23/01 JES: support style sheet declarations
local (xmlHeaders = "");
for i = 2 to 100 { // allow for up to 99 lines between <xml> and <outlineDocument>
local (aLine = string.nthField (s, "\r", i));
local (lowerLine = string.trimWhiteSpace (string.lower (aLine)));
if lowerLine beginsWith "<opml " {
break};
if lowerLine beginsWith "<outlinedocument " {
break};
if string.trimWhiteSpace (aLine) != "" { //05/15/2001 JES: don't add lines which are plain whitespace
if not (string.lower (string.trimWhiteSpace (aLine)) beginsWith "<!-- opml generated by ") { //05/24/02 JES: skip "generated by" comments so they don't get doubled-up by op.outlineToXml
xmlHeaders = xmlHeaders + aLine + "\r"}}};
if sizeOf (string.trimWhiteSpace (xmlHeaders)) > 0 { //05/24/02 JES: only add headers if they actually exist
window.attributes.setOne ("xmlHeaders", xmlHeaders, adr)}};
if not (string.trimWhiteSpace (s) == "") { //don't error on empty files -- treat as empty outlines
op.xmlToOutline (s, adr)};
window.attributes.setOne ("flOutlineDocument", true, adr)}
else { //open in outliner as raw XML
op.newOutlineObject (s, adr);
local (oldTarget = target.set (adr));
op.firstSummit ();
op.fullExpand ();
try {target.set (oldTarget)};
window.attributes.setOne ("flOutlineDocument", false, adr)};
if not flHidden {
edit (adr, adrButtonTable:adrButtonTable)};
window.setTitle (adr, title);
<<window.update (adr) //commented -- 7/2/05; 11:43:13 AM by DW
setTimeCreated (adr, timeCreated); //03/05/2001 JES: preserve timeCreated for the OPML header
setTimeModified (adr, timeModified); //03/05/2001 JES: preserve timeCreated for the OPML header
return (true)};
return (false)} //we didn't handle the file
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.