tools v1.0

(With some additions)
Lots of authors, brought together by Apprentice Alf.
This commit is contained in:
Apprentice Alf
2009-02-13 20:59:59 +00:00
parent 71d66953d3
commit 93c2ccd2c2
26 changed files with 1923 additions and 129 deletions

View File

@@ -1,5 +1,5 @@
#! /usr/bin/python
# For use in Topaz Scripts version 2.0
# For use in Topaz Scripts version 2.2
"""
@@ -13,11 +13,22 @@ y2/pHuYme7U1TsgSjwIDAQAB
-----END PUBLIC KEY-----
"""
from __future__ import with_statement
import csv
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
import sys
sys.stdout=Unbuffered(sys.stdout)
import csv
import os
import getopt
import zlib
@@ -305,7 +316,10 @@ def encodeNumber(number):
byte += flag
result += chr(byte)
flag = 0x80
if number == 0 : break
if number == 0 :
if (byte == 0xFF and negative == False) :
result += chr(0x80)
break
if negative:
result += chr(0xFF)
@@ -841,13 +855,12 @@ def main(argv=sys.argv):
if len(bookKeys) == 0 :
if verbose > 0 :
print ("Book key could not be found. Maybe this book is not registered with this device.")
return 1
else :
bookKey = bookKeys[0]
if verbose > 0:
print("Book key: " + bookKey.encode('hex'))
if command == "printRecord" :
extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
if outputFile != "" and verbose>0 :
@@ -859,6 +872,7 @@ def main(argv=sys.argv):
print ("Decrypted book saved. Don't pirate!")
elif verbose > 0:
print("Output directory name was not supplied.")
return 1
return 0

View File

@@ -1,10 +1,19 @@
#! /usr/bin/python
# For use with Topaz Scripts Version 2.0
#!/usr/bin/python
# For use with Topaz Scripts Version 2.2
from __future__ import with_statement
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
import sys
sys.stdout=Unbuffered(sys.stdout)
import csv
import sys
import os
import getopt
import zlib
@@ -90,7 +99,10 @@ def encodeNumber(number):
byte += flag
result += chr(byte)
flag = 0x80
if number == 0 : break
if number == 0 :
if (byte == 0xFF and negative == False) :
result += chr(0x80)
break
if negative:
result += chr(0xFF)
@@ -480,12 +492,11 @@ def main(argv=sys.argv):
if len(bookKeys) == 0 :
if verbose > 0 :
print ("Book key could not be found. Maybe this book is not registered with this device.")
return 1
else :
bookKey = bookKeys[0]
if verbose > 0:
print("Book key: " + bookKey.encode('hex'))
if command == "printRecord" :
extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
@@ -498,6 +509,7 @@ def main(argv=sys.argv):
print ("Decrypted book saved. Don't pirate!")
elif verbose > 0:
print("Output directory name was not supplied.")
return 1
return 0

View File

@@ -1,10 +1,20 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
from __future__ import with_statement
import csv
import sys
sys.stdout=Unbuffered(sys.stdout)
import csv
import os
import getopt
from struct import pack
@@ -61,7 +71,10 @@ def encodeNumber(number):
byte += flag
result += chr(byte)
flag = 0x80
if number == 0 : break
if number == 0 :
if (byte == 0xFF and negative == False) :
result += chr(0x80)
break
if negative:
result += chr(0xFF)
@@ -729,8 +742,6 @@ def main(argv):
if len(argv) == 0:
printOutput = True
argv = sys.argv
else :
argv = argv.split()
try:
opts, args = getopt.getopt(argv[1:], "hd", ["flat-xml"])

View File

@@ -1,8 +1,7 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
from __future__ import with_statement
import csv
import sys
import os
@@ -61,8 +60,11 @@ def encodeNumber(number):
byte += flag
result += chr(byte)
flag = 0x80
if number == 0 : break
if number == 0 :
if (byte == 0xFF and negative == False) :
result += chr(0x80)
break
if negative:
result += chr(0xFF)

View File

@@ -1,10 +1,9 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
from __future__ import with_statement
import csv
import sys
import csv
import os
import math
import getopt

View File

