# Export documents to other formats.

Literate programs can be translated into many formats. Commonly markup langauges focus on translation to other markup languages, we add an extra ability to convert markup to source code.

    import pidgy, pathlib, typing, textwrap, IPython
    try: from . import util
    except: import util

We can reuse existing nbconvert machinery if we expand every file to a notebook.

    def file_to_nb(file: pathlib.Path) -> "nbformat.NotebookNode":
        import nbformat
        if file.suffix in {'.md', '.markdown'}:
            return nbformat.v4.new_notebook(cells=[nbformat.v4.new_code_cell(file.read_text())])
        return nbformat.reads(file.read_text(), 4)

A notebook can also be flattened.

    def flattennb(nb: typing.Union[str, "nbformat.NotebookNode"]):
        if isinstance(nb, str): return nb
        return [textwrap.indent(''.join(x.source), x.cell_type != 'code' and '# ' or '') for x in nb.cells]

    def to_markup(input: typing.Union[str, "nbformat.NotebookNode"], exporter: "nbconvert.Exporter") -> str:
        return exporter.from_notebook_node(input)[0]

    def to_python(input, tangle = pidgy.tangle.pidgyManager()):
        import black, isort
        code = pidgy.loader.tangle(flattennb(input))
        code = isort.SortImports(file_contents=code).output
        code = black.format_str(code, mode=black.FileMode(line_length=100))
        return code

    def convert(*files, to: {'python', 'markdown'}, write: bool=False):
        import nbconvert
        exporter = nbconvert.get_exporter(to)()
        for file in util.yield_files(files):
            nb = file_to_nb(file)
            if to =='python':
                body = '\n'.join(to_python(''.join(getattr(x, 'source', []))) for x in nb.cells)
            else:
                body = to_markup(nb, exporter)
            if write:
                new = pathlib.Path(file).with_suffix(dict(python='.py', markdown='.md')[to])
                new.write_text(body)
                __import__('click').echo(F"{new} created.")
            else:
                __import__('click').echo(body)

https://stackoverflow.com/questions/34643620/how-can-i-split-my-click-commands-each-with-a-set-of-sub-commands-into-multipl
