<s> """<STR_LIT>""" <EOL> import os <EOL> import re <EOL> import codecs <EOL> import zipfile <EOL> from os import path <EOL> try : <EOL> from PIL import Image <EOL> except ImportError : <EOL> try : <EOL> import Image <EOL> except ImportError : <EOL> Image = None <EOL> from docutils import nodes <EOL> from sphinx import addnodes <EOL> from sphinx . builders . html import StandaloneHTMLBuilder <EOL> from sphinx . util . i18n import format_date <EOL> from sphinx . util . osutil import ensuredir , copyfile , EEXIST <EOL> from sphinx . util . smartypants import sphinx_smarty_pants as ssp <EOL> from sphinx . util . console import brown <EOL> MIMETYPE_TEMPLATE = '<STR_LIT>' <EOL> CONTAINER_TEMPLATE = u'''<STR_LIT>''' <EOL> TOC_TEMPLATE = u'''<STR_LIT>''' <EOL> NAVPOINT_TEMPLATE = u'''<STR_LIT>''' <EOL> NAVPOINT_INDENT = '<STR_LIT:U+0020>' <EOL> NODE_NAVPOINT_TEMPLATE = '<STR_LIT>' <EOL> CONTENT_TEMPLATE = u'''<STR_LIT>''' <EOL> COVER_TEMPLATE = u'''<STR_LIT>''' <EOL> COVERPAGE_NAME = u'<STR_LIT>' <EOL> FILE_TEMPLATE = u'''<STR_LIT>''' <EOL> SPINE_TEMPLATE = u'''<STR_LIT>''' <EOL> GUIDE_TEMPLATE = u'''<STR_LIT>''' <EOL> TOCTREE_TEMPLATE = u'<STR_LIT>' <EOL> LINK_TARGET_TEMPLATE = u'<STR_LIT>' <EOL> FOOTNOTE_LABEL_TEMPLATE = u'<STR_LIT>' <EOL> FOOTNOTES_RUBRIC_NAME = u'<STR_LIT>' <EOL> CSS_LINK_TARGET_CLASS = u'<STR_LIT>' <EOL> GUIDE_TITLES = { <EOL> '<STR_LIT>' : u'<STR_LIT>' , <EOL> '<STR_LIT>' : u'<STR_LIT>' <EOL> } <EOL> MEDIA_TYPES = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> VECTOR_GRAPHICS_EXTENSIONS = ( '<STR_LIT>' , ) <EOL> REFURI_RE = re . compile ( "<STR_LIT>" ) <EOL> class EpubBuilder ( StandaloneHTMLBuilder ) : <EOL> """<STR_LIT>""" <EOL> name = '<STR_LIT>' <EOL> copysource = False <EOL> supported_image_types = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> add_permalinks = False <EOL> embedded = True <EOL> mimetype_template = MIMETYPE_TEMPLATE <EOL> container_template = CONTAINER_TEMPLATE <EOL> toc_template = TOC_TEMPLATE <EOL> navpoint_template = NAVPOINT_TEMPLATE <EOL> navpoint_indent = NAVPOINT_INDENT <EOL> node_navpoint_template = NODE_NAVPOINT_TEMPLATE <EOL> content_template = CONTENT_TEMPLATE <EOL> cover_template = COVER_TEMPLATE <EOL> coverpage_name = COVERPAGE_NAME <EOL> file_template = FILE_TEMPLATE <EOL> spine_template = SPINE_TEMPLATE <EOL> guide_template = GUIDE_TEMPLATE <EOL> toctree_template = TOCTREE_TEMPLATE <EOL> link_target_template = LINK_TARGET_TEMPLATE <EOL> css_link_target_class = CSS_LINK_TARGET_CLASS <EOL> guide_titles = GUIDE_TITLES <EOL> media_types = MEDIA_TYPES <EOL> refuri_re = REFURI_RE <EOL> def init ( self ) : <EOL> StandaloneHTMLBuilder . init ( self ) <EOL> self . out_suffix = '<STR_LIT>' <EOL> self . playorder = <NUM_LIT:0> <EOL> self . tocid = <NUM_LIT:0> <EOL> def get_theme_config ( self ) : <EOL> return self . config . epub_theme , self . config . epub_theme_options <EOL> def make_id ( self , name , id_cache = { } ) : <EOL> """<STR_LIT>""" <EOL> id = id_cache . get ( name ) <EOL> if not id : <EOL> id = '<STR_LIT>' % self . env . new_serialno ( '<STR_LIT>' ) <EOL> id_cache [ name ] = id <EOL> return id <EOL> def esc ( self , name ) : <EOL> """<STR_LIT>""" <EOL> name = name . replace ( '<STR_LIT:&>' , '<STR_LIT>' ) <EOL> name = name . replace ( '<STR_LIT:<>' , '<STR_LIT>' ) <EOL> name = name . replace ( '<STR_LIT:>>' , '<STR_LIT>' ) <EOL> name = name . replace ( '<STR_LIT:">' , '<STR_LIT>' ) <EOL> name = name . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> return name <EOL> def get_refnodes ( self , doctree , result ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( doctree , nodes . reference ) and '<STR_LIT>' in doctree : <EOL> refuri = doctree [ '<STR_LIT>' ] <EOL> if refuri . startswith ( '<STR_LIT>' ) or refuri . startswith ( '<STR_LIT>' ) or refuri . startswith ( '<STR_LIT>' ) or refuri . startswith ( '<STR_LIT>' ) : <EOL> return result <EOL> classes = doctree . parent . attributes [ '<STR_LIT>' ] <EOL> for level in range ( <NUM_LIT:8> , <NUM_LIT:0> , - <NUM_LIT:1> ) : <EOL> if ( self . toctree_template % level ) in classes : <EOL> result . append ( { <EOL> '<STR_LIT>' : level , <EOL> '<STR_LIT>' : self . esc ( refuri ) , <EOL> '<STR_LIT:text>' : ssp ( self . esc ( doctree . astext ( ) ) ) <EOL> } ) <EOL> break <EOL> else : <EOL> for elem in doctree . children : <EOL> result = self . get_refnodes ( elem , result ) <EOL> return result <EOL> def get_toc ( self ) : <EOL> """<STR_LIT>""" <EOL> doctree = self . env . get_and_resolve_doctree ( self . config . master_doc , <EOL> self , prune_toctrees = False , <EOL> includehidden = True ) <EOL> self . refnodes = self . get_refnodes ( doctree , [ ] ) <EOL> master_dir = path . dirname ( self . config . master_doc ) <EOL> if master_dir : <EOL> master_dir += '<STR_LIT:/>' <EOL> for item in self . refnodes : <EOL> item [ '<STR_LIT>' ] = master_dir + item [ '<STR_LIT>' ] <EOL> self . toc_add_files ( self . refnodes ) <EOL> def toc_add_files ( self , refnodes ) : <EOL> """<STR_LIT>""" <EOL> refnodes . insert ( <NUM_LIT:0> , { <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : self . esc ( self . config . master_doc + '<STR_LIT>' ) , <EOL> '<STR_LIT:text>' : ssp ( self . esc ( <EOL> self . env . titles [ self . config . master_doc ] . astext ( ) ) ) <EOL> } ) <EOL> for file , text in reversed ( self . config . epub_pre_files ) : <EOL> refnodes . insert ( <NUM_LIT:0> , { <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : self . esc ( file ) , <EOL> '<STR_LIT:text>' : ssp ( self . esc ( text ) ) <EOL> } ) <EOL> for file , text in self . config . epub_post_files : <EOL> refnodes . append ( { <EOL> '<STR_LIT>' : <NUM_LIT:1> , <EOL> '<STR_LIT>' : self . esc ( file ) , <EOL> '<STR_LIT:text>' : ssp ( self . esc ( text ) ) <EOL> } ) <EOL> def fix_fragment ( self , prefix , fragment ) : <EOL> """<STR_LIT>""" <EOL> return prefix + fragment . replace ( '<STR_LIT::>' , '<STR_LIT:->' ) <EOL> def fix_ids ( self , tree ) : <EOL> """<STR_LIT>""" <EOL> for node in tree . traverse ( nodes . reference ) : <EOL> if '<STR_LIT>' in node : <EOL> m = self . refuri_re . match ( node [ '<STR_LIT>' ] ) <EOL> if m : <EOL> node [ '<STR_LIT>' ] = self . fix_fragment ( m . group ( <NUM_LIT:1> ) , m . group ( <NUM_LIT:2> ) ) <EOL> if '<STR_LIT>' in node : <EOL> node [ '<STR_LIT>' ] = self . fix_fragment ( '<STR_LIT>' , node [ '<STR_LIT>' ] ) <EOL> for node in tree . traverse ( addnodes . desc_signature ) : <EOL> ids = node . attributes [ '<STR_LIT>' ] <EOL> newids = [ ] <EOL> for id in ids : <EOL> newids . append ( self . fix_fragment ( '<STR_LIT>' , id ) ) <EOL> node . attributes [ '<STR_LIT>' ] = newids <EOL> def add_visible_links ( self , tree , show_urls = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> def make_footnote_ref ( doc , label ) : <EOL> """<STR_LIT>""" <EOL> footnote_ref = nodes . footnote_reference ( '<STR_LIT>' ) <EOL> footnote_ref . append ( nodes . Text ( label ) ) <EOL> doc . note_autofootnote_ref ( footnote_ref ) <EOL> return footnote_ref <EOL> def make_footnote ( doc , label , uri ) : <EOL> """<STR_LIT>""" <EOL> footnote = nodes . footnote ( uri ) <EOL> para = nodes . paragraph ( ) <EOL> para . append ( nodes . Text ( uri ) ) <EOL> footnote . append ( para ) <EOL> footnote . insert ( <NUM_LIT:0> , nodes . label ( '<STR_LIT>' , label ) ) <EOL> doc . note_autofootnote ( footnote ) <EOL> return footnote <EOL> def footnote_spot ( tree ) : <EOL> """<STR_LIT>""" <EOL> fns = tree . traverse ( nodes . footnote ) <EOL> if fns : <EOL> fn = fns [ - <NUM_LIT:1> ] <EOL> return fn . parent , fn . parent . index ( fn ) + <NUM_LIT:1> <EOL> for node in tree . traverse ( nodes . rubric ) : <EOL> if len ( node . children ) == <NUM_LIT:1> and node . children [ <NUM_LIT:0> ] . astext ( ) == FOOTNOTES_RUBRIC_NAME : <EOL> return node . parent , node . parent . index ( node ) + <NUM_LIT:1> <EOL> doc = tree . traverse ( nodes . document ) [ <NUM_LIT:0> ] <EOL> rub = nodes . rubric ( ) <EOL> rub . append ( nodes . Text ( FOOTNOTES_RUBRIC_NAME ) ) <EOL> doc . append ( rub ) <EOL> return doc , doc . index ( rub ) + <NUM_LIT:1> <EOL> if show_urls == '<STR_LIT>' : <EOL> return <EOL> if show_urls == '<STR_LIT>' : <EOL> doc = tree . traverse ( nodes . document ) [ <NUM_LIT:0> ] <EOL> fn_spot , fn_idx = footnote_spot ( tree ) <EOL> nr = <NUM_LIT:1> <EOL> for node in tree . traverse ( nodes . reference ) : <EOL> uri = node . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if ( uri . startswith ( '<STR_LIT>' ) or uri . startswith ( '<STR_LIT>' ) or <EOL> uri . startswith ( '<STR_LIT>' ) ) and uri not in node . astext ( ) : <EOL> idx = node . parent . index ( node ) + <NUM_LIT:1> <EOL> if show_urls == '<STR_LIT>' : <EOL> uri = self . link_target_template % { '<STR_LIT>' : uri } <EOL> link = nodes . inline ( uri , uri ) <EOL> link [ '<STR_LIT>' ] . append ( self . css_link_target_class ) <EOL> node . parent . insert ( idx , link ) <EOL> elif show_urls == '<STR_LIT>' : <EOL> label = FOOTNOTE_LABEL_TEMPLATE % nr <EOL> nr += <NUM_LIT:1> <EOL> footnote_ref = make_footnote_ref ( doc , label ) <EOL> node . parent . insert ( idx , footnote_ref ) <EOL> footnote = make_footnote ( doc , label , uri ) <EOL> fn_spot . insert ( fn_idx , footnote ) <EOL> footnote_ref [ '<STR_LIT>' ] = footnote [ '<STR_LIT>' ] [ <NUM_LIT:0> ] <EOL> footnote . add_backref ( footnote_ref [ '<STR_LIT>' ] [ <NUM_LIT:0> ] ) <EOL> fn_idx += <NUM_LIT:1> <EOL> def write_doc ( self , docname , doctree ) : <EOL> """<STR_LIT>""" <EOL> self . fix_ids ( doctree ) <EOL> self . add_visible_links ( doctree , self . config . epub_show_urls ) <EOL> return StandaloneHTMLBuilder . write_doc ( self , docname , doctree ) <EOL> def fix_genindex ( self , tree ) : <EOL> """<STR_LIT>""" <EOL> for key , columns in tree : <EOL> for entryname , ( links , subitems , key_ ) in columns : <EOL> for ( i , ( ismain , link ) ) in enumerate ( links ) : <EOL> m = self . refuri_re . match ( link ) <EOL> if m : <EOL> links [ i ] = ( ismain , <EOL> self . fix_fragment ( m . group ( <NUM_LIT:1> ) , m . group ( <NUM_LIT:2> ) ) ) <EOL> for subentryname , subentrylinks in subitems : <EOL> for ( i , ( ismain , link ) ) in enumerate ( subentrylinks ) : <EOL> m = self . refuri_re . match ( link ) <EOL> if m : <EOL> subentrylinks [ i ] = ( ismain , <EOL> self . fix_fragment ( m . group ( <NUM_LIT:1> ) , m . group ( <NUM_LIT:2> ) ) ) <EOL> def is_vector_graphics ( self , filename ) : <EOL> """<STR_LIT>""" <EOL> ext = path . splitext ( filename ) [ - <NUM_LIT:1> ] <EOL> return ext in VECTOR_GRAPHICS_EXTENSIONS <EOL> def copy_image_files_pil ( self ) : <EOL> """<STR_LIT>""" <EOL> ensuredir ( path . join ( self . outdir , self . imagedir ) ) <EOL> for src in self . app . status_iterator ( self . images , '<STR_LIT>' , <EOL> brown , len ( self . images ) ) : <EOL> dest = self . images [ src ] <EOL> try : <EOL> img = Image . open ( path . join ( self . srcdir , src ) ) <EOL> except IOError : <EOL> if not self . is_vector_graphics ( src ) : <EOL> self . warn ( '<STR_LIT>' % <EOL> ( path . join ( self . srcdir , src ) , ) ) <EOL> try : <EOL> copyfile ( path . join ( self . srcdir , src ) , <EOL> path . join ( self . outdir , self . imagedir , dest ) ) <EOL> except ( IOError , OSError ) as err : <EOL> self . warn ( '<STR_LIT>' % <EOL> ( path . join ( self . srcdir , src ) , err ) ) <EOL> continue <EOL> if self . config . epub_fix_images : <EOL> if img . mode in ( '<STR_LIT:P>' , ) : <EOL> img = img . convert ( ) <EOL> if self . config . epub_max_image_width > <NUM_LIT:0> : <EOL> ( width , height ) = img . size <EOL> nw = self . config . epub_max_image_width <EOL> if width > nw : <EOL> nh = ( height * nw ) / width <EOL> img = img . resize ( ( nw , nh ) , Image . BICUBIC ) <EOL> try : <EOL> img . save ( path . join ( self . outdir , self . imagedir , dest ) ) <EOL> except ( IOError , OSError ) as err : <EOL> self . warn ( '<STR_LIT>' % <EOL> ( path . join ( self . srcdir , src ) , err ) ) <EOL> def copy_image_files ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . images : <EOL> if self . config . epub_fix_images or self . config . epub_max_image_width : <EOL> if not Image : <EOL> self . warn ( '<STR_LIT>' ) <EOL> super ( EpubBuilder , self ) . copy_image_files ( ) <EOL> else : <EOL> self . copy_image_files_pil ( ) <EOL> else : <EOL> super ( EpubBuilder , self ) . copy_image_files ( ) <EOL> def handle_page ( self , pagename , addctx , templatename = '<STR_LIT>' , <EOL> outfilename = None , event_arg = None ) : <EOL> """<STR_LIT>""" <EOL> if pagename . startswith ( '<STR_LIT>' ) : <EOL> self . fix_genindex ( addctx [ '<STR_LIT>' ] ) <EOL> StandaloneHTMLBuilder . handle_page ( self , pagename , addctx , templatename , <EOL> outfilename , event_arg ) <EOL> def handle_finish ( self ) : <EOL> """<STR_LIT>""" <EOL> self . get_toc ( ) <EOL> self . build_mimetype ( self . outdir , '<STR_LIT>' ) <EOL> self . build_container ( self . outdir , '<STR_LIT>' ) <EOL> self . build_content ( self . outdir , '<STR_LIT>' ) <EOL> self . build_toc ( self . outdir , '<STR_LIT>' ) <EOL> self . build_epub ( self . outdir , self . config . epub_basename + '<STR_LIT>' ) <EOL> def build_mimetype ( self , outdir , outname ) : <EOL> """<STR_LIT>""" <EOL> self . info ( '<STR_LIT>' % outname ) <EOL> f = codecs . open ( path . join ( outdir , outname ) , '<STR_LIT:w>' , '<STR_LIT:utf-8>' ) <EOL> try : <EOL> f . write ( self . mimetype_template ) <EOL> finally : <EOL> f . close ( ) <EOL> def build_container ( self , outdir , outname ) : <EOL> """<STR_LIT>""" <EOL> self . info ( '<STR_LIT>' % outname ) <EOL> fn = path . join ( outdir , outname ) <EOL> try : <EOL> os . mkdir ( path . dirname ( fn ) ) <EOL> except OSError as err : <EOL> if err . errno != EEXIST : <EOL> raise <EOL> f = codecs . open ( path . join ( outdir , outname ) , '<STR_LIT:w>' , '<STR_LIT:utf-8>' ) <EOL> try : <EOL> f . write ( self . container_template ) <EOL> finally : <EOL> f . close ( ) <EOL> def content_metadata ( self , files , spine , guide ) : <EOL> """<STR_LIT>""" <EOL> metadata = { } <EOL> metadata [ '<STR_LIT:title>' ] = self . esc ( self . config . epub_title ) <EOL> metadata [ '<STR_LIT>' ] = self . esc ( self . config . epub_author ) <EOL> metadata [ '<STR_LIT>' ] = self . esc ( self . config . epub_uid ) <EOL> metadata [ '<STR_LIT>' ] = self . esc ( self . config . epub_language ) <EOL> metadata [ '<STR_LIT>' ] = self . esc ( self . config . epub_publisher ) <EOL> metadata [ '<STR_LIT>' ] = self . esc ( self . config . epub_copyright ) <EOL> metadata [ '<STR_LIT>' ] = self . esc ( self . config . epub_scheme ) <EOL> metadata [ '<STR_LIT:id>' ] = self . esc ( self . config . epub_identifier ) <EOL> metadata [ '<STR_LIT:date>' ] = self . esc ( format_date ( '<STR_LIT>' , language = self . config . language , <EOL> warn = self . warn ) ) <EOL> metadata [ '<STR_LIT>' ] = files <EOL> metadata [ '<STR_LIT>' ] = spine <EOL> metadata [ '<STR_LIT>' ] = guide <EOL> return metadata <EOL> def build_content ( self , outdir , outname ) : <EOL> """<STR_LIT>""" <EOL> self . info ( '<STR_LIT>' % outname ) <EOL> if not outdir . endswith ( os . sep ) : <EOL> outdir += os . sep <EOL> olen = len ( outdir ) <EOL> projectfiles = [ ] <EOL> self . files = [ ] <EOL> self . ignored_files = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> self . config . epub_basename + '<STR_LIT>' ] + self . config . epub_exclude_files <EOL> for root , dirs , files in os . walk ( outdir ) : <EOL> for fn in files : <EOL> filename = path . join ( root , fn ) [ olen : ] <EOL> if filename in self . ignored_files : <EOL> continue <EOL> ext = path . splitext ( filename ) [ - <NUM_LIT:1> ] <EOL> if ext not in self . media_types : <EOL> if ext not in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> self . warn ( '<STR_LIT>' % filename ) <EOL> continue <EOL> filename = filename . replace ( os . sep , '<STR_LIT:/>' ) <EOL> projectfiles . append ( self . file_template % { <EOL> '<STR_LIT>' : self . esc ( filename ) , <EOL> '<STR_LIT:id>' : self . esc ( self . make_id ( filename ) ) , <EOL> '<STR_LIT>' : self . esc ( self . media_types [ ext ] ) <EOL> } ) <EOL> self . files . append ( filename ) <EOL> spine = [ ] <EOL> for item in self . refnodes : <EOL> if '<STR_LIT:#>' in item [ '<STR_LIT>' ] : <EOL> continue <EOL> if item [ '<STR_LIT>' ] in self . ignored_files : <EOL> continue <EOL> spine . append ( self . spine_template % { <EOL> '<STR_LIT>' : self . esc ( self . make_id ( item [ '<STR_LIT>' ] ) ) <EOL> } ) <EOL> for info in self . domain_indices : <EOL> spine . append ( self . spine_template % { <EOL> '<STR_LIT>' : self . esc ( self . make_id ( info [ <NUM_LIT:0> ] + self . out_suffix ) ) <EOL> } ) <EOL> if self . get_builder_config ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> spine . append ( self . spine_template % { <EOL> '<STR_LIT>' : self . esc ( self . make_id ( '<STR_LIT>' + self . out_suffix ) ) <EOL> } ) <EOL> content_tmpl = self . content_template <EOL> html_tmpl = None <EOL> if self . config . epub_cover : <EOL> image , html_tmpl = self . config . epub_cover <EOL> image = image . replace ( os . sep , '<STR_LIT:/>' ) <EOL> mpos = content_tmpl . rfind ( '<STR_LIT>' ) <EOL> cpos = content_tmpl . rfind ( '<STR_LIT:\n>' , <NUM_LIT:0> , mpos ) + <NUM_LIT:1> <EOL> content_tmpl = content_tmpl [ : cpos ] + COVER_TEMPLATE % { '<STR_LIT>' : self . esc ( self . make_id ( image ) ) } + content_tmpl [ cpos : ] <EOL> if html_tmpl : <EOL> spine . insert ( <NUM_LIT:0> , self . spine_template % { <EOL> '<STR_LIT>' : self . esc ( self . make_id ( self . coverpage_name ) ) } ) <EOL> if self . coverpage_name not in self . files : <EOL> ext = path . splitext ( self . coverpage_name ) [ - <NUM_LIT:1> ] <EOL> self . files . append ( self . coverpage_name ) <EOL> projectfiles . append ( self . file_template % { <EOL> '<STR_LIT>' : self . esc ( self . coverpage_name ) , <EOL> '<STR_LIT:id>' : self . esc ( self . make_id ( self . coverpage_name ) ) , <EOL> '<STR_LIT>' : self . esc ( self . media_types [ ext ] ) <EOL> } ) <EOL> ctx = { '<STR_LIT:image>' : self . esc ( image ) , '<STR_LIT:title>' : self . config . project } <EOL> self . handle_page ( <EOL> path . splitext ( self . coverpage_name ) [ <NUM_LIT:0> ] , ctx , html_tmpl ) <EOL> guide = [ ] <EOL> auto_add_cover = True <EOL> auto_add_toc = True <EOL> if self . config . epub_guide : <EOL> for type , uri , title in self . config . epub_guide : <EOL> file = uri . split ( '<STR_LIT:#>' ) [ <NUM_LIT:0> ] <EOL> if file not in self . files : <EOL> self . files . append ( file ) <EOL> if type == '<STR_LIT>' : <EOL> auto_add_cover = False <EOL> if type == '<STR_LIT>' : <EOL> auto_add_toc = False <EOL> guide . append ( self . guide_template % { <EOL> '<STR_LIT:type>' : self . esc ( type ) , <EOL> '<STR_LIT:title>' : self . esc ( title ) , <EOL> '<STR_LIT>' : self . esc ( uri ) <EOL> } ) <EOL> if auto_add_cover and html_tmpl : <EOL> guide . append ( self . guide_template % { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT:title>' : self . guide_titles [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : self . esc ( self . coverpage_name ) <EOL> } ) <EOL> if auto_add_toc and self . refnodes : <EOL> guide . append ( self . guide_template % { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT:title>' : self . guide_titles [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : self . esc ( self . refnodes [ <NUM_LIT:0> ] [ '<STR_LIT>' ] ) <EOL> } ) <EOL> projectfiles = '<STR_LIT:\n>' . join ( projectfiles ) <EOL> spine = '<STR_LIT:\n>' . join ( spine ) <EOL> guide = '<STR_LIT:\n>' . join ( guide ) <EOL> f = codecs . open ( path . join ( outdir , outname ) , '<STR_LIT:w>' , '<STR_LIT:utf-8>' ) <EOL> try : <EOL> f . write ( content_tmpl % <EOL> self . content_metadata ( projectfiles , spine , guide ) ) <EOL> finally : <EOL> f . close ( ) <EOL> def new_navpoint ( self , node , level , incr = True ) : <EOL> """<STR_LIT>""" <EOL> if incr : <EOL> self . playorder += <NUM_LIT:1> <EOL> self . tocid += <NUM_LIT:1> <EOL> node [ '<STR_LIT>' ] = self . navpoint_indent * level <EOL> node [ '<STR_LIT>' ] = self . esc ( self . node_navpoint_template % self . tocid ) <EOL> node [ '<STR_LIT>' ] = self . playorder <EOL> return self . navpoint_template % node <EOL> def insert_subnav ( self , node , subnav ) : <EOL> """<STR_LIT>""" <EOL> nlist = node . rsplit ( '<STR_LIT:\n>' , <NUM_LIT:1> ) <EOL> nlist . insert ( - <NUM_LIT:1> , subnav ) <EOL> return '<STR_LIT:\n>' . join ( nlist ) <EOL> def build_navpoints ( self , nodes ) : <EOL> """<STR_LIT>""" <EOL> navstack = [ ] <EOL> navlist = [ ] <EOL> level = <NUM_LIT:1> <EOL> lastnode = None <EOL> for node in nodes : <EOL> if not node [ '<STR_LIT:text>' ] : <EOL> continue <EOL> file = node [ '<STR_LIT>' ] . split ( '<STR_LIT:#>' ) [ <NUM_LIT:0> ] <EOL> if file in self . ignored_files : <EOL> continue <EOL> if node [ '<STR_LIT>' ] > self . config . epub_tocdepth : <EOL> continue <EOL> if node [ '<STR_LIT>' ] == level : <EOL> navlist . append ( self . new_navpoint ( node , level ) ) <EOL> elif node [ '<STR_LIT>' ] == level + <NUM_LIT:1> : <EOL> navstack . append ( navlist ) <EOL> navlist = [ ] <EOL> level += <NUM_LIT:1> <EOL> if lastnode and self . config . epub_tocdup : <EOL> navlist . append ( self . new_navpoint ( lastnode , level , False ) ) <EOL> navlist . append ( self . new_navpoint ( node , level ) ) <EOL> else : <EOL> while node [ '<STR_LIT>' ] < level : <EOL> subnav = '<STR_LIT:\n>' . join ( navlist ) <EOL> navlist = navstack . pop ( ) <EOL> navlist [ - <NUM_LIT:1> ] = self . insert_subnav ( navlist [ - <NUM_LIT:1> ] , subnav ) <EOL> level -= <NUM_LIT:1> <EOL> navlist . append ( self . new_navpoint ( node , level ) ) <EOL> lastnode = node <EOL> while level != <NUM_LIT:1> : <EOL> subnav = '<STR_LIT:\n>' . join ( navlist ) <EOL> navlist = navstack . pop ( ) <EOL> navlist [ - <NUM_LIT:1> ] = self . insert_subnav ( navlist [ - <NUM_LIT:1> ] , subnav ) <EOL> level -= <NUM_LIT:1> <EOL> return '<STR_LIT:\n>' . join ( navlist ) <EOL> def toc_metadata ( self , level , navpoints ) : <EOL> """<STR_LIT>""" <EOL> metadata = { } <EOL> metadata [ '<STR_LIT>' ] = self . config . epub_uid <EOL> metadata [ '<STR_LIT:title>' ] = self . config . epub_title <EOL> metadata [ '<STR_LIT>' ] = level <EOL> metadata [ '<STR_LIT>' ] = navpoints <EOL> return metadata <EOL> def build_toc ( self , outdir , outname ) : <EOL> """<STR_LIT>""" <EOL> self . info ( '<STR_LIT>' % outname ) <EOL> if self . config . epub_tocscope == '<STR_LIT:default>' : <EOL> doctree = self . env . get_and_resolve_doctree ( self . config . master_doc , <EOL> self , prune_toctrees = False , <EOL> includehidden = False ) <EOL> refnodes = self . get_refnodes ( doctree , [ ] ) <EOL> self . toc_add_files ( refnodes ) <EOL> else : <EOL> refnodes = self . refnodes <EOL> navpoints = self . build_navpoints ( refnodes ) <EOL> level = max ( item [ '<STR_LIT>' ] for item in self . refnodes ) <EOL> level = min ( level , self . config . epub_tocdepth ) <EOL> f = codecs . open ( path . join ( outdir , outname ) , '<STR_LIT:w>' , '<STR_LIT:utf-8>' ) <EOL> try : <EOL> f . write ( self . toc_template % self . toc_metadata ( level , navpoints ) ) <EOL> finally : <EOL> f . close ( ) <EOL> def build_epub ( self , outdir , outname ) : <EOL> """<STR_LIT>""" <EOL> self . info ( '<STR_LIT>' % outname ) <EOL> projectfiles = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] + self . files <EOL> epub = zipfile . ZipFile ( path . join ( outdir , outname ) , '<STR_LIT:w>' , <EOL> zipfile . ZIP_DEFLATED ) <EOL> epub . write ( path . join ( outdir , '<STR_LIT>' ) , '<STR_LIT>' , <EOL> zipfile . ZIP_STORED ) <EOL> for file in projectfiles : <EOL> fp = path . join ( outdir , file ) <EOL> epub . write ( fp , file , zipfile . ZIP_DEFLATED ) <EOL> epub . close ( ) </s>
