[tomboy] Fix for #652783, resolves relative paths between exported notes.



commit e25f42a594428f7a5b46f9df593617886db4628c
Author: Robert Nordan <rpvn robpvn net>
Date:   Sat Jun 25 10:04:43 2011 +0200

    Fix for #652783, resolves relative paths between exported notes.
    
    Signed-off-by: Jared Jennings <jjennings src gnome org>

 Tomboy/Addins/ExportToHtml/ExportToHtml.xsl        |   16 +++-
 .../ExportToHtml/ExportToHtmlApplicationAddin.cs   |  106 +++++++++++++++++++-
 Tomboy/ExportAllApplicationAddin.cs                |   69 +++++++++++++
 3 files changed, 186 insertions(+), 5 deletions(-)
---
diff --git a/Tomboy/Addins/ExportToHtml/ExportToHtml.xsl b/Tomboy/Addins/ExportToHtml/ExportToHtml.xsl
index eeabc22..8d1dea5 100644
--- a/Tomboy/Addins/ExportToHtml/ExportToHtml.xsl
+++ b/Tomboy/Addins/ExportToHtml/ExportToHtml.xsl
@@ -12,6 +12,7 @@
 <xsl:param name="export-linked" />
 <xsl:param name="export-linked-all" />
 <xsl:param name="root-note" />
+<xsl:param name="exporting-multiple" />
 
 <xsl:param name="newline" select="'&#xA;'" />
 
@@ -133,9 +134,18 @@
 </xsl:template>
 
 <xsl:template match="link:internal">
-	<a style="color:#204A87" href="#{tomboy:ToLower(node())}">
-		<xsl:value-of select="node()"/>
-	</a>
+	<xsl:choose>
+		<xsl:when test="$exporting-multiple">
+			<a style="color:#204A87" href="{tomboy:GetRelativePath(node())}">
+				<xsl:value-of select="node()"/>
+			</a>
+		</xsl:when>
+		<xsl:otherwise>
+			<a style="color:#204A87" href="#{tomboy:ToLower(node())}">
+				<xsl:value-of select="node()"/>
+			</a>
+		</xsl:otherwise>
+	</xsl:choose>
 </xsl:template>
 
 <xsl:template match="link:url">
diff --git a/Tomboy/Addins/ExportToHtml/ExportToHtmlApplicationAddin.cs b/Tomboy/Addins/ExportToHtml/ExportToHtmlApplicationAddin.cs
index 737d4bc..7432361 100644
--- a/Tomboy/Addins/ExportToHtml/ExportToHtmlApplicationAddin.cs
+++ b/Tomboy/Addins/ExportToHtml/ExportToHtmlApplicationAddin.cs
@@ -1,5 +1,9 @@
 using System;
 using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
 using Tomboy;
 using Mono.Unix;
 
@@ -11,7 +15,40 @@ namespace Tomboy.ExportToHtml
 	public class ExportToHtmlApplicationAddin : ExportAllApplicationAddin
 	{
 
-		ExportToHtmlNoteAddin exporter = new ExportToHtmlNoteAddin ();
+		const string stylesheet_name = "ExportToHtml.xsl";
+		static XslTransform xsl;
+
+		Gtk.ImageMenuItem item;
+
+		static XslTransform NoteXsl
+		{
+			get {
+				if (xsl == null) {
+					Assembly asm = Assembly.GetExecutingAssembly ();
+					string asm_dir = System.IO.Path.GetDirectoryName (asm.Location);
+					string stylesheet_file = Path.Combine (asm_dir, stylesheet_name);
+
+					xsl = new XslTransform ();
+
+					if (File.Exists (stylesheet_file)) {
+						Logger.Info ("ExportToHTML: Using user-custom {0} file.",
+						            stylesheet_name);
+						xsl.Load (stylesheet_file);
+					} else {
+						Stream resource = asm.GetManifestResourceStream (stylesheet_name);
+						if (resource != null) {
+							XmlTextReader reader = new XmlTextReader (resource);
+							xsl.Load (reader, null, null);
+							resource.Close ();
+						} else {
+							Logger.Error ("Unable to find HTML export template '{0}'.",
+							            stylesheet_name);
+						}
+					}
+				}
+				return xsl;
+			}
+		}
 
 		/// <summary>
 		/// Sets the names of the export type.
@@ -43,12 +80,77 @@ namespace Tomboy.ExportToHtml
 
 			writer = new StreamWriter (output_path);
 
-			exporter.WriteHTMLForNote (writer, note, false, false);
+			WriteHTMLForNote (writer, note);
 
 			if (writer != null)
 				writer.Close ();
 
 			return;
 		}
