Code

Remove any "inkscape:*" or "sodipodi:*" attributes when saving as "plain SVG". Fixes...
[inkscape.git] / src / extension / internal / svg.cpp
index 47f1ce31bfddebd7ac7c67648b862f408b2d63f2..b10aa87ec0d4d62fbe6b04be28f8056b801d12da 100644 (file)
@@ -21,6 +21,7 @@
 #include "extension/system.h"
 #include "extension/output.h"
 #include <vector>
+#include "xml/attribute-record.h"
 
 #ifdef WITH_GNOME_VFS
 # include <libgnomevfs/gnome-vfs.h>
@@ -32,6 +33,37 @@ namespace Internal {
 
 #include "clear-n_.h"
 
+
+using Inkscape::Util::List;
+using Inkscape::XML::AttributeRecord;
+using Inkscape::XML::Node;
+
+
+
+void pruneExtendedAttributes( Inkscape::XML::Node *repr )
+{
+    if (repr) {
+        if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) {
+            std::vector<gchar const*> toBeRemoved;
+            for ( List<AttributeRecord const> it = repr->attributeList(); it; ++it ) {
+                const gchar* attrName = g_quark_to_string(it->key);
+                if ((strncmp("inkscape:", attrName, 9) == 0) || (strncmp("sodipodi:", attrName, 9) == 0)) {
+                    toBeRemoved.push_back(attrName);
+                }
+            }
+            // Can't change the set we're interating over while we are iterating.
+            for ( std::vector<gchar const*>::iterator it = toBeRemoved.begin(); it != toBeRemoved.end(); ++it ) {
+                repr->setAttribute(*it, 0);
+            }
+        }
+
+        for ( Node *child = repr->firstChild(); child; child = child->next() ) {
+            pruneExtendedAttributes(child);
+        }
+    }
+}
+
+
 /**
     \return   None
     \brief    What would an SVG editor be without loading/saving SVG
@@ -51,7 +83,7 @@ Svg::init(void)
 
     /* SVG in */
     ext = Inkscape::Extension::build_from_mem(
-        "<inkscape-extension>\n"
+        "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
             "<name>" N_("SVG Input") "</name>\n"
             "<id>" SP_MODULE_KEY_INPUT_SVG "</id>\n"
             "<input>\n"
@@ -65,7 +97,7 @@ Svg::init(void)
 
     /* SVG out Inkscape */
     ext = Inkscape::Extension::build_from_mem(
-        "<inkscape-extension>\n"
+        "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
             "<name>" N_("SVG Output Inkscape") "</name>\n"
             "<id>" SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE "</id>\n"
             "<output>\n"
@@ -73,13 +105,13 @@ Svg::init(void)
                 "<mimetype>image/x-inkscape-svg</mimetype>\n"
                 "<filetypename>" N_("Inkscape SVG (*.svg)") "</filetypename>\n"
                 "<filetypetooltip>" N_("SVG format with Inkscape extensions") "</filetypetooltip>\n"
-                "<dataloss>FALSE</dataloss>\n"
+                "<dataloss>false</dataloss>\n"
             "</output>\n"
         "</inkscape-extension>", new Svg());
 
     /* SVG out */
     ext = Inkscape::Extension::build_from_mem(
-        "<inkscape-extension>\n"
+        "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
             "<name>" N_("SVG Output") "</name>\n"
             "<id>" SP_MODULE_KEY_OUTPUT_SVG "</id>\n"
             "<output>\n"
@@ -175,11 +207,11 @@ Svg::open (Inkscape::Extension::Input */*mod*/, const gchar *uri)
     \param     doc   Document to save.
     \param     uri   The filename to save the file to.
 
-    This function first checks it's parameters, and makes sure that
+    This function first checks its parameters, and makes sure that
     we're getting good data.  It also checks the module ID of the
-    incoming module to figure out if this is save should include
+    incoming module to figure out whether this save should include
     the Inkscape namespace stuff or not.  The result of that comparison
-    is stored in the spns variable.
+    is stored in the exportExtensions variable.
 
     If there is not to be Inkscape name spaces a new document is created
     without.  (I think, I'm not sure on this code)
@@ -191,35 +223,35 @@ Svg::open (Inkscape::Extension::Input */*mod*/, const gchar *uri)
     all of this code.  I just stole it.
 */
 void
-Svg::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
+Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
 {
     g_return_if_fail(doc != NULL);
-    g_return_if_fail(uri != NULL);
+    g_return_if_fail(filename != NULL);
 
-    gchar *save_path = g_path_get_dirname (uri);
+    gchar *save_path = g_path_get_dirname(filename);
 
-    gboolean const spns = (!mod->get_id()
+    bool const exportExtensions = ( !mod->get_id()
       || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE)
       || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE));
 
     Inkscape::XML::Document *rdoc = NULL;
     Inkscape::XML::Node *repr = NULL;
-    if (spns) {
+    if (exportExtensions) {
         repr = sp_document_repr_root (doc);
     } else {
         rdoc = sp_repr_document_new ("svg:svg");
         repr = rdoc->root();
-        repr = sp_document_root (doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
-    }
+        repr = sp_document_root (doc)->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD);
 
-    Inkscape::IO::fixupHrefs( doc, save_path, spns );
+        pruneExtendedAttributes(repr);
+    }
 
-    gboolean const s = sp_repr_save_file (repr->document(), uri, SP_SVG_NS_URI);
-    if (s == FALSE) {
+    if (!sp_repr_save_rebased_file(repr->document(), filename, SP_SVG_NS_URI,
+                                   doc->base, filename)) {
         throw Inkscape::Extension::Output::save_failed();
     }
 
-    if (!spns) {
+    if (!exportExtensions) {
         Inkscape::GC::release(rdoc);
     }