@@ -1,8 +1,21 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
import os, sys, getopt
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
import sys
sys.stdout=Unbuffered(sys.stdout)
import os, getopt
# local routines
import convert2xml
@@ -27,8 +40,6 @@ def main(argv):
if len(argv) == 0:
argv = sys.argv
else :
argv = argv.split()
try:
opts, args = getopt.getopt(argv[1:], "h:",["fixed-image"])
@@ -36,11 +47,11 @@ def main(argv):
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
sys.exit(1)
if len(opts) == 0 and len(args) == 0 :
usage()
sys.exit(2)
sys.exit(1)
for o, a in opts:
if o =="-h":
@@ -53,39 +64,39 @@ def main(argv):
if not os.path.exists(bookDir) :
print "Can not find directory with unencrypted book"
sys.exit(-1)
sys.exit(1)
dictFile = os.path.join(bookDir,'dict0000.dat')
if not os.path.exists(dictFile) :
print "Can not find dict0000.dat file"
sys.exit(-1)
sys.exit(1)
pageDir = os.path.join(bookDir,'page')
if not os.path.exists(pageDir) :
print "Can not find page directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
imgDir = os.path.join(bookDir,'img')
if not os.path.exists(imgDir) :
print "Can not find image directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
svgDir = os.path.join(bookDir,'svg')
if not os.path.exists(svgDir) :
print "Can not find svg directory in unencrypted book"
print "please run gensvg.py before running genhtml.py"
sys.exit(-1)
sys.exit(1)
otherFile = os.path.join(bookDir,'other0000.dat')
if not os.path.exists(otherFile) :
print "Can not find other0000.dat in unencrypted book"
sys.exit(-1)
sys.exit(1)
metaFile = os.path.join(bookDir,'metadata0000.dat')
if not os.path.exists(metaFile) :
print "Can not find metadata0000.dat in unencrypted book"
sys.exit(-1)
sys.exit(1)
htmlFileName = "book.html"
htmlstr = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
@@ -123,18 +134,28 @@ def main(argv):
pnum = int(spage)
# get page height and width from first text page for use in stylesheet scaling
pname = 'page%04d.dat' % pnum
pname = 'page%04d.dat' % (pnum + 1)
fname = os.path.join(pageDir,pname)
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append('--flat-xml')
pargv.append(dictFile)
pargv.append(fname)
flat_xml = convert2xml.main(pargv)
(ph, pw) = getpagedim.getPageDim(flat_xml)
if (ph == '-1') : ph = 11000
if (pw == '-1') : pw = 8500
if (ph == '-1') or (ph == '0') : ph = '11000'
if (pw == '-1') or (pw == '0') : pw = '8500'
# now build up the style sheet
print ' ', 'other0000.dat'
fname = os.path.join(bookDir,'other0000.dat')
xname = os.path.join(bookDir, 'style.css')
xmlstr = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append('--flat-xml')
pargv.append(dictFile)
pargv.append(fname)
xmlstr = convert2xml.main(pargv)
cssstr , classlst = stylexml2css.convert2CSS(xmlstr, fontsize, ph, pw)
file(xname, 'wb').write(cssstr)
htmlstr += '<link href="style.css" rel="stylesheet" type="text/css" />\n'
@@ -143,7 +164,12 @@ def main(argv):
for filename in filenames:
print ' ', filename
fname = os.path.join(pageDir,filename)
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append('--flat-xml')
pargv.append(dictFile)
pargv.append(fname)
flat_xml = convert2xml.main(pargv)
htmlstr += flatxml2html.convert2HTML(flat_xml, classlst, fname, bookDir, fixedimage)
htmlstr += '</body>\n</html>\n'

View File

