def write_example(src_name, src_dir, rst_dir, cfg): """Write rst file from a given python example. Parameters ---------- src_name : str Name of example file. src_dir : 'str' Source directory for python examples. rst_dir : 'str' Destination directory for rst files generated from python examples. cfg : config object Sphinx config object created by Sphinx. """ last_dir = src_dir.psplit()[-1] # to avoid leading . in file names, and wrong names in links if last_dir == '.' or last_dir == 'examples': last_dir = Path('') else: last_dir += '_' src_path = src_dir.pjoin(src_name) example_file = rst_dir.pjoin(src_name) shutil.copyfile(src_path, example_file) image_dir = rst_dir.pjoin('images') thumb_dir = image_dir.pjoin('thumb') notebook_dir = rst_dir.pjoin('notebook') image_dir.makedirs() thumb_dir.makedirs() notebook_dir.makedirs() base_image_name = os.path.splitext(src_name)[0] image_path = image_dir.pjoin(base_image_name + '_{0}.png') basename, py_ext = os.path.splitext(src_name) rst_path = rst_dir.pjoin(basename + cfg.source_suffix_str) notebook_path = notebook_dir.pjoin(basename + '.ipynb') if _plots_are_current(src_path, image_path) and rst_path.exists and \ notebook_path.exists: return print('plot2rst: %s' % basename) blocks = split_code_and_text_blocks(example_file) if blocks[0][2].startswith('#!'): blocks.pop(0) # don't add shebang line to rst file. rst_link = '.. _example_%s:\n\n' % (last_dir + src_name) figure_list, rst = process_blocks(blocks, src_path, image_path, cfg) has_inline_plots = any(cfg.plot2rst_plot_tag in b[2] for b in blocks) if has_inline_plots: example_rst = ''.join([rst_link, rst]) else: # print first block of text, display all plots, then display code. first_text_block = [b for b in blocks if b[0] == 'text'][0] label, (start, end), content = first_text_block figure_list = save_all_figures(image_path) rst_blocks = [IMAGE_TEMPLATE % f.lstrip('/') for f in figure_list] example_rst = rst_link example_rst += eval(content) example_rst += ''.join(rst_blocks) code_info = dict(src_name=src_name, code_start=end) example_rst += LITERALINCLUDE.format(**code_info) example_rst += CODE_LINK.format(src_name) ipnotebook_name = src_name.replace('.py', '.ipynb') ipnotebook_name = './notebook/' + ipnotebook_name example_rst += NOTEBOOK_LINK.format(ipnotebook_name) with open(rst_path, 'w') as f: f.write(example_rst) thumb_path = thumb_dir.pjoin(src_name[:-3] + '.png') first_image_file = image_dir.pjoin(figure_list[0].lstrip('/')) if first_image_file.exists: first_image = io.imread(first_image_file) save_thumbnail(first_image, thumb_path, cfg.plot2rst_thumb_shape) if not thumb_path.exists: if cfg.plot2rst_default_thumb is None: print("WARNING: No plots found and default thumbnail not defined.") print("Specify 'plot2rst_default_thumb' in Sphinx config file.") else: shutil.copy(cfg.plot2rst_default_thumb, thumb_path) # Export example to IPython notebook nb = Notebook() # Add sphinx roles to the examples, otherwise docutils # cannot compile the ReST for the notebook sphinx_roles = PythonDomain.roles.keys() preamble = '\n'.join(f'.. role:: py:{role}(literal)\n' for role in sphinx_roles) # Grab all references to inject them in cells where needed ref_regexp = re.compile('\n(\\.\\. \\[(\\d+)\\].*(?:\n[ ]{7,8}.*)+)') math_role_regexp = re.compile(':math:`(.*?)`') text = '\n'.join((content for (cell_type, _, content) in blocks if cell_type != 'code')) references = re.findall(ref_regexp, text) for (cell_type, _, content) in blocks: if cell_type == 'code': nb.add_cell(content, cell_type='code') else: if content.startswith('r'): content = content.replace('r"""', '') escaped = False else: content = content.replace('"""', '') escaped = True if not escaped: content = content.replace("\\", "\\\\") content = content.replace('.. seealso::', '**See also:**') content = re.sub(math_role_regexp, r'$\1$', content) # Remove math directive when rendering notebooks # until we implement a smarter way of capturing and replacing # its content content = content.replace('.. math::', '') if not content.strip(): continue content = (preamble + content).rstrip('\n') content = '\n'.join([line for line in content.split('\n') if not line.startswith('.. image')]) # Remove reference links until we can figure out a better way to # preserve them for (reference, ref_id) in references: ref_tag = f'[{ref_id}]_' if ref_tag in content: content = content.replace(ref_tag, ref_tag[:-1]) html = publish_parts(content, writer_name='html')['html_body'] nb.add_cell(html, cell_type='markdown') with open(notebook_path, 'w') as f: f.write(nb.json())
def write_example(src_name, src_dir, rst_dir, cfg): """Write rst file from a given python example. Parameters ---------- src_name : str Name of example file. src_dir : 'str' Source directory for python examples. rst_dir : 'str' Destination directory for rst files generated from python examples. cfg : config object Sphinx config object created by Sphinx. """ last_dir = src_dir.psplit()[-1] # to avoid leading . in file names, and wrong names in links if last_dir == '.' or last_dir == 'examples': last_dir = Path('') else: last_dir += '_' src_path = src_dir.pjoin(src_name) example_file = rst_dir.pjoin(src_name) shutil.copyfile(src_path, example_file) image_dir = rst_dir.pjoin('images') thumb_dir = image_dir.pjoin('thumb') notebook_dir = rst_dir.pjoin('notebook') image_dir.makedirs() thumb_dir.makedirs() notebook_dir.makedirs() base_image_name = os.path.splitext(src_name)[0] image_path = image_dir.pjoin(base_image_name + '_{0}.png') basename, py_ext = os.path.splitext(src_name) rst_path = rst_dir.pjoin(basename + cfg.source_suffix_str) notebook_path = notebook_dir.pjoin(basename + '.ipynb') if _plots_are_current(src_path, image_path) and rst_path.exists and \ notebook_path.exists: return print('plot2rst: %s' % basename) blocks = split_code_and_text_blocks(example_file) if blocks[0][2].startswith('#!'): blocks.pop(0) # don't add shebang line to rst file. rst_link = '.. _example_%s:\n\n' % (last_dir + src_name) figure_list, rst = process_blocks(blocks, src_path, image_path, cfg) has_inline_plots = any(cfg.plot2rst_plot_tag in b[2] for b in blocks) if has_inline_plots: example_rst = ''.join([rst_link, rst]) else: # print first block of text, display all plots, then display code. first_text_block = [b for b in blocks if b[0] == 'text'][0] label, (start, end), content = first_text_block figure_list = save_all_figures(image_path) rst_blocks = [IMAGE_TEMPLATE % f.lstrip('/') for f in figure_list] example_rst = rst_link example_rst += eval(content) example_rst += ''.join(rst_blocks) code_info = dict(src_name=src_name, code_start=end) example_rst += LITERALINCLUDE.format(**code_info) example_rst += CODE_LINK.format(src_name) ipnotebook_name = src_name.replace('.py', '.ipynb') ipnotebook_name = './notebook/' + ipnotebook_name example_rst += NOTEBOOK_LINK.format(ipnotebook_name) with open(rst_path, 'w') as f: f.write(example_rst) thumb_path = thumb_dir.pjoin(src_name[:-3] + '.png') first_image_file = image_dir.pjoin(figure_list[0].lstrip('/')) if first_image_file.exists: first_image = io.imread(first_image_file) save_thumbnail(first_image, thumb_path, cfg.plot2rst_thumb_shape) if not thumb_path.exists: if cfg.plot2rst_default_thumb is None: print("WARNING: No plots found and default thumbnail not defined.") print("Specify 'plot2rst_default_thumb' in Sphinx config file.") else: shutil.copy(cfg.plot2rst_default_thumb, thumb_path) # Export example to IPython notebook nb = Notebook() # Add sphinx roles to the examples, otherwise docutils # cannot compile the ReST for the notebook sphinx_roles = PythonDomain.roles.keys() preamble = '\n'.join('.. role:: py:{0}(literal)\n'.format(role) for role in sphinx_roles) # Grab all references to inject them in cells where needed ref_regexp = re.compile('\n(\.\. \[(\d+)\].*(?:\n[ ]{7,8}.*)+)') math_role_regexp = re.compile(':math:`(.*?)`') text = '\n'.join((content for (cell_type, _, content) in blocks if cell_type != 'code')) references = re.findall(ref_regexp, text) for (cell_type, _, content) in blocks: if cell_type == 'code': nb.add_cell(content, cell_type='code') else: if content.startswith('r'): content = content.replace('r"""', '') escaped = False else: content = content.replace('"""', '') escaped = True if not escaped: content = content.replace("\\", "\\\\") content = content.replace('.. seealso::', '**See also:**') content = re.sub(math_role_regexp, r'$\1$', content) # Remove math directive when rendering notebooks # until we implement a smarter way of capturing and replacing # its content content = content.replace('.. math::', '') if not content.strip(): continue content = (preamble + content).rstrip('\n') content = '\n'.join([line for line in content.split('\n') if not line.startswith('.. image')]) # Remove reference links until we can figure out a better way to # preserve them for (reference, ref_id) in references: ref_tag = '[{0}]_'.format(ref_id) if ref_tag in content: content = content.replace(ref_tag, ref_tag[:-1]) html = publish_parts(content, writer_name='html')['html_body'] nb.add_cell(html, cell_type='markdown') with open(notebook_path, 'w') as f: f.write(nb.json())