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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
|
"""
DocWriter.py - DocWriter class and friends
$Id: DocWriter.py,v 1.2 1998/09/04 08:36:46 rob Exp $
Copyright 1998 Rob Tillotson <rob@io.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2,
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
This module implements a Writer class which outputs to an e-text.
It is suitable for use with the regular AbstractFormatter object.
This writer has a couple of extra methods, for opening a document,
setting bookmarks, etc.
"""
__version__ = '$Id: DocWriter.py,v 1.2 1998/09/04 08:36:46 rob Exp $'
import sys, string, os
import formatter
import metrics
from PDA.Palm.App import Doc
DOCTYPES = ['aportis', 'teal']
DEFAULT_DOCTYPE = 'aportis'
teal_header_attrs = {
1: {'FONT': '2', 'ALIGN': 'CENTER', 'STYLE': 'NORMAL'},
2: {'FONT': '1', 'ALIGN': 'LEFT', 'STYLE': 'UNDERLINE'},
3: {'FONT': '1', 'ALIGN': 'LEFT', 'STYLE': 'NORMAL'},
4: {'FONT': '0', 'ALIGN': 'LEFT', 'STYLE': 'UNDERLINE'},
5: {'FONT': '0', 'ALIGN': 'LEFT', 'STYLE': 'UNDERLINE'},
6: {'FONT': '0', 'ALIGN': 'LEFT', 'STYLE': 'UNDERLINE'}
}
teal_header_fonts = {
1: 2,
2: 1,
3: 1
}
teal_default_header_attrs = {'FONT': '0', 'ALIGN': 'LEFT', 'STYLE': 'NORMAL'}
def tag(name, attr):
s = '<'+name
if attr:
s = s + ' ' + string.join(map(lambda x: '%s=%s' % x, attr.items()))
s = s + '>'
return s
class DevNull:
def write(self, *a, **kw): pass
def read(self, *a, **kw): return ''
def readline(self, *a, **kw): return ''
def readlines(self, *a, **kw): return []
def close(self, *a, **kw): pass
class DocWriter(formatter.NullWriter):
"""A Writer which outputs to a Doc-format e-text, via PalmPython.
"""
def __init__(self, target=None, title=None, options=None):
formatter.NullWriter.__init__(self)
self.options = {}
if options: self.options.update(options)
if target:
self.open(target, title)
elif title:
self.open_stdout()
else:
self.doc = DevNull()
self.reset()
def has_option(self, k): return self.options.has_key(k)
def set_option(self, k, v=1): self.options[k] = v
def get_option(self, k, d=None): return self.options.get(k,d)
def clear_option(self, k):
if self.options.has_key(k):
del self.options[k]
def open_stdout(self, target=None, title=None):
"""Open the writer, sending output to stdout. Use only for
debugging, and note that some information (notably bookmarks)
will not be passed along to the output, as it is effectively
'out of band'.
"""
self.doc = sys.stdout
def open(self, target, title, dlp=None):
"""Open the document. The first argument is the local filename,
the second is the PalmOS database name. If a third argument is
provided, it must be an open DLP object to which the document is
directly installed.
"""
kw = {}
if self.options.has_key('creator'):
kw['creator'] = self.options['creator']
if self.options.has_key('type'):
kw['type'] = self.options['type']
if self.options.has_key('backup'):
kw['backup'] = self.options['backup']
if self.options.has_key('category'):
kw['category'] = self.options['category']
self.doc = apply(Doc.DOCWriter, (title, target), kw)
def close(self):
"""Close the document.
"""
self.flush()
self.doc.close()
self.doc = DevNull()
def set_bookmark(self, s):
"""Set a bookmark at the current output position; the single
argument is the bookmark title. (Per the Doc format, only
the first 15 characters will be preserved; also, note that
bookmarks appear in the menu in the order they are set.)
"""
if self.has_option('teal-bookmarks'):
self.send_raw_tag('BOOKMARK',{'NAME':'"%s"' % s[:15]})
else:
self.flush()
self.doc.bookmark(s)
def send_raw_tag(self, tagname, attr):
"""Insert a raw SGML-like tag in the output, given the tag
name and attributes. Use this for inserting TealDoc-style
images, rules, etc.
"""
self.flush()
self.doc.write(tag(tagname, attr))
def send_heading(self, text, level=1):
"""Insert a heading of the specified level."""
if self.has_option('teal-headers'):
if self.has_option('teal-wrap-headers'):
l = metrics.wordwrap(text, max_width=160,
font=teal_header_fonts.get(level,0))
else:
l = [text]
for t in l:
d = {'TEXT': '"%s"' % t}
d.update(teal_header_attrs.get(level, teal_default_header_attrs))
self.send_raw_tag('HEADER', d)
self.send_line_break()
else:
self.send_literal_data(text)
self.send_line_break()
def set_title(self, title):
"""Set the document title."""
self.doc.title = title
def has_title(self):
if self.doc.title: return 1
# --- writer API
def reset(self):
self.list_depth = 0
def send_paragraph(self, blankline=0):
"""Insert a paragraph break; the parameter (if present) is
the number of blank lines to insert between this and the
next paragraph.
"""
self.doc.write('\n'*blankline)
# reset paragraph counters
def send_line_break(self):
"""Insert a line break."""
self.doc.write('\n')
# reset line counters
def send_hor_rule(self, *a, **kw):
"""Generate a horizontal rule. If the output document is
in Teal format, this method inserts a <HRULE> tag, and the
keyword parameters are the attributes of that tag. If the
output is in standard Doc format, an artificial rule will
be created by lining up a bunch of punctuation characters;
the character type is specified by the 'char' attribute
('*' is the default), and the count is estimated according
to the width of the Pilot screen.
"""
if self.has_option('teal-hrules'):
if kw.has_key('char'): del kw['char']
if kw.has_key('break'): del kw['break']
# later, do various default things based on 'char'
self.doc.write(tag('HRULE', kw)+'\n')
else:
char = kw.get('char', '*')[:1]
if char == '-': count = 39
else: count = 26
brk = kw.get('break', 'none')
if brk in ['before', 'both']: self.doc.write('\n')
self.doc.write(char * count)
if brk in ['after', 'both']: self.doc.write('\n')
def send_literal_data(self, data):
"""Send literal data to the document."""
self.doc.write(data)
def send_flowing_data(self, data):
"""Send flowing data to the document."""
self.doc.write(data)
def send_label_data(self, data):
self.doc.write(' '*self.list_depth)
self.doc.write(data)
if data and data[-1] not in ' \n\r\t':
self.doc.write(' ')
#----
def new_alignment(self, align):
"""Does nothing, as the Doc format doesn't support it yet."""
pass
def new_font(self, font):
"""Does nothing, as the Doc format doesn't support it yet."""
pass
def new_margin(self, margin, level):
if margin is None or level == 0:
self.list_depth = 0
elif margin in ['ol', 'ul']:
self.list_depth = level - 1
def new_spacing(self, spacing):
"""Does nothing, as the Doc format doesn't support it yet."""
pass
def new_styles(self, styles):
"""Does nothing, as the Doc format doesn't support it yet."""
pass
|