← Back to team overview

zim-wiki team mailing list archive

Re: Zim feature requests.

 

On Wed, 4 Jul 2012 08:27:48 +0200
Jaap Karssenberg <jaap.karssenberg@xxxxxxxxx> wrote:

> On Wed, Jul 4, 2012 at 7:33 AM, Brian Allen Vanderburg II
> <BrianVanderburg2@xxxxxxx> wrote:
> > I've got an idea for a couple features I think would be a little
> > nice:
> >
> > XML export.
> >
> > I have a site that is static but locally stored in XML which is then
> > transformed based on the document type (root element namespace) to
> > an HTML page.  Instead of creating a template which creates the
> > entire HTML page layout (bit of duplication and any changes would
> > require changes both to my tranforms and the export templates), it
> > would be nice if I could just create a template to export to XML
> > for my custom document format.
> 
> Well, you can make a custom HTML template and use you own XML instead
> of HTML. Of course part of the elements are filled in by the export
> code. If you want to modify those, you need to copy and customize
> "zim/formats/html.py".
> 

I checked out zim-next and looked through some of the code.  Since the
data that gets passed to the exporters is already a parse tree, it
seems there could be a couple simpler solutions for XML export:

1.  Plain export of the parse tree as xml (with a root namespace). My
site builder allows chaining the output of one transform into another
based on the root element namespace, so I could then write a transform
that would transform the Zim xml to my document xml which then would be
transformed to the html result.

I am working on implementing a simple exporter for this and have
attached a file with the changes.

2.  XSL transforms on the parse tree.  This would allow creating any
output xml by using an xsl transform on the parse tree.  I don't think
Python's built-in xml modules have xsl support.  lxml does but that
would add another dependency to zim.

Brian Allen Vanderburg II
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: allen@allen-pc-20120704160952-wxejfa4bch8lg3h3
# target_branch: http://bazaar.launchpad.net/~jaap.karssenberg/zim\
#   /pyzim-next/
# testament_sha1: 3a4b44732dc1e7ded81aac63ccde22dc3a182186
# timestamp: 2012-07-04 12:12:55 -0400
# base_revision_id: pardus@xxxxxxxx-20120313150044-59s16uwtoemlo3tj
# 
# Begin patch
=== added directory 'data/templates/zimxml'
=== added file 'data/templates/zimxml/Default.xml'
--- data/templates/zimxml/Default.xml	1970-01-01 00:00:00 +0000
+++ data/templates/zimxml/Default.xml	2012-07-04 16:09:52 +0000
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding"utf-8"?>
+<zim-page xmlns="http://www.zim-wiki.org/page"; version="1.0">
+<zim-data>
+    <title>[% title %]</title>
+</zim-data>
+[% page.body %]
+</zim-page>

=== modified file 'zim.py'
--- zim.py	2011-06-30 20:49:24 +0000
+++ zim.py	2012-07-04 16:09:09 +0000
@@ -4,6 +4,8 @@
 import logging
 import os
 
+print sys.path
+
 # Check if we run the correct python version
 try:
 	version_info = sys.version_info

=== modified file 'zim/formats/__init__.py'
--- zim/formats/__init__.py	2012-03-13 15:00:44 +0000
+++ zim/formats/__init__.py	2012-07-04 16:09:09 +0000
@@ -155,7 +155,7 @@
 
 def list_formats(type):
 	if type == EXPORT_FORMAT:
-		return ['HTML','LaTeX', 'Markdown (pandoc)']
+		return ['HTML','LaTeX', 'Markdown (pandoc)', 'ZimXML (parse tree)']
 	elif type == TEXT_FORMAT:
 		return ['Text', 'Wiki', 'Markdown (pandoc)']
 	else:

=== modified file 'zim/formats/wiki.py'
--- zim/formats/wiki.py	2012-03-13 15:00:44 +0000
+++ zim/formats/wiki.py	2012-07-04 16:09:09 +0000
@@ -169,7 +169,7 @@
 	def parse_pre(builder, indent, text):
 		'''Verbatim block with indenting'''
 		if indent:
-			text = re.sub('^'+indent, '', text, flags=re.M) # remove indent
+			text = re.sub('(?m)^'+indent, '', text) # remove indent
 			attrib = {'indent': len(indent)}
 		else:
 			attrib = None
