%PDF- %PDF-
| Direktori : /lib/calibre/calibre/ebooks/rtf2xml/ |
| Current File : //lib/calibre/calibre/ebooks/rtf2xml/colors.py |
#########################################################################
# #
# #
# copyright 2002 Paul Henry Tremblay #
# #
# 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. #
# #
# #
#########################################################################
import sys, os, re
from calibre.ebooks.rtf2xml import copy
from calibre.ptempfile import better_mktemp
from . import open_for_read, open_for_write
class Colors:
"""
Change lines with color info from color numbers to the actual color names.
"""
def __init__(self,
in_file,
bug_handler,
copy=None,
run_level=1
):
"""
Required:
'file'--file to parse
Optional:
'copy'-- whether to make a copy of result for debugging
'temp_dir' --where to output temporary results (default is
directory from which the script is run.)
Returns:
nothing
"""
self.__file = in_file
self.__copy = copy
self.__bug_handler = bug_handler
self.__line = 0
self.__write_to = better_mktemp()
self.__run_level = run_level
def __initiate_values(self):
"""
Initiate all values.
"""
self.__color_dict = {}
self.__state = 'before_color_table'
self.__state_dict = {
'before_color_table': self.__before_color_func,
'in_color_table' : self.__in_color_func,
'after_color_table' : self.__after_color_func,
'cw<ci<red_______' : self.__default_color_func,
'cw<ci<green_____' : self.__default_color_func,
'cw<ci<blue______' : self.__blue_func,
'tx<nu<__________' : self.__do_nothing_func,
}
self.__color_string = '#'
self.__color_num = 1
self.__line_color_exp = re.compile(r'bdr-color_:(\d+)')
# cw<bd<bor-par-to<nu<bdr-hair__|bdr-li-wid:0.50|bdr-sp-wid:1.00|bdr-color_:2
def __before_color_func(self, line):
"""
Requires:
line
Returns:
nothing
Logic:
Check to see if the line marks the beginning of the color table.
If so, change states.
Always print out the line.
"""
# mi<mk<clrtbl-beg
if self.__token_info == 'mi<mk<clrtbl-beg':
self.__state = 'in_color_table'
self.__write_obj.write(line)
def __default_color_func(self, line):
"""
Requires:
line
Returns:
nothing
Logic:
get the hex number from the line and add it to the color string.
"""
hex_num = line[-3:-1]
self.__color_string += hex_num
def __blue_func(self, line):
"""
Requires:
line
Returns:
nothing
Logic:
Get the hex number from the line and add it to the color string.
Add a key -> value pair to the color dictionary, with the number
as the key, and the hex number as the value. Write an empty tag
with the hex number and number as attributes. Add one to the color
number. Reset the color string to '#'
"""
hex_num = line[-3:-1]
self.__color_string += hex_num
self.__color_dict[self.__color_num] = self.__color_string
self.__write_obj.write(
'mi<tg<empty-att_'
'<color-in-table<num>%s<value>%s\n' % (self.__color_num, self.__color_string)
)
self.__color_num += 1
self.__color_string = '#'
def __in_color_func(self, line):
"""
Requires:
line
Returns:
nothing
Logic:
Check if the end of the color table has been reached. If so,
change the state to after the color table.
Otherwise, get a function by passing the self.__token_info to the
state dictionary.
"""
# mi<mk<clrtbl-beg
# cw<ci<red_______<nu<00
if self.__token_info == 'mi<mk<clrtbl-end':
self.__state = 'after_color_table'
else:
action = self.__state_dict.get(self.__token_info)
if action is None:
sys.stderr.write('in module colors.py\n'
'function is self.__in_color_func\n'
'no action for %s' % self.__token_info
)
action(line)
def __after_color_func(self, line):
"""
Check the to see if it contains color info. If it does, extract the
number and look up the hex value in the color dictionary. If the color
dictionary has no key for the number, print out an error message.
Otherwise, print out the line.
Added Oct 10, 2003
If the number is 0, that indicates no color
"""
# cw<ci<font-color<nu<2
if self.__token_info == 'cw<ci<font-color':
hex_num = int(line[20:-1])
hex_num = self.__figure_num(hex_num)
if hex_num:
self.__write_obj.write(
'cw<ci<font-color<nu<%s\n' % hex_num
)
elif line[0:5] == 'cw<bd':
the_index = line.find('bdr-color_')
if the_index > -1:
line = re.sub(self.__line_color_exp, self.__sub_from_line_color, line)
self.__write_obj.write(line)
"""
if num == 0:
hex_num = 'false'
else:
hex_num = self.__color_dict.get(num)
if hex_num == None:
if self.__run_level > 0:
sys.stderr.write(
'module is colors.py\n'
'function is self.__after_color_func\n'
'no value in self.__color_dict for key %s\n' % num
)
if self.__run_level > 3:
sys.stderr.write(
'run level is %s\n'
'Script will now quit\n'
% self.__run_level)
else:
self.__write_obj.write(
'cw<ci<font-color<nu<%s\n' % hex_num
)
"""
else:
self.__write_obj.write(line)
# cw<bd<bor-par-to<nu<bdr-hair__|bdr-li-wid:0.50|bdr-sp-wid:1.00|bdr-color_:2
def __sub_from_line_color(self, match_obj):
num = match_obj.group(1)
try:
num = int(num)
except ValueError:
if self.__run_level > 3:
msg = 'can\'t make integer from string\n'
raise self.__bug_handler(msg)
else:
return 'bdr-color_:no-value'
hex_num = self.__figure_num(num)
return 'bdr-color_:%s' % hex_num
def __figure_num(self, num):
if num == 0:
hex_num = 'false'
else:
hex_num = self.__color_dict.get(num)
if hex_num is None:
hex_num = '0'
if self.__run_level > 3:
msg = 'no value in self.__color_dict' \
'for key %s at line %d\n' % (num, self.__line)
raise self.__bug_handler(msg)
return hex_num
def __do_nothing_func(self, line):
"""
Bad RTF will have text in the color table
"""
pass
def convert_colors(self):
"""
Requires:
nothing
Returns:
nothing (changes the original file)
Logic:
Read one line in at a time. Determine what action to take based on
the state. If the state is before the color table, look for the
beginning of the color table.
If the state is in the color table, create the color dictionary
and print out the tags.
If the state if after the color table, look for lines with color
info, and substitute the number with the hex number.
"""
self.__initiate_values()
with open_for_read(self.__file) as read_obj:
with open_for_write(self.__write_to) as self.__write_obj:
for line in read_obj:
self.__line+=1
self.__token_info = line[:16]
action = self.__state_dict.get(self.__state)
if action is None:
try:
sys.stderr.write('no matching state in module fonts.py\n')
sys.stderr.write(self.__state + '\n')
except:
pass
action(line)
copy_obj = copy.Copy(bug_handler=self.__bug_handler)
if self.__copy:
copy_obj.copy_file(self.__write_to, "color.data")
copy_obj.rename(self.__write_to, self.__file)
os.remove(self.__write_to)