+
+		public void WriteHTMLForNote (TextWriter writer,
+		                              Note note)
+		{
+			// NOTE: Don't use the XmlDocument version, which strips
+			// whitespace between elements for some reason.  Also,
+			// XPathDocument is faster.
+			StringWriter s_writer = new StringWriter ();
+			NoteArchiver.Write (s_writer, note.Data);
+			StringReader reader = new StringReader (s_writer.ToString ());
+			s_writer.Close ();
+			XPathDocument doc = new XPathDocument (reader);
+			reader.Close ();
+
+			XsltArgumentList args = new XsltArgumentList ();
+			args.AddParam ("exporting-multiple", "", true);
+			args.AddParam ("export-linked", "", false);
+			args.AddParam ("export-linked-all", "", false);
+			args.AddParam ("root-note", "", note.Title);
+			args.AddExtensionObject ("http://beatniksoftware.com/tomboy";,
+				new ExportAllTransformExtension (note, this));
+
+			if ((bool) Preferences.Get (Preferences.ENABLE_CUSTOM_FONT)) {
+				string font_face = (string) Preferences.Get (Preferences.CUSTOM_FONT_FACE);
+				Pango.FontDescription font_desc =
+				        Pango.FontDescription.FromString (font_face);
+				string font = String.Format ("font-family:'{0}';", font_desc.Family);
+
+				args.AddParam ("font", "", font);
+			}
+
+			NoteXsl.Transform (doc, args, writer);
+		}
+	}
+
+		/// <summary>
+	/// Makes <see cref="System.String.ToLower"/> available in the
+	/// XSL stylesheet and resolves relative paths between notes.
+	/// </summary>
+	public class ExportAllTransformExtension
+	{
+		private Note note;
+		private ExportToHtmlApplicationAddin parent;
+
+		public ExportAllTransformExtension (Note note, ExportToHtmlApplicationAddin parent)
+		{
+			this.note = note;
+			this.parent = parent;
+		}
+
+		public String ToLower (string s)
+		{
+			return s.ToLower ();
+		}
+
+		public string GetRelativePath (string title_to)
+		{
+			if (string.IsNullOrEmpty (title_to))
+				return string.Empty;
+
+			//Get the the value from the exportAll superclass, changing from platform
+			//dependent to URL drectory seperators since we're making HTML.
+			string system_relative_path = parent.ResolveRelativePath (note, title_to);
+			return system_relative_path.Replace (System.IO.Path.DirectorySeparatorChar, '/');
+		}
 	}
 }
diff --git a/Tomboy/ExportAllApplicationAddin.cs b/Tomboy/ExportAllApplicationAddin.cs
index a42eb47..6bfdad9 100644
--- a/Tomboy/ExportAllApplicationAddin.cs
+++ b/Tomboy/ExportAllApplicationAddin.cs
@@ -32,6 +32,11 @@ namespace Tomboy
 		private bool initialized = false;
 
 		/// <summary>
+		/// Used to inform the path resolver if all notes are being exported or just one notebook.
+		/// </summary>
+		private bool exporting_single_notebook = false;
+
+		/// <summary>
 		/// Called when Tomboy has started up and is nearly 100% initialized.
 		/// </summary>
 		public override void Initialize ()