@@ -192,7 +192,7 @@
 		# accidentally
 		attrib['type'] = type
 		if indent:
-			body = re.sub('^'+indent, '', body, flags=re.M) # remove indent
+			body = re.sub('(?m)^'+indent, '', body) # remove indent
 			attrib['indent'] = len(indent)
 
 		builder.span(OBJECT, attrib, body)
@@ -222,7 +222,7 @@
 		per list item
 		'''
 		if indent:
-			text = re.sub('^'+indent, '', text, flags=re.M) # remove indent
+			text = re.sub('(?m)^'+indent, '', text) # remove indent
 			attrib = {'indent': len(indent)}
 		else:
 			attrib = None
@@ -275,7 +275,7 @@
 
 	def parse_indent(self, builder, text, indent):
 		'''Parse indented blocks and turn them into 'div' elements'''
-		text = re.sub('^'+indent, '', text, flags=re.M) # remove indent
+		text = re.sub('(?m)^'+indent, '', text) # remove indent
 		builder.start(BLOCK, {'indent': len(indent)})
 		self.inline_parser(builder, text)
 		builder.end(BLOCK)

=== added file 'zim/formats/zimxml.py'
--- zim/formats/zimxml.py	1970-01-01 00:00:00 +0000
+++ zim/formats/zimxml.py	2012-07-04 16:09:52 +0000
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2008 Jaap Karssenberg <jaap.karssenberg@xxxxxxxxx>
+
+'''This module supports dumping to ZimXMLL'''
+
+import re
+import string
+
+from zim.formats import *
+from zim.parsing import TextBuffer, link_type
+
+info = {
+	'name': 'zimxml',
+	'desc': 'ZimXML (parse tree)',
+	'mimetype': 'text/xml',
+	'extension': 'xml',
+	'native': False,
+	'import': False,
+	'export': True,
+}
+
+class Dumper(DumperClass):
+
+	def dump(self, tree):
+		assert isinstance(tree, ParseTree)
+		from cStringIO import StringIO
+		output = TextBuffer()
+
+		# Copied from zim/formats/__init__.py
+
+		# Parent dies when we have attributes that are not a string
+		for element in tree.getiterator('*'):
+			for key in element.attrib.keys():
+				element.attrib[key] = str(element.attrib[key])
+
+		xml = StringIO()
+		ElementTreeModule.ElementTree.write(tree, xml, 'utf-8')
+		output.append(xml.getvalue())
+		return output.get_lines(end_with_newline=not tree.ispartial)
+

=== modified file 'zim/gui/exportdialog.py'
--- zim/gui/exportdialog.py	2012-02-22 12:57:37 +0000
+++ zim/gui/exportdialog.py	2012-07-04 16:09:09 +0000
@@ -103,7 +103,6 @@
 			parser = get_format('wiki').Parser()
 			parsetree = parser.parse(text)
 			page = Page(Path(page.name), parsetree=parsetree)
-
 			exporter.export_page(file.dir, page, filename=file.basename)
 
 		return True
@@ -285,7 +284,7 @@
 
 		if show_file:
 			basename = self.uistate['selected_page'].basename
-			ext = zim.formats.get_format(self.uistate['format']).info['extension']
+			ext = zim.formats.get_format(zim.formats.canonical_name(self.uistate['format'])).info['extension']
 
 			if self.uistate['output_file'] \
 			and isinstance(self.uistate['output_file'], File):

=== modified file 'zim/parser.py'
--- zim/parser.py	2012-03-13 15:00:44 +0000
+++ zim/parser.py	2012-07-04 16:09:09 +0000
@@ -60,12 +60,11 @@
 
 	# Fix tabs
 	spaces = ' ' * tabstop
-	pattern = '^(\t*)((?:%s)+)' % spaces
+	pattern = '(?m)^(\t*)((?:%s)+)' % spaces
 	text = re.sub(
 		pattern,
 		lambda m: m.group(1) + '\t' * (len(m.group(2)) / tabstop),
-		text,
-		flags=re.M
+		text
 	)
 
 	return text

# Begin bundle
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

Attachment: signature.asc
Description: PGP signature


Follow ups

References