Monday, November 08, 2010 at 12:02 AM.

on save (adr, flClosing=false) {
		<<7/8/06; 3:25:10 PM by DW
			<<Wake up the (new) fileSynch thread when an outline file is saved. We want the same instant-upload that we get in the folderWatcher in dotOpml.root. 
		<<8/10/05; 6:27:55 AM by DW
			<<Added code that pops all the hoists before saving, then restores them.
			<<Saving with something hoisted was a disaster. It only saves the hoisted material, the rest is lost. Reported on the opml-support list by David Wilkinson.
		<<6/13/05; 2:31:51 PM by DW
			<<If it's the OPML editor, call back, so we can do an immediate scan of the folder if it's in the www folder. Makes for quicker upstreaming. It's done within a try so there's no harm if it's not present.
		<<6/25/02; 1:06:47 AM by JES
			<<Set the title attribute of the window after it's been saved. The title attribute is used when creating bookmarks for disk-based outline files.
		<<3/26/02; 6:30:59 PM by JES
			<<If the window has an adrCloud attribute, add a <cloud> element to the OPML file.
			<<We make a local copy of the cloudData table, rename server to domain.
			<<If the window has a requestNotificationProcedure attribute, use its value for the registerProcedure cloudData sub-element.
		<<8/9/01; 1:11:41 AM by JES
			<<Preserve line endings for non-OPML files.
			<<On MacOS X, default to LF for the line ending.
	local (atts);
	window.attributes.getAll (@atts, adr);
	local (f = window.getTitle (adr));
	if not (string.lower (f) endsWith (".opml")) {
		if not (f contains ".") {
			f = f + ".opml"}};
	on saveFile () {
		try {
			msg ("Saving \"" + f + "\"."); //Monday, August 21, 2000 at 5:47:45 AM by DW
			atts.title = file.fileFromPath (f);
			window.setTitle (adr, atts.title);
			local (xmlText);
			if defined (atts.flOutlineDocument) { //PBS 09/15/00: it may be raw XML
				if not (atts.flOutlineDocument) {
					xmlText = string (adr^); //raw XML is just string of the outline
					if defined (atts.lineEnding) { //use the same line ending as the original document
						xmlText = string.replaceAll (xmlText, "\r", atts.lineEnding)}
					else { //add linefeeds if this is Windows or change to LF's if MacOS X
						bundle {
							if system.environment.isWindows {
								xmlText = string.replaceAll (xmlText, "\r", "\r\n")};
							if system.environment.isCarbon {
								xmlText = string.replaceAll (xmlText, "\r", "\n")}}};
					if defined (atts.fileCreator) { //02/21/2001 JES: save with recorded type/creator
						file.writeWholeFile (f, xmlText, atts.fileType, atts.fileCreator)}
					else {
						file.writeWholeFile (f, xmlText, 'TEXT', 'Radu')}}};
			if xmlText == nil { //if it's an outlineDocument, xmlText is not yet set
				local (cloud, adrcloud);
				if defined (atts.adrCloud) {
					cloud = atts.adrCloud^;
					if not defined (cloud.domain) {
						table.rename (@cloud.server, "domain")};
					if defined (atts.requestNotificationProcedure) {
						cloud.registerProcedure = atts.requestNotificationProcedure};
					adrcloud = @cloud};
				bundle { //get xmltext, got more complicated, 8/10/05; 6:29:23 AM by DW
					local (stack = {}, cursor, olddisplay = op.setdisplay (false), i);
					loop {
						stack = stack + {op.getcursor ()};
						if not op.dehoist () {
					xmlText = op.outlineToXml (adr, adrcloud:adrcloud); //convert to OPML
					for i = sizeof (stack) downto 2 {
						local (cursor = stack [i]);
						op.setcursor (cursor);
						op.hoist ()};
					op.setdisplay (olddisplay)};
				bundle { //01/23/01 JES: support style sheet declarations
					if defined (atts.xmlHeaders) {
						local (ix = string.patternMatch ("?>", xmlText) + 3);
						xmlText = string.insert (atts.xmlHeaders, xmlText, ix)}};
				if defined (atts.lineEnding) { //02/21/2001 JES: save the file with the recorded line-endings
					xmlText = string.replaceAll (xmlText, "\r", atts.lineEnding)};
				if system.environment.isMac { //12/31/00 JES: convert Mac text to latin
					xmlText = string.macToLatin (xmlText)};
				if defined (atts.fileCreator) { //02/21/2001 JES: save with recorded type/creator
					file.writeWholeFile (f, xmlText, atts.fileType, atts.fileCreator)}
				else {
					file.writeWholeFile (f, xmlText, 'OPML', 'Radu')}}; //PBS 09/21/00: save with Mac codes
			window.attributes.setOne ("f", f, adr);
			window.attributes.setOne ("title", atts.title);
			msg ("");
			bundle { //call back if it's the OPML editor, 6/13/05; 2:34:00 PM by DW
				if defined (system.environment.isOpmlEditor) {
					if system.environment.isOpmlEditor {
						try {
							dotOpmlSuite.fileSaveCallback (f)};
						try { //we want the same effect for all other file synch guys
							fileSynch.thread.wake ()}}}};
			return (true)}
		else {
			window.attributes.setOne ("savingError", tryError, adr);
			dialog.alert (tryError);
			return (false)}};
	if defined (atts.f) { //save files whose path is already known
		f = atts.f;
		if f != "" {
			return (saveFile ())}};
	if not (file.putFileDialog ("Save as:", @f)) {
		return (false)}; //prevent other callbacks from running
	local (defaultExtension = ".opml");
	local (flOutlineDocument = false);
	if defined (atts.flOutlineDocument) { //PBS 12/26/00: check extension only with OPML documents
		flOutlineDocument = atts.flOutlineDocument}
	else { //it's a new document, so it's opml
		flOutlineDocument = true};
	if flOutlineDocument { //ensure .opml extension
		if not (string.lower (f) endsWith defaultExtension) {
			f = f + defaultExtension}}
	else { //PBS 12/26/00: if no extension, use .txt extension
		local (fname = file.fileFromPath (f));
		if not (fname contains ".") {
			f = f + ".txt"}};
	return (saveFile ());
	return (true)};
bundle { //debugging
	save (["0000008"].window, false)}

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.