Code

r16525@tres: ted | 2007-09-11 20:49:47 -0700
authorgouldtj <gouldtj@users.sourceforge.net>
Wed, 12 Sep 2007 06:36:45 +0000 (06:36 +0000)
committergouldtj <gouldtj@users.sourceforge.net>
Wed, 12 Sep 2007 06:36:45 +0000 (06:36 +0000)
 Adding in code to XSLT.

src/extension/implementation/xslt.cpp
src/extension/implementation/xslt.h
src/xml/repr-io.cpp

index 3301679ccd1b1a184aca242e644d0ccb942bced1..cb3260d3731cce87976ecd3244b4f6a2bd722993 100644 (file)
@@ -5,7 +5,7 @@
  * Authors:
  *   Ted Gould <ted@gould.cx>
  *
- * Copyright (C) 2006 Authors
+ * Copyright (C) 2006-2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #endif
 
 #include "xslt.h"
+#include "../extension.h"
+#include "../output.h"
 
+#include "xml/repr.h"
+#include "io/sys.h"
+#include "file.h"
+
+#include <libxml/parser.h>
+#include <libxslt/transform.h>
+
+Inkscape::XML::Document * sp_repr_do_read (xmlDocPtr doc, const gchar * default_ns);
 
 /* Namespaces */
 namespace Inkscape {
@@ -30,8 +40,187 @@ namespace Implementation {
 
 */
 XSLT::XSLT(void) :
-    Implementation()
+    Implementation(),
+    _filename(""),
+    _parsedDoc(NULL),
+    _stylesheet(NULL)
+{
+}
+
+Glib::ustring
+XSLT::solve_reldir(Inkscape::XML::Node *reprin) {
+
+    gchar const *s = reprin->attribute("reldir");
+
+    if (!s) {
+        Glib::ustring str = sp_repr_children(reprin)->content();
+        return str;
+    }
+
+    Glib::ustring reldir = s;
+
+    if (reldir == "extensions") {
+
+        for (unsigned int i=0;
+            i < Inkscape::Extension::Extension::search_path.size();
+            i++) {
+
+            gchar * fname = g_build_filename(
+               Inkscape::Extension::Extension::search_path[i],
+               sp_repr_children(reprin)->content(),
+               NULL);
+            Glib::ustring filename = fname;
+            g_free(fname);
+
+            if ( Inkscape::IO::file_test(filename.c_str(), G_FILE_TEST_EXISTS) )
+                return filename;
+
+        }
+    } else {
+        Glib::ustring str = sp_repr_children(reprin)->content();
+        return str;
+    }
+
+    return "";
+}
+
+bool
+XSLT::check(Inkscape::Extension::Extension *module)
+{
+    if (load(module)) {
+        unload(module);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool
+XSLT::load(Inkscape::Extension::Extension *module)
+{
+    if (module->loaded()) { return true; }
+
+    Inkscape::XML::Node *child_repr = sp_repr_children(module->get_repr());
+    while (child_repr != NULL) {
+        if (!strcmp(child_repr->name(), "xslt")) {
+            child_repr = sp_repr_children(child_repr);
+            while (child_repr != NULL) {
+                if (!strcmp(child_repr->name(), "file")) {
+                    _filename = solve_reldir(child_repr);
+                }
+                child_repr = sp_repr_next(child_repr);
+            }
+
+            break;
+        }
+        child_repr = sp_repr_next(child_repr);
+    }
+
+    _parsedDoc = xmlParseFile(_filename.c_str());
+    if (_parsedDoc == NULL) { return false; }
+
+    _stylesheet = xsltParseStylesheetDoc(_parsedDoc);
+
+    return true;
+}
+
+void
+XSLT::unload(Inkscape::Extension::Extension *module)
 {
+    if (!module->loaded()) { return; }
+    xsltFreeStylesheet(_stylesheet);
+    xmlFreeDoc(_parsedDoc);
+    return;
+}
+
+SPDocument *
+XSLT::open(Inkscape::Extension::Input *module, gchar const *filename)
+{
+    xmlDocPtr filein = xmlParseFile(filename);
+    if (filein == NULL) { return NULL; }
+
+    const char * params[1];
+    params[0] = NULL;
+
+    xmlDocPtr result = xsltApplyStylesheet(_stylesheet, filein, params);
+    xmlFreeDoc(filein);
+    
+    Inkscape::XML::Document * rdoc = sp_repr_do_read( result, SP_SVG_NS_URI);
+    xmlFreeDoc(result);
+
+    if (rdoc == NULL) {
+        return NULL;
+    }
+
+    if (strcmp(rdoc->root()->name(), "svg:svg") != 0) {
+        return NULL;
+    }
+
+    gchar * base = NULL;
+    gchar * name = NULL;
+    gchar * s = NULL, * p = NULL;
+    s = g_strdup(filename);
+    p = strrchr(s, '/');
+    if (p) {
+        name = g_strdup(p + 1);
+        p[1] = '\0';
+        base = g_strdup(s);
+    } else {
+        base = NULL;
+        name = g_strdup(filename);
+    }    
+    g_free(s);
+
+    SPDocument * doc = sp_document_create(rdoc, filename, base, name, true);
+
+    g_free(base); g_free(name);
+
+    return doc;
+}
+
+void
+XSLT::save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename)
+{
+    g_return_if_fail(doc != NULL);
+    g_return_if_fail(filename != NULL);
+
+    Inkscape::XML::Node *repr = NULL;
+    repr = sp_document_repr_root (doc);
+
+    gchar *save_path = g_path_get_dirname (filename);
+    Inkscape::IO::fixupHrefs( doc, save_path, true );
+    g_free(save_path);
+
+    std::string tempfilename_out;
+    int tempfd_out = 0;
+    try {
+        tempfd_out = Glib::file_open_tmp(tempfilename_out, "ink_ext_XXXXXX");
+    } catch (...) {
+        /// \todo Popup dialog here
+        return;
+    }
+
+    gboolean const s = sp_repr_save_file (repr->document(), tempfilename_out.c_str(), SP_SVG_NS_URI);
+    if (s == FALSE) {
+        throw Inkscape::Extension::Output::save_failed();
+    }
+
+    xmlDocPtr svgdoc = xmlParseFile(tempfilename_out.c_str());
+    close(tempfd_out);
+    if (svgdoc == NULL) {
+        return;
+    }
+
+    const char * params[1];
+    params[0] = NULL;
+
+    xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, params);
+    xmlSaveFile(filename, newdoc);
+
+    xmlFreeDoc(newdoc);
+    xmlFreeDoc(svgdoc);
+
+    return;
 }
 
 
index 822f4010e44c462f55e20b2c0791b755cbb91d6a..45befb529045aaf45cb854ef23ed8e8e43567a3f 100644 (file)
@@ -4,7 +4,7 @@
  * Authors:
  *   Ted Gould <ted@gould.cx>
  *
- * Copyright (C) 2006 Authors
+ * Copyright (C) 2006-2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
 #include "implementation.h"
 
+#include "libxml/tree.h"
+#include "libxslt/xslt.h"
+#include "libxslt/xsltInternals.h"
+
 namespace Inkscape {
 namespace XML {
 class Node;
@@ -27,10 +31,22 @@ namespace Implementation {
 
 class XSLT : public Implementation {
 private:
+    std::string _filename;
+    xmlDocPtr _parsedDoc;
+    xsltStylesheetPtr _stylesheet;
 
+    Glib::ustring solve_reldir(Inkscape::XML::Node *reprin);
 public:
     XSLT (void);
 
+    bool load(Inkscape::Extension::Extension *module);
+    void unload(Inkscape::Extension::Extension *module);
+
+    bool check(Inkscape::Extension::Extension *module);
+
+    SPDocument *open(Inkscape::Extension::Input *module,
+                     gchar const *filename);
+    void save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename);
 };
 
 }  /* Inkscape  */
index 8369fb80345180269767f416d78af9948822fca2..62d43dd41aa77f7a5d501bece2a1963dca31a278 100644 (file)
@@ -36,7 +36,7 @@ using Inkscape::XML::SimpleDocument;
 using Inkscape::XML::Node;
 using Inkscape::XML::AttributeRecord;
 
-static Document *sp_repr_do_read (xmlDocPtr doc, const gchar *default_ns);
+Document *sp_repr_do_read (xmlDocPtr doc, const gchar *default_ns);
 static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ns, GHashTable *prefix_map);
 static gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *name, const gchar *default_ns, GHashTable *prefix_map);
 static void sp_repr_write_stream_root_element (Node *repr, Writer &out, bool add_whitespace, gchar const *default_ns, int inlineattrs, int indent);