@@ -1,8 +1,20 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
import os, sys, getopt
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
import sys
sys.stdout=Unbuffered(sys.stdout)
import os, getopt
# local routines
import convert2xml
@@ -190,8 +202,6 @@ def main(argv):
if len(argv) == 0:
argv = sys.argv
else :
argv = argv.split()
try:
opts, args = getopt.getopt(argv[1:], "xrh")
@@ -199,11 +209,11 @@ def main(argv):
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
sys.exit(1)
if len(opts) == 0 and len(args) == 0 :
usage()
sys.exit(2)
sys.exit(1)
raw = 0
for o, a in opts:
@@ -219,33 +229,33 @@ def main(argv):
if not os.path.exists(bookDir) :
print "Can not find directory with unencrypted book"
sys.exit(-1)
sys.exit(1)
dictFile = os.path.join(bookDir,'dict0000.dat')
if not os.path.exists(dictFile) :
print "Can not find dict0000.dat file"
sys.exit(-1)
sys.exit(1)
pageDir = os.path.join(bookDir,'page')
if not os.path.exists(pageDir) :
print "Can not find page directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
imgDir = os.path.join(bookDir,'img')
if not os.path.exists(imgDir) :
print "Can not find image directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
glyphsDir = os.path.join(bookDir,'glyphs')
if not os.path.exists(glyphsDir) :
print "Can not find glyphs directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
metaFile = os.path.join(bookDir,'metadata0000.dat')
if not os.path.exists(metaFile) :
print "Can not find metadata0000.dat in unencrypted book"
sys.exit(-1)
sys.exit(1)
svgDir = os.path.join(bookDir,'svg')
if not os.path.exists(svgDir) :
@@ -274,7 +284,12 @@ def main(argv):
for filename in filenames:
print ' ', filename
fname = os.path.join(glyphsDir,filename)
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append('--flat-xml')
pargv.append(dictFile)
pargv.append(fname)
flat_xml = convert2xml.main(pargv)
gp = GParser(flat_xml)
for i in xrange(0, gp.count):
path = gp.getPath(i)
@@ -297,7 +312,12 @@ def main(argv):
for filename in filenames:
print ' ', filename
fname = os.path.join(pageDir,filename)
flat_xml = convert2xml.main('convert2xml.py --flat-xml ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append('--flat-xml')
pargv.append(dictFile)
pargv.append(fname)
flat_xml = convert2xml.main(pargv)
pp = PParser(flat_xml)
if (raw) :
pfile = open(os.path.join(svgDir,filename.replace('.dat','.svg')), 'w')

View File

@@ -1,8 +1,21 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
import os, sys, getopt
class Unbuffered:
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
import sys
sys.stdout=Unbuffered(sys.stdout)
import os, getopt
# local routines
import convert2xml
@@ -23,8 +36,6 @@ def main(argv):
if len(argv) == 0:
argv = sys.argv
else :
argv = argv.split()
try:
opts, args = getopt.getopt(argv[1:], "h:")
@@ -32,11 +43,11 @@ def main(argv):
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
sys.exit(1)
if len(opts) == 0 and len(args) == 0 :
usage()
sys.exit(2)
sys.exit(1)
for o, a in opts:
if o =="-h":
@@ -47,32 +58,32 @@ def main(argv):
if not os.path.exists(bookDir) :
print "Can not find directory with unencrypted book"
sys.exit(-1)
sys.exit(1)
dictFile = os.path.join(bookDir,'dict0000.dat')
if not os.path.exists(dictFile) :
print "Can not find dict0000.dat file"
sys.exit(-1)
sys.exit(1)
pageDir = os.path.join(bookDir,'page')
if not os.path.exists(pageDir) :
print "Can not find page directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
glyphsDir = os.path.join(bookDir,'glyphs')
if not os.path.exists(glyphsDir) :
print "Can not find glyphs directory in unencrypted book"
sys.exit(-1)
sys.exit(1)
otherFile = os.path.join(bookDir,'other0000.dat')
if not os.path.exists(otherFile) :
print "Can not find other0000.dat in unencrypted book"
sys.exit(-1)
sys.exit(1)
metaFile = os.path.join(bookDir,'metadata0000.dat')
if not os.path.exists(metaFile) :
print "Can not find metadata0000.dat in unencrypted book"
sys.exit(-1)
sys.exit(1)
xmlDir = os.path.join(bookDir,'xml')
if not os.path.exists(xmlDir):
@@ -90,7 +101,11 @@ def main(argv):
print ' ', 'other0000.dat'
fname = os.path.join(bookDir,'other0000.dat')
xname = os.path.join(xmlDir, 'stylesheet.xml')
xmlstr = convert2xml.main('convert2xml.py ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append(dictFile)
pargv.append(fname)
xmlstr = convert2xml.main(pargv)
file(xname, 'wb').write(xmlstr)
filenames = os.listdir(pageDir)
@@ -100,7 +115,11 @@ def main(argv):
print ' ', filename
fname = os.path.join(pageDir,filename)
xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
xmlstr = convert2xml.main('convert2xml.py ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append(dictFile)
pargv.append(fname)
xmlstr = convert2xml.main(pargv)
file(xname, 'wb').write(xmlstr)
filenames = os.listdir(glyphsDir)
@@ -110,7 +129,11 @@ def main(argv):
print ' ', filename
fname = os.path.join(glyphsDir,filename)
xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
xmlstr = convert2xml.main('convert2xml.py ' + dictFile + ' ' + fname)
pargv=[]
pargv.append('convert2xml.py')
pargv.append(dictFile)
pargv.append(fname)
xmlstr = convert2xml.main(pargv)
file(xname, 'wb').write(xmlstr)

View File

@@ -1,8 +1,7 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
from __future__ import with_statement
import csv
import sys
import os

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
import Tkinter
import Tkconstants
# basic scrolled text widget
class ScrolledText(Tkinter.Text):
def __init__(self, master=None, **kw):
self.frame = Tkinter.Frame(master)
self.vbar = Tkinter.Scrollbar(self.frame)
self.vbar.pack(side=Tkconstants.RIGHT, fill=Tkconstants.Y)
kw.update({'yscrollcommand': self.vbar.set})
Tkinter.Text.__init__(self, self.frame, **kw)
self.pack(side=Tkconstants.LEFT, fill=Tkconstants.BOTH, expand=True)
self.vbar['command'] = self.yview
# Copy geometry methods of self.frame without overriding Text
# methods = hack!
text_meths = vars(Tkinter.Text).keys()
methods = vars(Tkinter.Pack).keys() + vars(Tkinter.Grid).keys() + vars(Tkinter.Place).keys()
methods = set(methods).difference(text_meths)
for m in methods:
if m[0] != '_' and m != 'config' and m != 'configure':
setattr(self, m, getattr(self.frame, m))
def __str__(self):
return str(self.frame)

View File

@@ -1,8 +1,7 @@
#! /usr/bin/python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
# For use with Topaz Scripts Version 2.0
# For use with Topaz Scripts Version 2.2
from __future__ import with_statement
import csv
import sys
import os

View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
import os, sys
import signal
import threading
import subprocess
from subprocess import Popen, PIPE, STDOUT
# **heavily** chopped up and modfied version of asyncproc.py
# to make it actually work on Windows as well as Mac/Linux
# For the original see:
# "http://www.lysator.liu.se/~bellman/download/"
# author is "Thomas Bellman <bellman@lysator.liu.se>"
# available under GPL version 3 or Later
# create an asynchronous subprocess whose output can be collected in
# a non-blocking manner
# What a mess! Have to use threads just to get non-blocking io
# in a cross-platform manner
# luckily all thread use is hidden within this class
class Process(object):
def __init__(self, *params, **kwparams):
if len(params) <= 3:
kwparams.setdefault('stdin', subprocess.PIPE)
if len(params) <= 4:
kwparams.setdefault('stdout', subprocess.PIPE)
if len(params) <= 5:
kwparams.setdefault('stderr', subprocess.PIPE)
self.__pending_input = []
self.__collected_outdata = []
self.__collected_errdata = []
self.__exitstatus = None
self.__lock = threading.Lock()
self.__inputsem = threading.Semaphore(0)
self.__quit = False
self.__process = subprocess.Popen(*params, **kwparams)
if self.__process.stdin:
self.__stdin_thread = threading.Thread(
name="stdin-thread",
target=self.__feeder, args=(self.__pending_input,
self.__process.stdin))
self.__stdin_thread.setDaemon(True)
self.__stdin_thread.start()
if self.__process.stdout:
self.__stdout_thread = threading.Thread(
name="stdout-thread",
target=self.__reader, args=(self.__collected_outdata,
self.__process.stdout))
self.__stdout_thread.setDaemon(True)
self.__stdout_thread.start()
if self.__process.stderr:
self.__stderr_thread = threading.Thread(
name="stderr-thread",
target=self.__reader, args=(self.__collected_errdata,
self.__process.stderr))
self.__stderr_thread.setDaemon(True)
self.__stderr_thread.start()
def pid(self):
return self.__process.pid
def kill(self, signal):
self.__process.send_signal(signal)
# check on subprocess (pass in 'nowait') to act like poll
def wait(self, flag):
if flag.lower() == 'nowait':
rc = self.__process.poll()
else:
rc = self.__process.wait()
if rc != None:
if self.__process.stdin:
self.closeinput()
if self.__process.stdout:
self.__stdout_thread.join()
if self.__process.stderr:
self.__stderr_thread.join()
return self.__process.returncode
def terminate(self):
if self.__process.stdin:
self.closeinput()
self.__process.terminate()
# thread gets data from subprocess stdout
def __reader(self, collector, source):
while True:
data = os.read(source.fileno(), 65536)
self.__lock.acquire()
collector.append(data)
self.__lock.release()
if data == "":
source.close()
break
return
# thread feeds data to subprocess stdin
def __feeder(self, pending, drain):
while True:
self.__inputsem.acquire()
self.__lock.acquire()
if not pending and self.__quit:
drain.close()
self.__lock.release()
break
data = pending.pop(0)
self.__lock.release()
drain.write(data)
# non-blocking read of data from subprocess stdout
def read(self):
self.__lock.acquire()
outdata = "".join(self.__collected_outdata)
del self.__collected_outdata[:]
self.__lock.release()
return outdata
# non-blocking read of data from subprocess stderr
def readerr(self):
self.__lock.acquire()
errdata = "".join(self.__collected_errdata)
del self.__collected_errdata[:]
self.__lock.release()
return errdata
# non-blocking write to stdin of subprocess
def write(self, data):
if self.__process.stdin is None:
raise ValueError("Writing to process with stdin not a pipe")
self.__lock.acquire()
self.__pending_input.append(data)
self.__inputsem.release()
self.__lock.release()
# close stdinput of subprocess
def closeinput(self):
self.__lock.acquire()
self.__quit = True
self.__inputsem.release()
self.__lock.release()

View File

@@ -0,0 +1,75 @@
Changes in 2.2
- fix for minor bug in encode_Number from clark nova
- more fixes to handle paths with spaces in them
- updates to work better with the gui front end
Changes in 2.1
- extremely minor changes to support a gui frontend
- no changes to functionality
Changes in version 2.0
- gensvg.py now accepts two options
-x : output browseable XHTML+SVG pages (default)
-r : output raw SVG images (useful for later conversion to pdf)
- flatxml2html.py now understands page.groups of type graphic
and handles vertical regions as svg images
- genhtml.py now accepts an option
--fixed-image : which will force the conversion
of all fixed regions to svg images
- minor bug fixes and html conversion improvements
Changes in version 1.8
- gensvg.py now builds wonderful xhtml pages with embedded svg
that can be easily paged through as if reading a book!
(tested in Safari for Mac and Win and Firefox)
(requires javascript to be enabled)
- genhtml.py now REQUIRES that gensvg.py be run FIRST
this allows create of images on the fly from glyphs
- genhtml.py now automatically makes tables of words into svg
based images and will handle glyph based ornate first
letters of words
- cmbtc_dump_mac_linux.py has been renamed to be
cmbtc_dump_nonK4PC.py to make it clearer
when it needs to be used
Changes in version 1.7
- gensvg.py has been improved so that the glyphs render exactly (ClarkNova)
- gensvg.py has fixed a render order "bug" that allowed some images to cover or hide text. (ClarkNova)
- change generated html to use external stylesheet via a link to "style.css"
- add missing <title> tag
- make xhtml compliant doctype and minor changes to write correct xhtml
- make divs that act as anchors be hidden visually and to take up 0 height and 0 width to prevent any impact on layout
Changes in version 1.6
- support for books whose paragraphs have no styles
- support to run cmbtc_dump on Linux and Mac OSX provided you know your PID of your ipod or standalone Kindle
(contributed by DiapDealer)
Changes in version 1.5
- completely reworked generation of styles to use actual page heights and widths
- added new script getpagedim.py to support the above
- style names with underscores in them are now properly paired with their base class
- fixed hanging indents that did not ever set a left margin
- added support for a number of not previously known region types
- added support for a previously unknown snippet - <empty></empty>
- corrected a bug that caused unknown regions to abort the program
- added code to make the handling of unknown regions better in general
- corrected a bug that caused the last link on a page to be missing (if it was the last thing on the page)
Changes in version 1.3
- font generation by gensvg.py is now greatly improved with support for contour points added
- support for more region types
- support for inline images in paragraphs or text fields (ie. initial graphics for the first letter of a word)
- greatly improved dtd information used for the xml to prevent parsing mistakes
Version 1.0
- initial release