mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
FB2 Output: Produce output that is closer to the FB2 Spec
This commit is contained in:
commit
b66c7ec2d5
@ -32,7 +32,6 @@ TAG_MAP = {
|
|||||||
'p' : 'p',
|
'p' : 'p',
|
||||||
'li' : 'p',
|
'li' : 'p',
|
||||||
'div': 'p',
|
'div': 'p',
|
||||||
'br' : 'p',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TAG_SPACE = []
|
TAG_SPACE = []
|
||||||
@ -42,7 +41,6 @@ TAG_IMAGES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
TAG_LINKS = [
|
TAG_LINKS = [
|
||||||
'a',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
BLOCK = [
|
BLOCK = [
|
||||||
@ -56,9 +54,8 @@ STYLES = [
|
|||||||
|
|
||||||
class FB2MLizer(object):
|
class FB2MLizer(object):
|
||||||
'''
|
'''
|
||||||
Todo: * Ensure all style tags are inside of the p tags.
|
Todo: * Include more FB2 specific tags in the conversion.
|
||||||
* Include more FB2 specific tags in the conversion.
|
* Handle a tags.
|
||||||
* Handle reopening of a tag properly.
|
|
||||||
* Figure out some way to turn oeb_book.toc items into <section><title>
|
* Figure out some way to turn oeb_book.toc items into <section><title>
|
||||||
<p> to allow for readers to generate toc from the document.
|
<p> to allow for readers to generate toc from the document.
|
||||||
'''
|
'''
|
||||||
@ -66,7 +63,8 @@ class FB2MLizer(object):
|
|||||||
def __init__(self, log):
|
def __init__(self, log):
|
||||||
self.log = log
|
self.log = log
|
||||||
self.image_hrefs = {}
|
self.image_hrefs = {}
|
||||||
self.link_hrefs = {}
|
# Used to ensure text and tags are always within <p> and </p>
|
||||||
|
self.in_p = False
|
||||||
|
|
||||||
def extract_content(self, oeb_book, opts):
|
def extract_content(self, oeb_book, opts):
|
||||||
self.log.info('Converting XHTML to FB2 markup...')
|
self.log.info('Converting XHTML to FB2 markup...')
|
||||||
@ -78,17 +76,15 @@ class FB2MLizer(object):
|
|||||||
self.image_hrefs = {}
|
self.image_hrefs = {}
|
||||||
self.link_hrefs = {}
|
self.link_hrefs = {}
|
||||||
output = [self.fb2_header()]
|
output = [self.fb2_header()]
|
||||||
output.append(self.get_cover_page())
|
|
||||||
output.append(u'ghji87yhjko0Caliblre-toc-placeholder-for-insertion-later8ujko0987yjk')
|
|
||||||
output.append(self.get_text())
|
output.append(self.get_text())
|
||||||
output.append(self.fb2_body_footer())
|
output.append(self.fb2_body_footer())
|
||||||
output.append(self.fb2mlize_images())
|
output.append(self.fb2mlize_images())
|
||||||
output.append(self.fb2_footer())
|
output.append(self.fb2_footer())
|
||||||
output = ''.join(output).replace(u'ghji87yhjko0Caliblre-toc-placeholder-for-insertion-later8ujko0987yjk', self.get_toc())
|
output = self.clean_text(u''.join(output))
|
||||||
output = self.clean_text(output)
|
if self.opts.pretty_print:
|
||||||
if self.opts.sectionize_chapters:
|
return u'<?xml version="1.0" encoding="UTF-8"?>\n%s' % etree.tostring(etree.fromstring(output), encoding=unicode, pretty_print=True)
|
||||||
output = self.sectionize_chapters(output)
|
else:
|
||||||
return u'<?xml version="1.0" encoding="UTF-8"?>\n%s' % etree.tostring(etree.fromstring(output), encoding=unicode, pretty_print=True)
|
return u'<?xml version="1.0" encoding="UTF-8"?>' + output
|
||||||
|
|
||||||
def clean_text(self, text):
|
def clean_text(self, text):
|
||||||
text = re.sub(r'(?miu)<section>\s*</section>', '', text)
|
text = re.sub(r'(?miu)<section>\s*</section>', '', text)
|
||||||
@ -116,88 +112,40 @@ class FB2MLizer(object):
|
|||||||
author_middle = ' '.join(author_parts[1:-2])
|
author_middle = ' '.join(author_parts[1:-2])
|
||||||
author_last = author_parts[-1]
|
author_last = author_parts[-1]
|
||||||
|
|
||||||
return u'<FictionBook xmlns:xlink="http://www.w3.org/1999/xlink" ' \
|
return u'<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">' \
|
||||||
'xmlns="http://www.gribuser.ru/xml/fictionbook/2.0">\n' \
|
'<description>' \
|
||||||
'<description>\n<title-info>\n ' \
|
'<title-info>' \
|
||||||
'<author>\n<first-name>%s</first-name>\n<middle-name>%s' \
|
'<genre></genre>' \
|
||||||
'</middle-name>\n<last-name>%s</last-name>\n</author>\n' \
|
'<author>' \
|
||||||
'<book-title>%s</book-title> ' \
|
'<first-name>%s</first-name>' \
|
||||||
'</title-info><document-info> ' \
|
'<middle-name>%s</middle-name>' \
|
||||||
'<program-used>%s - %s</program-used></document-info>\n' \
|
'<last-name>%s</last-name>' \
|
||||||
'</description>\n<body>\n<section>' % tuple(map(prepare_string_for_xml,
|
'</author>' \
|
||||||
(author_first, author_middle,
|
'<book-title>%s</book-title>' \
|
||||||
author_last, self.oeb_book.metadata.title[0].value,
|
'<annotation><p/></annotation>' \
|
||||||
__appname__, __version__)))
|
'</title-info>' \
|
||||||
|
'<document-info>' \
|
||||||
def get_cover_page(self):
|
'<program-used>%s %s</program-used>' \
|
||||||
output = u''
|
'</document-info>' \
|
||||||
if 'cover' in self.oeb_book.guide:
|
'</description><body>' % tuple(map(prepare_string_for_xml, (author_first, author_middle, author_last,
|
||||||
output += '<image xlink:href="#cover.jpg" />'
|
self.oeb_book.metadata.title[0].value, __appname__, __version__)))
|
||||||
self.image_hrefs[self.oeb_book.guide['cover'].href] = 'cover.jpg'
|
|
||||||
if 'titlepage' in self.oeb_book.guide:
|
|
||||||
self.log.debug('Generating cover page...')
|
|
||||||
href = self.oeb_book.guide['titlepage'].href
|
|
||||||
item = self.oeb_book.manifest.hrefs[href]
|
|
||||||
if item.spine_position is None:
|
|
||||||
stylizer = Stylizer(item.data, item.href, self.oeb_book,
|
|
||||||
self.opts, self.opts.output_profile)
|
|
||||||
output += ''.join(self.dump_text(item.data.find(XHTML('body')), stylizer, item))
|
|
||||||
return output
|
|
||||||
|
|
||||||
def get_toc(self):
|
|
||||||
toc = []
|
|
||||||
if self.opts.inline_toc:
|
|
||||||
self.log.debug('Generating table of contents...')
|
|
||||||
toc.append(u'<p>%s</p>' % _('Table of Contents:'))
|
|
||||||
for item in self.oeb_book.toc:
|
|
||||||
if item.href in self.link_hrefs.keys():
|
|
||||||
toc.append('<p><a xlink:href="#%s">%s</a></p>\n' % (self.link_hrefs[item.href], item.title))
|
|
||||||
else:
|
|
||||||
self.oeb.warn('Ignoring toc item: %s not found in document.' % item)
|
|
||||||
return ''.join(toc)
|
|
||||||
|
|
||||||
def sectionize_chapters(self, text):
|
|
||||||
def remove_p(t):
|
|
||||||
t = t.replace('<p>', '')
|
|
||||||
t = t.replace('</p>', '')
|
|
||||||
return t
|
|
||||||
text = re.sub(r'(?imsu)(<p>)\s*(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*(</p>)\s*(<p>)\s*(?P<strong><strong>.+?</strong>)\s*(</p>)', lambda mo: '</section><section>%s<title><p>%s</p></title>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text)
|
|
||||||
text = re.sub(r'(?imsu)(<p>)\s*(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*(</p>)\s*(?P<strong><strong>.+?</strong>)', lambda mo: '</section><section>%s<title><p>%s</p></title>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text)
|
|
||||||
text = re.sub(r'(?imsu)(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*(<p>)\s*(?P<strong><strong>.+?</strong>)\s*(</p>)', lambda mo: '</section><section>%s<title><p>%s</p></title>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text)
|
|
||||||
text = re.sub(r'(?imsu)(<p>)\s*(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*(?P<strong><strong>.+?</strong>)\s*(</p>)', lambda mo: '</section><section>%s<title><p>%s</p></title>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text)
|
|
||||||
text = re.sub(r'(?imsu)(?P<anchor><a\s+id="calibre_link-\d+"\s*/>)\s*(?P<strong><strong>.+?</strong>)', lambda mo: '</section><section>%s<title><p>%s</p></title>' % (mo.group('anchor'), remove_p(mo.group('strong'))), text)
|
|
||||||
return text
|
|
||||||
|
|
||||||
def get_text(self):
|
def get_text(self):
|
||||||
text = []
|
text = []
|
||||||
for i, item in enumerate(self.oeb_book.spine):
|
for item in self.oeb_book.spine:
|
||||||
if self.opts.sectionize_chapters_using_file_structure and i is not 0:
|
|
||||||
text.append('<section>')
|
|
||||||
self.log.debug('Converting %s to FictionBook2 XML' % item.href)
|
self.log.debug('Converting %s to FictionBook2 XML' % item.href)
|
||||||
stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile)
|
stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile)
|
||||||
text.append(self.add_page_anchor(item))
|
text.append('<section>')
|
||||||
text += self.dump_text(item.data.find(XHTML('body')), stylizer, item)
|
text += self.dump_text(item.data.find(XHTML('body')), stylizer, item)
|
||||||
if self.opts.sectionize_chapters_using_file_structure and i is not len(self.oeb_book.spine) - 1:
|
text.append('</section>')
|
||||||
text.append('</section>')
|
|
||||||
return ''.join(text)
|
return ''.join(text)
|
||||||
|
|
||||||
def fb2_body_footer(self):
|
def fb2_body_footer(self):
|
||||||
return u'\n</section>\n</body>'
|
return u'</body>'
|
||||||
|
|
||||||
def fb2_footer(self):
|
def fb2_footer(self):
|
||||||
return u'</FictionBook>'
|
return u'</FictionBook>'
|
||||||
|
|
||||||
def add_page_anchor(self, page):
|
|
||||||
return self.get_anchor(page, '')
|
|
||||||
|
|
||||||
def get_anchor(self, page, aid):
|
|
||||||
aid = prepare_string_for_xml(aid)
|
|
||||||
aid = '%s#%s' % (page.href, aid)
|
|
||||||
if aid not in self.link_hrefs.keys():
|
|
||||||
self.link_hrefs[aid] = 'calibre_link-%s' % len(self.link_hrefs.keys())
|
|
||||||
aid = self.link_hrefs[aid]
|
|
||||||
return '<a id="%s" />' % aid
|
|
||||||
|
|
||||||
def fb2mlize_images(self):
|
def fb2mlize_images(self):
|
||||||
images = []
|
images = []
|
||||||
for item in self.oeb_book.manifest:
|
for item in self.oeb_book.manifest:
|
||||||
@ -218,12 +166,60 @@ class FB2MLizer(object):
|
|||||||
col = 1
|
col = 1
|
||||||
col += 1
|
col += 1
|
||||||
data += char
|
data += char
|
||||||
images.append('<binary id="%s" content-type="%s">%s\n</binary>' % (self.image_hrefs.get(item.href, '0000.JPEG'), item.media_type, data))
|
images.append('<binary id="%s" content-type="%s">%s\n</binary>' % (self.image_hrefs.get(item.href, '_0000.JPEG'), item.media_type, data))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error('Error: Could not include file %s becuase ' \
|
self.log.error('Error: Could not include file %s because ' \
|
||||||
'%s.' % (item.href, e))
|
'%s.' % (item.href, e))
|
||||||
return ''.join(images)
|
return ''.join(images)
|
||||||
|
|
||||||
|
def ensure_p(self):
|
||||||
|
if self.in_p:
|
||||||
|
return [], []
|
||||||
|
else:
|
||||||
|
self.in_p = True
|
||||||
|
return ['<p>'], ['p']
|
||||||
|
|
||||||
|
def insert_empty_line(self, tags):
|
||||||
|
if self.in_p:
|
||||||
|
text = ['']
|
||||||
|
closed_tags = []
|
||||||
|
tags.reverse()
|
||||||
|
for t in tags:
|
||||||
|
text.append('</%s>' % t)
|
||||||
|
closed_tags.append(t)
|
||||||
|
if t == 'p':
|
||||||
|
break
|
||||||
|
text.append('<empty-line />')
|
||||||
|
closed_tags.reverse()
|
||||||
|
for t in closed_tags:
|
||||||
|
text.append('<%s>' % t)
|
||||||
|
return text
|
||||||
|
else:
|
||||||
|
return ['<empty-line />']
|
||||||
|
|
||||||
|
def close_open_p(self, tags):
|
||||||
|
text = ['']
|
||||||
|
added_p = False
|
||||||
|
|
||||||
|
if self.in_p:
|
||||||
|
# Close all up to p. Close p. Reopen all closed tags including p.
|
||||||
|
closed_tags = []
|
||||||
|
tags.reverse()
|
||||||
|
for t in tags:
|
||||||
|
text.append('</%s>' % t)
|
||||||
|
closed_tags.append(t)
|
||||||
|
if t == 'p':
|
||||||
|
break
|
||||||
|
closed_tags.reverse()
|
||||||
|
for t in closed_tags:
|
||||||
|
text.append('<%s>' % t)
|
||||||
|
else:
|
||||||
|
text.append('<p>')
|
||||||
|
added_p = True
|
||||||
|
self.in_p = True
|
||||||
|
|
||||||
|
return text, added_p
|
||||||
|
|
||||||
def dump_text(self, elem, stylizer, page, tag_stack=[]):
|
def dump_text(self, elem, stylizer, page, tag_stack=[]):
|
||||||
if not isinstance(elem.tag, basestring) \
|
if not isinstance(elem.tag, basestring) \
|
||||||
or namespace(elem.tag) != XHTML_NS:
|
or namespace(elem.tag) != XHTML_NS:
|
||||||
@ -242,53 +238,28 @@ class FB2MLizer(object):
|
|||||||
if tag in TAG_IMAGES:
|
if tag in TAG_IMAGES:
|
||||||
if elem.attrib.get('src', None):
|
if elem.attrib.get('src', None):
|
||||||
if page.abshref(elem.attrib['src']) not in self.image_hrefs.keys():
|
if page.abshref(elem.attrib['src']) not in self.image_hrefs.keys():
|
||||||
self.image_hrefs[page.abshref(elem.attrib['src'])] = '%s.jpg' % len(self.image_hrefs.keys())
|
self.image_hrefs[page.abshref(elem.attrib['src'])] = '_%s.jpg' % len(self.image_hrefs.keys())
|
||||||
|
p_txt, p_tag = self.ensure_p()
|
||||||
|
fb2_text += p_txt
|
||||||
|
tags += p_tag
|
||||||
fb2_text.append('<image xlink:href="#%s" />' % self.image_hrefs[page.abshref(elem.attrib['src'])])
|
fb2_text.append('<image xlink:href="#%s" />' % self.image_hrefs[page.abshref(elem.attrib['src'])])
|
||||||
|
|
||||||
if tag in TAG_LINKS:
|
|
||||||
href = elem.get('href')
|
|
||||||
if href:
|
|
||||||
href = prepare_string_for_xml(page.abshref(href))
|
|
||||||
href = href.replace('"', '"')
|
|
||||||
if '://' in href:
|
|
||||||
fb2_text.append('<a xlink:href="%s">' % href)
|
|
||||||
else:
|
|
||||||
if href.startswith('#'):
|
|
||||||
href = href[1:]
|
|
||||||
if href not in self.link_hrefs.keys():
|
|
||||||
self.link_hrefs[href] = 'calibre_link-%s' % len(self.link_hrefs.keys())
|
|
||||||
href = self.link_hrefs[href]
|
|
||||||
fb2_text.append('<a xlink:href="#%s">' % href)
|
|
||||||
tags.append('a')
|
|
||||||
|
|
||||||
# Anchor ids
|
|
||||||
id_name = elem.get('id')
|
|
||||||
if id_name:
|
|
||||||
fb2_text.append(self.get_anchor(page, id_name))
|
|
||||||
|
|
||||||
if tag == 'h1' and self.opts.h1_to_title or tag == 'h2' and self.opts.h2_to_title or tag == 'h3' and self.opts.h3_to_title:
|
if tag == 'h1' and self.opts.h1_to_title or tag == 'h2' and self.opts.h2_to_title or tag == 'h3' and self.opts.h3_to_title:
|
||||||
fb2_text.append('<title>')
|
fb2_text.append('<title>')
|
||||||
tags.append('title')
|
tags.append('title')
|
||||||
|
if tag == 'br':
|
||||||
|
fb2_text += self.insert_empty_line(tag_stack+tags)
|
||||||
|
|
||||||
fb2_tag = TAG_MAP.get(tag, None)
|
fb2_tag = TAG_MAP.get(tag, None)
|
||||||
if fb2_tag == 'p':
|
if fb2_tag == 'p':
|
||||||
if 'p' in tag_stack+tags:
|
p_text, added_p = self.close_open_p(tag_stack+tags)
|
||||||
# Close all up to p. Close p. Reopen all closed tags including p.
|
fb2_text += p_text
|
||||||
all_tags = tag_stack+tags
|
if added_p:
|
||||||
closed_tags = []
|
|
||||||
all_tags.reverse()
|
|
||||||
for t in all_tags:
|
|
||||||
fb2_text.append('</%s>' % t)
|
|
||||||
closed_tags.append(t)
|
|
||||||
if t == 'p':
|
|
||||||
break
|
|
||||||
closed_tags.reverse()
|
|
||||||
for t in closed_tags:
|
|
||||||
fb2_text.append('<%s>' % t)
|
|
||||||
else:
|
|
||||||
fb2_text.append('<p>')
|
|
||||||
tags.append('p')
|
tags.append('p')
|
||||||
elif fb2_tag and fb2_tag not in tag_stack+tags:
|
elif fb2_tag and fb2_tag not in tag_stack+tags:
|
||||||
|
p_text, p_tags = self.ensure_p()
|
||||||
|
fb2_text += p_text
|
||||||
|
tags += p_tags
|
||||||
fb2_text.append('<%s>' % fb2_tag)
|
fb2_text.append('<%s>' % fb2_tag)
|
||||||
tags.append(fb2_tag)
|
tags.append(fb2_tag)
|
||||||
|
|
||||||
@ -296,18 +267,21 @@ class FB2MLizer(object):
|
|||||||
for s in STYLES:
|
for s in STYLES:
|
||||||
style_tag = s[1].get(style[s[0]], None)
|
style_tag = s[1].get(style[s[0]], None)
|
||||||
if style_tag and style_tag not in tag_stack+tags:
|
if style_tag and style_tag not in tag_stack+tags:
|
||||||
|
p_text, p_tags = self.ensure_p()
|
||||||
|
fb2_text += p_text
|
||||||
|
tags += p_tags
|
||||||
fb2_text.append('<%s>' % style_tag)
|
fb2_text.append('<%s>' % style_tag)
|
||||||
tags.append(style_tag)
|
tags.append(style_tag)
|
||||||
|
|
||||||
if tag in TAG_SPACE:
|
if tag in TAG_SPACE:
|
||||||
if not fb2_text or fb2_text[-1] != ' ' or not fb2_text[-1].endswith(' '):
|
fb2_text.append(' ')
|
||||||
fb2_text.append(' ')
|
|
||||||
|
|
||||||
if hasattr(elem, 'text') and elem.text:
|
if hasattr(elem, 'text') and elem.text:
|
||||||
if 'p' not in tag_stack+tags:
|
if not self.in_p:
|
||||||
fb2_text.append('<p>%s</p>' % prepare_string_for_xml(elem.text))
|
fb2_text.append('<p>')
|
||||||
else:
|
fb2_text.append(prepare_string_for_xml(elem.text))
|
||||||
fb2_text.append(prepare_string_for_xml(elem.text))
|
if not self.in_p:
|
||||||
|
fb2_text.append('</p>')
|
||||||
|
|
||||||
for item in elem:
|
for item in elem:
|
||||||
fb2_text += self.dump_text(item, stylizer, page, tag_stack+tags)
|
fb2_text += self.dump_text(item, stylizer, page, tag_stack+tags)
|
||||||
@ -316,10 +290,11 @@ class FB2MLizer(object):
|
|||||||
fb2_text += self.close_tags(tags)
|
fb2_text += self.close_tags(tags)
|
||||||
|
|
||||||
if hasattr(elem, 'tail') and elem.tail:
|
if hasattr(elem, 'tail') and elem.tail:
|
||||||
if 'p' not in tag_stack:
|
if not self.in_p:
|
||||||
fb2_text.append('<p>%s</p>' % prepare_string_for_xml(elem.tail))
|
fb2_text.append('<p>')
|
||||||
else:
|
fb2_text.append(prepare_string_for_xml(elem.tail))
|
||||||
fb2_text.append(prepare_string_for_xml(elem.tail))
|
if not self.in_p:
|
||||||
|
fb2_text.append('</p>')
|
||||||
|
|
||||||
return fb2_text
|
return fb2_text
|
||||||
|
|
||||||
@ -327,5 +302,7 @@ class FB2MLizer(object):
|
|||||||
text = []
|
text = []
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
text.append('</%s>' % tag)
|
text.append('</%s>' % tag)
|
||||||
|
if tag == 'p':
|
||||||
|
self.in_p = False
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
@ -16,20 +16,6 @@ class FB2Output(OutputFormatPlugin):
|
|||||||
file_type = 'fb2'
|
file_type = 'fb2'
|
||||||
|
|
||||||
options = set([
|
options = set([
|
||||||
OptionRecommendation(name='inline_toc',
|
|
||||||
recommended_value=False, level=OptionRecommendation.LOW,
|
|
||||||
help=_('Add Table of Contents to beginning of the book.')),
|
|
||||||
OptionRecommendation(name='sectionize_chapters',
|
|
||||||
recommended_value=False, level=OptionRecommendation.LOW,
|
|
||||||
help=_('Try to turn chapters into individual sections. ' \
|
|
||||||
'WARNING: ' \
|
|
||||||
'This option is experimental. It can cause conversion ' \
|
|
||||||
'to fail. It can also produce unexpected output.')),
|
|
||||||
OptionRecommendation(name='sectionize_chapters_using_file_structure',
|
|
||||||
recommended_value=False, level=OptionRecommendation.LOW,
|
|
||||||
help=_('Try to turn chapters into individual sections using the ' \
|
|
||||||
'internal structure of the ebook. This works well for EPUB ' \
|
|
||||||
'books that have been internally split by chapter.')),
|
|
||||||
OptionRecommendation(name='h1_to_title',
|
OptionRecommendation(name='h1_to_title',
|
||||||
recommended_value=False, level=OptionRecommendation.LOW,
|
recommended_value=False, level=OptionRecommendation.LOW,
|
||||||
help=_('Wrap all h1 tags with fb2 title elements.')),
|
help=_('Wrap all h1 tags with fb2 title elements.')),
|
||||||
|
@ -17,8 +17,6 @@ class PluginWidget(Widget, Ui_Form):
|
|||||||
ICON = I('mimetypes/fb2.png')
|
ICON = I('mimetypes/fb2.png')
|
||||||
|
|
||||||
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
Widget.__init__(self, parent, ['inline_toc', 'sectionize_chapters',
|
Widget.__init__(self, parent, ['h1_to_title', 'h2_to_title', 'h3_to_title'])
|
||||||
'sectionize_chapters_using_file_structure', 'h1_to_title',
|
|
||||||
'h2_to_title', 'h3_to_title'])
|
|
||||||
self.db, self.book_id = db, book_id
|
self.db, self.book_id = db, book_id
|
||||||
self.initialize_options(get_option, get_help, db, book_id)
|
self.initialize_options(get_option, get_help, db, book_id)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="6" column="0">
|
<item row="3" column="0">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
@ -28,41 +28,20 @@
|
|||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="opt_inline_toc">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Inline TOC</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="opt_sectionize_chapters">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sectionize Chapters (Use with care!)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="opt_sectionize_chapters_using_file_structure">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sectionize Chapters using file structure</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QCheckBox" name="opt_h1_to_title">
|
<widget class="QCheckBox" name="opt_h1_to_title">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Wrap h1 tags with <title> elements</string>
|
<string>Wrap h1 tags with <title> elements</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="opt_h2_to_title">
|
<widget class="QCheckBox" name="opt_h2_to_title">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Wrap h2 tags with <title> elements</string>
|
<string>Wrap h2 tags with <title> elements</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="opt_h3_to_title">
|
<widget class="QCheckBox" name="opt_h3_to_title">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Wrap h3 tags with <title> elements</string>
|
<string>Wrap h3 tags with <title> elements</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user