@@ -141,6 +146,7 @@ namespace Tomboy
 		void ExportAllNotes ()
 		{
 			Logger.Info ("Activated export all to " + export_type_pretty_name);
+			exporting_single_notebook = false;
 
 			//Opens the folder selection dialog
 			ExportMultipleDialog dialog =
@@ -236,6 +242,7 @@ namespace Tomboy
 						return;
 					}
 
+					exporting_single_notebook = true;
 					Logger.Debug ("Creating an export folder in: " + output_folder);
 					System.IO.Directory.CreateDirectory (output_folder);
 					ExportNotesInList (ListUnfiledNotes (), output_folder);
@@ -250,6 +257,7 @@ namespace Tomboy
 						return;
 					}
 
+					exporting_single_notebook = true;
 					Logger.Debug ("Creating an export folder in: " + output_folder);
 					System.IO.Directory.CreateDirectory (output_folder);
 					ExportNotesInList (notebook.Tag.Notes, output_folder);
@@ -425,6 +433,67 @@ namespace Tomboy
 			dialog.Destroy ();
 			Logger.Error (error_message);
 		}
+
+		/// <summary>
+		/// Determines the relative path between two exported files, can optionally be used
+		/// by the subclass.
+		/// </summary>
+		/// <param name="title_from">
+		/// The note we're finding the relative path from.
+		/// </param>
+		/// <param name="title_to">
+		/// The title of the note we're finding the relative path to.
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		public string ResolveRelativePath (Note note_from, string title_to)
+		{
+			NoteManager manager = Tomboy.DefaultNoteManager;
+			Note note_to = manager.Find (title_to);
+			string title_from = SanitizeNoteTitle (note_from.Title);
+			title_to = SanitizeNoteTitle (note_to.Title);
+
+			if (exporting_single_notebook) {
+				//If there is only one notebook being exported
+				if (NotebookManager.GetNotebookFromNote (note_from) == NotebookManager.GetNotebookFromNote (note_to)) {
+					return title_to + "." + export_file_suffix;
+				} else {
+					return "";
+				}
+			} else {
+				//If all notebooks are available
+				if (NotebookManager.GetNotebookFromNote (note_from) == NotebookManager.GetNotebookFromNote (note_to)) {
+					//Both notes are in the same notebook
+					return title_to + "." + export_file_suffix;
+				} else {
+					//Unfiled notes are a special case because they're in the root directory and will
+					// throw an exception from the notebookmanager
+					string notebook_from;
+					string notebook_to;
+					try {
+						notebook_from = NotebookManager.GetNotebookFromNote (note_from).NormalizedName;
+					} catch (Exception ex) {
+						notebook_from = "___NotebookManager___UnfiledNotes__Notebook___"; //TODO: Ugly!
+					}
+					try {
+						notebook_to = NotebookManager.GetNotebookFromNote (note_to).NormalizedName;
+					} catch (Exception ex) {
+						notebook_to = "___NotebookManager___UnfiledNotes__Notebook___";
+					}
+
+					if (notebook_to == "___NotebookManager___UnfiledNotes__Notebook___") {
+						return ".." + System.IO.Path.DirectorySeparatorChar + title_to + "." + export_file_suffix;
+					} else if (notebook_from == "___NotebookManager___UnfiledNotes__Notebook___") {
+						return SanitizePath (notebook_to) + System.IO.Path.DirectorySeparatorChar
+							+ title_to + "." + export_file_suffix;
+					} else {
+						return ".." + System.IO.Path.DirectorySeparatorChar + SanitizePath (notebook_to)
+							+ System.IO.Path.DirectorySeparatorChar + title_to + "." + export_file_suffix;
+					}
+				}
+			}
+		}
 	}
 
 	/// <summary>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]