docs: def single_html(epub_file_path, html_out=sys.stdout, mathjax_version=None,
                  numchapters=None, includes=None):
      """Generate complete book HTML."""
      epub = cnxepub.EPUB.from_file(epub_file_path)
      if len(epub) != 1:
          raise Exception('Expecting an epub with one book')
  
      package = epub[0]
      binder = cnxepub.adapt_package(package)
      partcount.update({}.fromkeys(parts, 0))
      partcount['book'] += 1
  
      html = cnxepub.SingleHTMLFormatter(binder, includes=includes)
  
      # Truncate binder to the first N chapters where N = numchapters.
      logger.debug('Full binder: {}'.format(cnxepub.model_to_tree(binder)))
      if numchapters is not None:
          apply_numchapters(html.get_node_type, binder, numchapters)
          logger.debug('Truncated Binder: {}'.format(
              cnxepub.model_to_tree(binder)))
  
      # Add mathjax to the page.
      if mathjax_version:
          etree.SubElement(
              html.head,
              'script',
              src=MATHJAX_URL.format(mathjax_version=mathjax_version))
  
      print(str(html), file=html_out)
      if hasattr(html_out, 'name'):
          # html_out is a file, close after writing
          html_out.close()