Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/adapters.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/adapters.py	(revision 532)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/adapters.py	(revision 532)
@@ -0,0 +1,104 @@
+import re
+from xml.dom import minidom
+from types import ListType
+from types import TupleType
+
+from zope.interface import implements
+from Products.CMFPlone.Portal import PloneSite
+
+from quintagroup.transmogrifier.interfaces import IExportDataCorrector
+from quintagroup.transmogrifier.adapters.exporting import ReferenceExporter
+
+from quintagroup.transmogrifier.simpleblog2quills.interfaces import IExportItemManipulator, IBlog
+
+IMAGE_FOLDER = 'images'
+
+class BlogExporter(object):
+    implements(IExportDataCorrector)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, data):
+        return data
+
+def recurseToInterface(item, ifaces):
+    """Recurse up the aq_chain until an object providing `iface' is found,
+    and return that.
+    """
+    if not isinstance(ifaces, (ListType, TupleType)):
+        ifaces = [ifaces]
+    parent = item.aq_parent
+    for iface in ifaces:
+        if iface.providedBy(item):
+            return item
+    for iface in ifaces:
+        if iface.providedBy(parent):
+            return parent
+    if isinstance(parent, PloneSite):
+        # Stop when we get to the portal root.
+        return None
+    return recurseToInterface(parent, ifaces)
+
+class BlogEntryExporter(ReferenceExporter):
+    implements(IExportDataCorrector)
+
+    HREF = re.compile(r'href="([^"]+)"')
+    SRC = re.compile(r'src="([^"]+)"')
+
+    def __call__(self, data):
+        data = super(BlogEntryExporter, self)(data)
+        doc = minidom.parseString(data['data'])
+        try:
+            elem = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == 'body'][0]
+        except IndexError:
+            return data
+
+        text = elem.firstChild.nodeValue
+        # urls = self.HREF.findall(text)
+        urls = self.SRC.findall(text)
+        blog = recurseToInterface(self.context, IBlog)
+        blog_url = blog.absolute_url()
+        blog_path = blog.getPhysicalPath()
+        for url in urls:
+            image_id = url.rsplit('/', 1)[-1]
+            if url.startswith('http://'):
+                new_url = '/'.join((blog_url, IMAGE_FOLDER, image_id))
+            else:
+                path = self.context.getPhysicalPath()
+                # /plone/blog 2
+                # /plone/blog/bloggins/entry 4
+                # ../../images
+                level = len(path) - len(blog_path)
+                new_url = '/'.join(['..' for i in range(level)])
+                new_url = '/'.join([new_url, IMAGE_FOLDER, image_id])
+
+            text = text.replace(url, new_url, 1)
+
+        elem.firstChild.nodeValue = text
+        data['data'] = doc.toxml('utf-8')
+        return data
+
+class PathRewriter(object):
+    implements(IExportItemManipulator)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, item, **kw):
+        pathkey = kw.get('path')
+        if pathkey is None:
+            return item
+
+        path = item[pathkey]
+        blog = recurseToInterface(self.context, IBlog)
+        if blog is None:
+            return item
+
+        new_path = list(blog.getPhysicalPath())[2:]
+        new_path.append(IMAGE_FOLDER)
+        new_path.append(self.context.getId())
+        new_path = '/'.join(new_path)
+        item[pathkey] = new_path
+
+        return item
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/configure.zcml
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/configure.zcml	(revision 528)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/configure.zcml	(revision 532)
@@ -1,4 +1,6 @@
 <configure
     xmlns="http://namespaces.zope.org/zope"
+    xmlns:five="http://namespaces.zope.org/five"
+    xmlns:zcml="http://namespaces.zope.org/zcml"
     xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier"
     i18n_domain="quintagroup.transmogrifier.simpleblog2quills">
@@ -7,4 +9,74 @@
     <include package="quintagroup.transmogrifier" file="meta.zcml" />
 
