From 0a06b01de629d811f25150dd5cf77401c1b6823c Mon Sep 17 00:00:00 2001 From: gouldtj Date: Wed, 12 Sep 2007 06:36:45 +0000 Subject: [PATCH] r16525@tres: ted | 2007-09-11 20:49:47 -0700 Adding in code to XSLT. --- src/extension/implementation/xslt.cpp | 193 +++++++++++++++++++++++++- src/extension/implementation/xslt.h | 18 ++- src/xml/repr-io.cpp | 2 +- 3 files changed, 209 insertions(+), 4 deletions(-) diff --git a/src/extension/implementation/xslt.cpp b/src/extension/implementation/xslt.cpp index 3301679cc..cb3260d37 100644 --- a/src/extension/implementation/xslt.cpp +++ b/src/extension/implementation/xslt.cpp @@ -5,7 +5,7 @@ * Authors: * Ted Gould * - * Copyright (C) 2006 Authors + * Copyright (C) 2006-2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -15,7 +15,17 @@ #endif #include "xslt.h" +#include "../extension.h" +#include "../output.h" +#include "xml/repr.h" +#include "io/sys.h" +#include "file.h" + +#include +#include + +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; } diff --git a/src/extension/implementation/xslt.h b/src/extension/implementation/xslt.h index 822f4010e..45befb529 100644 --- a/src/extension/implementation/xslt.h +++ b/src/extension/implementation/xslt.h @@ -4,7 +4,7 @@ * Authors: * Ted Gould * - * Copyright (C) 2006 Authors + * Copyright (C) 2006-2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -14,6 +14,10 @@ #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 */ diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 8369fb803..62d43dd41 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -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); -- 2.30.2