forked from pfalcon/zim-desktop-wiki-markdown
-
Notifications
You must be signed in to change notification settings - Fork 0
/
exporter.py
147 lines (124 loc) · 4.52 KB
/
exporter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*- coding: utf-8 -*-
# Copyright 2009 Jaap Karssenberg <pardus@cpan.org>
'''This module contains the export functions for zim'''
import logging
from zim.fs import *
from zim.formats import get_format, BaseLinker
from zim.templates import get_template
from zim.notebook import Page, IndexPage, PageNameError
from zim.stores import encode_filename
logger = logging.getLogger('zim.exporter')
class Exporter(object):
'''Class that handles an export action'''
def __init__(self, notebook, format, template=None,
index_page=None, document_root_url=None):
'''Constructor. The 'notebook' is the source for pages to be exported.
(The export target is given as an argument to export_all() or export().)
The 'format' and 'template' arguments determine the output format.
If 'index_page' is given a page index is generated and
'document_root_url' is used to prefix any file links that start with '/'.
'''
self.notebook = notebook
self.index_page = index_page
self.document_root_url = document_root_url
self.linker = StaticLinker(format, notebook,
document_root_url=document_root_url)
if isinstance(format, basestring):
self.format = get_format(format)
else:
self.format = format
if template and isinstance(template, basestring):
self.template = get_template(format, template)
else:
self.template = template
if self.template:
self.template.set_linker(self.linker)
def export_all(self, dir, callback=None):
'''Export all pages in the notebook to 'dir'. Attachments are copied
along. The function 'callback' will be called after each page with the
page object as single argument. If the callback returns False the
export will be cancelled.
'''
logger.info('Exporting notebook to %s', dir)
for page in self.notebook.walk():
if page.hascontent:
self.export_page(dir, page)
if callback and not callback(page):
logger.warn('Export cancelled')
return False
if self.index_page:
page = IndexPage(self.notebook)
page.name = self.index_page # HACK
self.export_page(dir, page)
logger.info('Export done')
return True
def export_page(self, dir, page):
'''Export 'page' to a file below 'dir'. Path below 'dir' will be
determined by the namespace of 'page'. Attachments wil also be
copied along.
'''
logger.info('Exporting %s', page.name)
dirname = encode_filename(page.name)
filename = dirname + '.' + self.format.info['extension']
file = dir.file(filename)
fh = file.open('w')
self.export_page_to_fh(fh, page)
fh.close()
subdir = dir.subdir(dirname)
attachments = self.notebook.get_attachments_dir(page)
for name in attachments.list():
file = attachments.file(name)
if file.exists(): # tests os.isfile
file.copyto(subdir)
def export_page_to_fh(self, fh, page):
'''Export 'page' and print the output to open file handle 'hf'.
(Does not do anything with attachments.)
'''
if self.template is None:
self.linker.set_path(page)
lines = page.dump(self.format, linker=self.linker)
else:
lines = self.template.process(self.notebook, page)
fh.writelines(l.encode('utf-8') for l in lines)
class StaticLinker(BaseLinker):
'''Linker object for exporting a single page. It links files, images
and icons with absolute file paths, but can not link other pages corectly.
'''
def __init__(self, format, notebook, path=None, document_root_url=None):
BaseLinker.__init__(self)
if isinstance(format, basestring):
format = get_format(format)
self.notebook = notebook
self.path = path
self.document_root_url = document_root_url
self._extension = '.' + format.info['extension']
def page(self, link):
try:
page = self.notebook.resolve_path(link, source=self.path)
except PageNameError:
return ''
else:
if page == self.path:
return ''
parent = page.commonparent(self.path)
if parent == self.path:
path = './' + self.path.basename + '/'
downpath = page.relname(parent)
path += encode_filename(downpath) + self._extension
elif parent == page:
uppath = self.path.relname(parent)
path = '../' * (uppath.count(':') + 1)
path += encode_filename(page.basename) + self._extension
else:
uppath = self.path.relname(parent)
downpath = page.relname(parent)
path = '../' * uppath.count(':') or './'
path += encode_filename(downpath) + self._extension
#~ print '>>>', path
return path
def file(self, link):
if self.document_root_url and link.startswith('/'):
return ''.join((self.document_root_url.rstrip('/'), link))
else:
file = self.notebook.resolve_file(link, self.path)
return file.uri