+    <utility
+        component=".itemmanipulator.ItemManipulatorSection"
+        name="quintagroup.transmogrifier.itemmanipulator"
+        provides="collective.transmogrifier.interfaces.ISectionBlueprint"
+        />
+
+    <configure zcml:condition="installed Products.SimpleBlog">
+
+        <!-- In Plone 2.1 overrides.zcml isn't loaded, but conflicting configuration
+             actions wouldn't raise error on startup - the latest directive will
+             override previous -->
+        <transmogrifier:registerConfig
+            name="export"
+            title="Export pipeline configuration"
+            description="Customized for SimpleBlog/Quills content types content export pipeline."
+            configuration="export.cfg"
+            />
+
+        <!-- mark blog and blog entry objects so we can register export adapters for them -->
+        <five:implements
+            class="Products.SimpleBlog.content.Blog"
+            interface=".interfaces.IBlog"
+            />
+
+        <five:implements
+            class="Products.SimpleBlog.content.BlogEntry"
+            interface=".interfaces.IBlogEntry"
+            />
+
+        <five:implements
+            class="Products.ATContentTypes.content.file.ATFile"
+            interface="quintagroup.transmogrifier.interfaces.IATFile"
+            />
+
+        <five:implements
+            class="Products.ATContentTypes.content.image.ATImage"
+            interface="quintagroup.transmogrifier.interfaces.IATImage"
+            />
+
+        <!-- 'datacorrector' section adapters -->
+        <adapter
+            for=".interfaces.IBlog"
+            provides="quintagroup.transmogrifier.interfaces.IExportDataCorrector"
+            factory=".adapters.BlogExporter"
+            name="manifest"
+            />
+
+        <adapter
+            for=".interfaces.IBlogEntry"
+            provides="quintagroup.transmogrifier.interfaces.IImportDataCorrector"
+            factory=".adapters.BlogEntryExporter"
+            name="marshall"
+            />
+
+        <!-- 'itemmanipulator' section adapter -->
+        <adapter
+            for="quintagroup.transmogrifier.interfaces.IATFile"
+            provides=".interfaces.IExportItemManipulator"
+            factory=".adapters.PathRewriter"
+            />
+
+        <adapter
+            for="quintagroup.transmogrifier.interfaces.IATImage"
+            provides=".interfaces.IExportItemManipulator"
+            factory=".adapters.PathRewriter"
+            />
+
+    </configure>
+
+    <!-- next is for importing -->
     <transmogrifier:stylesheet
         source="marshall"
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/export.cfg
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/export.cfg	(revision 532)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/export.cfg	(revision 532)
@@ -0,0 +1,50 @@
+[transmogrifier]
+pipeline =
+    sitewalker
+    manifestexporter
+    fileexporter
+    marshaller
+    propertiesexporter
+    commentsexporter
+    datacorrector
+    itemmanipulator
+    writer
+    EXPORTING
+
+[sitewalker]
+blueprint = quintagroup.transmogrifier.sitewalker
+
+[manifestexporter]
+blueprint = quintagroup.transmogrifier.manifestexporter
+
+[fileexporter]
+blueprint = quintagroup.transmogrifier.fileexporter
+
+[marshaller]
+blueprint = quintagroup.transmogrifier.marshaller
+
+[propertiesexporter]
+blueprint = quintagroup.transmogrifier.propertiesexporter
+exclude = title
+
+[commentsexporter]
+blueprint = quintagroup.transmogrifier.commentsexporter
+
+[datacorrector]
+blueprint = quintagroup.transmogrifier.datacorrector
+sources =
+    marshall
+
+[itemmanipulator]
+blueprint = quintagroup.transmogrifier.itemmanipulator
+type = export
+
+[writer]
+blueprint = quintagroup.transmogrifier.writer
+prefix = structure
+
+[EXPORTING]
+blueprint = quintagroup.transmogrifier.logger
+keys = 
+    _type
+    _path
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/interfaces.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/interfaces.py	(revision 532)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/interfaces.py	(revision 532)
@@ -0,0 +1,28 @@
+from zope.interface import Interface
+
+class IBlog(Interface):
+    """ Marker interface for SimpleBlog blog object.
+    """
+
+class IBlogEntry(Interface):
+    """ Marker interface for SimpleBlog blog entry object.
+    """
+
+class IItemManipulator(Interface):
+    """ Interface for adapters that are looked up in 'itemmanipulator' 
+        pipeline section.
+    """
+
+    def __call__(item, **kw):
+        """ Do something with a pipeline item and return it.
+            kw - dictionary with extra arguments, for example some useful keys
+                in item (pathkey, ...)
+        """
+
+class IExportItemManipulator(IItemManipulator):
+    """ Exporting adapter.
+    """
+
+class IImportItemManipulator(IItemManipulator):
+    """ Importing adapter
+    """
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/itemmanipulator.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/itemmanipulator.py	(revision 532)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/itemmanipulator.py	(revision 532)
@@ -0,0 +1,47 @@
+from zope.interface import classProvides, implements
+from zope.component import queryAdapter
+
+from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
+from collective.transmogrifier.utils import defaultMatcher
+
+from quintagroup.transmogrifier.simpleblog2quills.interfaces import \
+    IItemManipulator, IExportItemManipulator, IImportItemManipulator
+
+class ItemManipulatorSection(object):
+    classProvides(ISectionBlueprint)
+    implements(ISection)
+
+    def __init__(self, transmogrifier, name, options, previous):
+        self.previous = previous
+        self.context = transmogrifier.context
+
+        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+
+        # 'type' options specifies adapter interface
+        type_ = options.get('type', 'general')
+        if type_ == 'general':
+            self.interface = IItemManipulator
+        elif type_ == 'export':
+            self.interface = IExportItemManipulator
+        elif type_ == 'import':
+            self.interface = IImportItemManipulator
+        else:
+            self.interface = None
+
+    def __iter__(self):
+        for item in self.previous:
+            pathkey = self.pathkey(*item.keys())[0]
+
+            if not (pathkey and self.interface is not None):
+                yield item; continue
+
+            path = item[pathkey]
+            obj = self.context.unrestrictedTraverse(path, None)
+            if obj is None:         # path doesn't exist
+                yield item; continue
+
+            adapter = queryAdapter(obj, self.interface, name='')
+            if adapter:
+                item = adapter(item, path=pathkey)
+
+            yield item
