Giter VIP home page Giter VIP logo

ipymd's Introduction

Build Status Coverage Status

Replace .ipynb with .md in the IPython Notebook

The goal of ipymd is to replace .ipynb notebook files like:

{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "Here is some Python code:"
   ]
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world!\n"
     ]
    }
   ],
   "source": [
    "print(\"Hello world!\")"
   ]
  }
  ...
  ]
}

with:

Here is some Python code:

```python
>>> print("Hello world!")
Hello world!
```

The JSON .ipynb are removed from the equation, and the conversion happens on the fly. The IPython Notebook becomes an interactive Markdown text editor!

A drawback is that you lose prompt numbers and images (for now).

This is useful when you write technical documents, blog posts, books, etc.

image

Installation

  1. Install ipymd:

    To install the latest release version:

    pip install ipymd

    Alternatively, to install the development version:

    pip install git+https://github.com/rossant/ipymd
  2. Optional: To interact with .ipynb files:

    pip install jupyter ipython

    To interact with .odt files:

    pip install git+https://github.com/eea/odfpy
  3. Open your jupyter_notebook_config.py. Here's how to find it:

    jupyter notebook --generate-config  # generate a default config file
    jupyter --config-dir  # find out the path to the config file
    
  4. Add the following in jupyter_notebook_config.py:

    c.NotebookApp.contents_manager_class = 'ipymd.IPymdContentsManager'
  5. Now, you can open .md files in the Notebook.

Why?

IPython Notebook

Pros:

  • Excellent UI for executing code interactively and writing text

Cons:

  • .ipynb not git-friendly
  • Cannot easily edit in a text editor
  • Cannot easily edit on GitHub's web interface

Markdown

Pros:

  • Simple ASCII/Unicode format to write code and text
  • Can easily edit in a text editor
  • Can easily edit on GitHub's web interface
  • Git-friendly

Cons:

  • No UI to execute code interactively

ipymd

All pros of IPython Notebook and Markdown, no cons!

How it works

  • Write in Markdown in document.md

    • Either in a text editor (convenient when working on text)
    • Or in the Notebook (convenient when writing code examples)
  • Markdown cells, code cells and (optionally) notebook metadata are saved in the file

  • Collaborators can work on the Markdown document using GitHub's web interface.

  • By convention, a notebook code cell is equivalent to a Markdown code block with explicit python syntax highlighting:

    >>> print("Hello world")
    Hello world
    
  • Notebook metadata can be specified in YAML inside Jekyll-style front-matter dashes at the beginning of a document:

    ---
    kernelspec:
      name: some-non-native-kernel
    ---
    
    First cell content

    Native kernel metadata will be elided by default: non-python kernels haven't been tested yet, but support is planned.

  • Cell metadata is specified with YAML stream documents with dashes and periods, such as to create slides:

    # Previous slide
    
    ---
    slideshow:
      slide_type: slide
    ...
    
    # Some Slide Content

    NOTE: You probably shouldn't use --- to mean an <hr/>: *** could be a suitable substitute.

  • Null metadata (i.e. splitting a markdown cell) can be created with just three dashes. This is useful when adding slideshow notes or skipped cells.

    A cell
    
    ---
    
    Another cell
  • The back-and-forth conversion is not strictly the identity function:

    • Extra line breaks in Markdown are discarded
    • Text output and standard output are combined into a single text output (stdout lines first, output lines last)

Caveats

WARNING: use this library at your own risks, backup your data, and version-control your notebooks and Markdown files!

  • Renaming doesn't work yet (issue #4)
  • New notebook doesn't work yet (issue #5)
  • Only nbformat v4 is supported currently (IPython 3.0)

Formats

ipymd uses a modular architecture that lets you define new formats. The following formats are currently implemented, and can be selected by modifying ~/.ipython/profile_<whichever>/ipython_notebook_config.py:

  • IPython notebook (.ipynb)
  • Markdown (.md)
    • c.IPymdContentsManager.format = 'markdown'
  • O'Reilly Atlas (.md with special HTML tags for code and mathematical equations)
    • c.IPymdContentsManager.format = 'atlas'
  • Python (.py): code cells are delimited by double line breaks. Markdown cells = Python comments. [TODO: this doesn't work well, see #28 and #31]
  • Opendocument (.odt). You need to install the development version of odfpy.

You can convert from any supported format to any supported format. This works by converting to an intermediate format that is basically a list of notebook cells.

ipymd cells

An ipymd cell is a Python dictionary with the following fields:

  • cell_type: markdown, code or notebok_metadata (if implemented)
  • input: a string with the code input (code cell only)
  • output: a string with the text output and stdout (code cell only)
  • source: a string containing Markdown markup (markdown cell only)
  • metadata: a dictionary containing cell (or notebook) metadata

Kernel Metadata

By default, notebook metadata for the native kernel (usually python2 or python3) won't be written to markdown. Since ipymd doesn't yet support other kernels, this doesn't matter much, but if you would like to pick a non-native python kernel to be interpreted as the default for ipymd, and store kernelspec and language_info for the other, you can add this to your ipython_notebook_config.py file:

  • c.IPymdContentsManager.default_kernel_name = 'python2'

Or, to always remember all notebook-level metadata:

  • c.IPymdContentsManager.verbose_metadata = True

Customize the Markdown format

You can customize the exact way the notebook is converted from/to Markdown by deriving from BaseMarkdownReader or MarkdownReader (idem with writers). Look at ipymd/formats/markdown.py.

Implement your own format

You can also implement your own format by following these instructions:

  • Create a MyFormatReader class that implements:

    • self.read(contents): yields ipymd cells from a contents string
  • Create a MyFormatWriter class that implements:

    • self.write(cell): append an ipymd cell
      • (optional) self.write_notebook_metadata(cell): write the notebook metadata dictionary
    • self.contents: return the contents as a string
  • To activate this format, call this at Notebook launch time (not in a kernel!), perhaps in your ipython_notebook_config.py:

  from ipymd import format_manager
  format_manager().register(
      name='my_format',
      reader=MyFormatReader,
      writer=MyFormatWriter,
      file_extension='.md',  # or anything else
      file_type='text',  # or JSON
  )
  • Now you can convert contents: ipymd.convert(contents, from_='notebook', to='my_format') or any other combination.

Contributing a new ipymd format

  • To further integrate your format in ipymd, create a ipymd/formats/my_format.py file.
  • Put your reader and writer class in there, as well as a top-level variable:
  MY_FORMAT = dict(
      reader=MyFormatReader,
      writer=MyFormatWriter,
      file_extension='.md',
      file_type='text',
  )
  • In setup.py, add this to entry_points:
      ...
      entry_points={
          'ipymd.format': [
              ...
              'my_format=myformat:MY_FORMAT',
              ...
          ]
      }

Note that the entry_point name will be used by default. you may override it, if you like, but Don't Repeat Yourself.

  • Add some unit tests in ipymd/formats/tests.
  • Propose a PR!

Look at the existing format implementations for more details.

Packaging a format

  • If you want to be able to redistribute your format without adding it to ipymd proper (i.e. in-house or experimental), implement all your code in a real python module.
  • Someplace easy to import, e.g. myformat.py or myformat/__init__.py, add:
  MY_FORMAT = dict(
      reader=MyFormatReader,
      writer=MyFormatWriter,
      file_extension='.md',  # or anything else
      file_type='text',  # or JSON
  )

and this to your setup.py:

  ...
      entry_points={
          'ipymd.format': [
              'my_format=myformat:MY_FORMAT',
              ],
          },
  ...
  • Publish on pypi!
  • Your users will now be able to pip install myformat, then configure their Notebook to use your format with the name my_format.

ipymd's People

Contributors

bollwyvl avatar dmhowcroft avatar jdanbrown avatar rafalskolasinski avatar rossant avatar sanketdg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ipymd's Issues

unicode in python output

Hi, I noticed that ipymd cannot save md file when python output contains unicode.

Following code

import sympy
from sympy.interactive import printing
printing.init_printing(use_latex='mathjax')
x,y,z = sympy.symbols('x y z')
expr = x**2 + x*y
expr

throws errors like
Error while saving file: ideas/graphs.md 'ascii' codec can't encode character u'\u22c5' in position 189: ordinal not in range(128)

Improve README

  • make it shorter
  • put the installation instructions at the beginning
  • document the CLI conversion tool

New Python format

Allows to open .py files in the notebook. Just the code is saved. By convention, unindented double line break = new cell. Option store_markdown_in_comments.

timeline for a next release?

@rossant, do you have an ETA for another release of ipymd on pypi? We're relying on some functionality in master in a couple of projects now, so we're having to pip install from master a lot. We could help with a release again if needed.

ipymd broken in IPython 4.0

jupyter notebook --NotebookApp.contents_manager_class=ipymd.IPymdContentsManager

error message:

[C 14:00:12.838 NotebookApp] Bad config encountered during initialization:
[C 14:00:12.838 NotebookApp] The 'contents_manager_class' trait of a NotebookApp 
instance must be a subclass of 'notebook.services.contents.manager.ContentsManager', 
but a value of class 'traitlets.traitlets.MetaHasTraits' 
(i.e. <class 'ipymd.core.contents_manager.IPymdContentsManager'>) 
was specified.

declaration of the class as follows:

class IPymdContentsManager(FileContentsManager, Configurable):

@Carreau @minrk any ideas?

Test the CLI tool

  • Refactor the arg parsing logic in a testable standalone function
  • Test calls to the ipymd executable

make ipymd pip-installable

Are there any plans to make ipymd pip-installable? I've been doing some experiments with this, and would like to use it for An Introduction to Applied Bioinformatics, but for convenience would either need ipymd to be pip-installable, or to package it in my project. I could help out with getting it pip-installable if that would be useful.

bug: keyerror 'markdown' on master with python 3

Hi,

I tried to use ipymd now with python3 on my laptop but I got following error after starting notebook server on the http://localhost:8888/tree

Server error: Traceback (most recent call last): File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/base/handlers.py", line 436, in wrapper result = yield gen.maybe_future(method(self, *args, **kwargs)) File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 1008, in run value = future.result() File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/concurrent.py", line 232, in result raise_exc_info(self._exc_info) File "<string>", line 3, in raise_exc_info File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 282, in wrapper yielded = next(result) File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/services/contents/handlers.py", line 126, in get path=path, type=type, format=format, content=content, File "/home/arymanus/dev3/lib/python3.4/site-packages/ipymd/core/contents_manager.py", line 86, in get file_extension = format_manager().file_extension(self.format) File "/home/arymanus/dev3/lib/python3.4/site-packages/ipymd/core/format_manager.py", line 143, in file_extension return self._formats[name]['file_extension'] KeyError: 'markdown'

terminal errors are as following

(dev3)arymanus:~> jupyter notebook
[I 15:39:44.992 NotebookApp] ipymd format markdown could not be loaded: No module named 'yaml'
[I 15:39:45.006 NotebookApp] ipymd format atlas could not be loaded: No module named 'yaml'
[I 15:39:45.012 NotebookApp] ipymd format opendocument could not be loaded: The 'odfpy' distribution was not found and is required by the application
[I 15:39:45.057 NotebookApp] Serving notebooks from local directory: /home/arymanus
[I 15:39:45.057 NotebookApp] 0 active kernels 
[I 15:39:45.058 NotebookApp] The IPython Notebook is running at: http://localhost:8888/
[I 15:39:45.058 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
Created new window in existing browser session.
[E 15:39:45.959 NotebookApp] Unhandled error in API request
    Traceback (most recent call last):
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/base/handlers.py", line 436, in wrapper
        result = yield gen.maybe_future(method(self, *args, **kwargs))
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 1008, in run
        value = future.result()
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/concurrent.py", line 232, in result
        raise_exc_info(self._exc_info)
      File "<string>", line 3, in raise_exc_info
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 282, in wrapper
        yielded = next(result)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/services/contents/handlers.py", line 126, in get
        path=path, type=type, format=format, content=content,
      File "/home/arymanus/dev3/lib/python3.4/site-packages/ipymd/core/contents_manager.py", line 86, in get
        file_extension = format_manager().file_extension(self.format)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/ipymd/core/format_manager.py", line 143, in file_extension
        return self._formats[name]['file_extension']
    KeyError: 'markdown'
[E 15:39:45.960 NotebookApp] Uncaught exception GET /api/contents?type=directory&_=1447166385733 (127.0.0.1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/api/contents?type=directory&_=1447166385733', version='HTTP/1.1', remote_ip='127.0.0.1', headers={'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest', 'Accept-Language': 'en-US,en;q=0.8', 'Connection': 'keep-alive', 'Host': 'localhost:8888', 'Referer': 'http://localhost:8888/tree', 'Accept-Encoding': 'gzip, deflate, sdch', 'Accept': 'application/json, text/javascript, */*; q=0.01'})
    Traceback (most recent call last):
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/base/handlers.py", line 436, in wrapper
        result = yield gen.maybe_future(method(self, *args, **kwargs))
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 1008, in run
        value = future.result()
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/concurrent.py", line 232, in result
        raise_exc_info(self._exc_info)
      File "<string>", line 3, in raise_exc_info
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 282, in wrapper
        yielded = next(result)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/services/contents/handlers.py", line 126, in get
        path=path, type=type, format=format, content=content,
      File "/home/arymanus/dev3/lib/python3.4/site-packages/ipymd/core/contents_manager.py", line 86, in get
        file_extension = format_manager().file_extension(self.format)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/ipymd/core/format_manager.py", line 143, in file_extension
        return self._formats[name]['file_extension']
    KeyError: 'markdown'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/web.py", line 1445, in _execute
        result = yield result
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 1008, in run
        value = future.result()
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/concurrent.py", line 232, in result
        raise_exc_info(self._exc_info)
      File "<string>", line 3, in raise_exc_info
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/gen.py", line 1014, in run
        yielded = self.gen.throw(*exc_info)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/base/handlers.py", line 454, in wrapper
        self.finish(json.dumps(reply))
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/base/handlers.py", line 375, in finish
        return super(APIHandler, self).finish(*args, **kwargs)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/web.py", line 934, in finish
        self._log()
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/web.py", line 1474, in _log
        self.application.log_request(self)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/tornado/web.py", line 1936, in log_request
        self.settings["log_function"](handler)
      File "/home/arymanus/dev3/lib/python3.4/site-packages/notebook/log.py", line 46, in log_request
        log_method(json.dumps(request.headers, indent=2))
      File "/usr/lib/python3.4/json/__init__.py", line 237, in dumps
        **kw).encode(obj)
      File "/usr/lib/python3.4/json/encoder.py", line 194, in encode
        chunks = list(chunks)
      File "/usr/lib/python3.4/json/encoder.py", line 429, in _iterencode
        o = _default(o)
      File "/usr/lib/python3.4/json/encoder.py", line 173, in default
        raise TypeError(repr(o) + " is not JSON serializable")
    TypeError: <tornado.httputil.HTTPHeaders object at 0x7f2321089668> is not JSON serializable
[E 15:39:45.962 NotebookApp] Cannot send error response after headers written

my virtualenv configuration

(dev3)arymanus:~> pip freeze
You are using pip version 6.1.1, however version 7.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
alabaster==0.7.6
appnope==0.1.0
Babel==2.1.1
backports-abc==0.4
Cython==0.23.4
decorator==4.0.4
docutils==0.12
gnureadline==6.3.3
holoviews==1.3.2
ipykernel==4.1.1
ipymd==0.1.2.dev0
ipyparallel==4.1.0
ipython==4.0.0
ipython-genutils==0.1.0
ipywidgets==4.1.1
Jinja2==2.8
jsonschema==2.5.1
jupyter==1.0.0
jupyter-client==4.1.1
jupyter-console==4.0.3
jupyter-core==4.0.6
jupyterhub==0.3.0
kwant==1.1.1.dev6+g195e424
MarkupSafe==0.23
mistune==0.7.1
mock==1.3.0
nbconvert==4.1.0
nbformat==4.0.1
nose==1.3.7
notebook==4.0.6
numpy==1.10.1
numpydoc==0.5
pamela==0.2.1
pandas==0.17.0
param==1.3.2
path.py==8.1.2
pbr==1.8.1
pexpect==4.0.1
pickleshare==0.5
ptyprocess==0.5
Pygments==2.0.2
pyreadline==2.1
python-dateutil==2.4.2
pytz==2015.7
pyzmq==15.0.0
qtconsole==4.1.0
requests==2.8.1
scipy==0.16.1
simplegeneric==0.8.1
six==1.10.0
snowballstemmer==1.2.0
Sphinx==1.3.1
sphinx-rtd-theme==0.1.9
SQLAlchemy==1.0.9
sympy==0.7.6.1
terminado==0.5
testpath==0.2
tinyarray==1.0.5.dev9+gcdf987c
tornado==4.3
traitlets==4.0.0

I will be happy to provide any more information you may need.

Usage examples?

I'm afraid I can't figure out how to use this. I have

c.NotebookApp.contents_manager_class = 'ipymd.IPymdContentsManager'

In my jupyter config. But when I open .md files, I can't compute with them. Likewise, if I start a new notebook and save it, it is still saved in ipynb format, not markdown. So clearly I'm missing either the purpose of this package and/or how to use it.

What I was looking for is a way to have jupyter create, open and close .md and .Rmd files into usable notebooks.

HTML format

Two strategies:

  • Write an HTML <-> Markdown converter, then ipymd can take care of the rest (using Beautiful Soup and/or html2text).
  • Directly write an HTML <-> ipymd_cells converter

Difficulty: detect code cells in the HTML. This will be highly document-dependent, and the user will be expected to specify how code cells should be detected

Use mainstream mistune

cc @lepture @bollwyvl

As far as I remember the changes were relatively minor. I'll give more information when I find the time to delve into the code again. It was something along the lines of "having a non-renderer Markdown parser that allows one to write callback methods that don't render anything".

Allow for optional reader or writer

  • A format could be unidirectional
  • Saving or loading in the notebook is not possible
  • An error is raised during the conversion if the reader or writer is not available

Can't import MarkdownContentsManager

Using IPython 3.0.0-rc1:

+In [1]: path.append(expanduser("~/.ipython/nbextensions/ipymd/"))
+In [2]: from ipymd import MarkdownContentsManager
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-6-cd24aac5f930> in <module>()
----> 1 from ipymd import MarkdownContentsManager

/Users/sgb/.ipython/nbextensions/ipymd/ipymd/__init__.py in <module>()
----> 1 from .nbplugins import (MarkdownContentsManager,
      2                         MarkdownOutputContentsManager,
      3                         AtlasContentsManager)

/Users/sgb/.ipython/nbextensions/ipymd/ipymd/nbplugins.py in <module>()
     13 from IPython.utils.io import atomic_writing
     14
---> 15 from .converters import nb_to_markdown, markdown_to_nb
     16
     17 class IPymdContentsManager(FileContentsManager):

/Users/sgb/.ipython/nbextensions/ipymd/ipymd/converters.py in <module>()
      7
      8 from .six import string_types
----> 9 from .htmlparser import get_html_contents
     10
     11 CODE_WRAP = {

/Users/sgb/.ipython/nbextensions/ipymd/ipymd/htmlparser.py in <module>()
      1 """Parse HTML and LaTeX equations from Atlas HTML5."""
----> 2 from html.parser import HTMLParser
      3 from html.entities import name2codepoint
      4
      5 class MyHTMLParser(HTMLParser):

ImportError: No module named parser

Any idea what I'm doing wrong?

Cell metadata

  • Provide a simple syntax to specify arbitrary block-level metadata
  • Line-level metadata is also possible, but to be processed independently by each format
  • Every format is free to interpret the metadata as they want
  • An ipymd Markdown cell has a new field metadata = {} which is just a Python dictionary

Examples of use-cases

  • Specifying a specific ODF style in a Markdown cell
  • Force rendering a code block as Markdown instead of a notebook cell
  • Skip particular code lines in a given format (better to deal with this directly in a format reader/writer)

How it works

  • Consider the body of a Markdown
  • If the first line contains ipymd-[a-zA-Z]+, it defines the cell's metadata
  • There can be several ipymd-foo or ipymd-foo=bar metadata fields on the line
  • ipymd-foo means metadata['foo'] = True
  • ipymd-foo=3 means metadata['foo'] = 3
  • If a format chooses to process some metadata, it must ensure that the information is not lost during the conversion, and it must implement two-way transformation of metadata. For example, an ODFReader must recreate the metadata from the cell's ODF style.

Add support for images

  • Support Markdown image tags
  • Support embedded images in the notebook
    • Extract images from the notebook
    • Save them to a given location, as specified by a customizable ImageManager class (for example, images/image_003.png)
    • Add a Markdown image tag

Fix README.md installation instructions for jupyter

As noted by Mobius Dumpling at http://stackoverflow.com/questions/18734739/using-ipython-notebooks-under-version-control, the README.md instructions don't work with jupyter:

Update: This solution is broken in iPython version 4, because of "The Big Split" of Jupyter from iPython. To adjust this solution to version 4, use the command jupyter notebook --generate-config to create a config file. The command jupyter --config-dir finds out which directory contains the config files. And the code snippet given by @rich should be added to the file named jupyter_notebook_config.py. The rest works as before. – mobius dumpling Oct 20 '15 at 20:55

Following these instructions worked for me

Configurable cell split

Issue raised by @bollwyvl. The question is "how to customize how cells are split during Markdown => ipynb conversion"?

There are several ways of doing it; here's one.

By default, the current behavior is kept: the smallest cells are created (i.e. one for every new line \n\n, basically), using the observation that it's easier to merge than to split cells.

Then, there is a dedicated class, for example CellMerger, that is responsible for merging consecutive cells. It implements a method to_merge(cell0, cell_1) that takes as input two consecutive ipymd cells, and returns True or False. When converting from Markdown to ipynb, this class is called at the end of the conversion. It starts from the first cell, decides whether it should be merged with the next one, does the merge if necessary, and move to the next pair of cells, until the end. (probably this should only concern Markdown cells; a code cell will never be merged with a Markdown cell!)

Returning always True means that we'll end up with as few Markdown cells as possible (a single big cell if there's no code cell).

Returning always False means that the current behavior is kept.

In the middle, we can customize how cells should be created out of Markdown text. For example, decide that two Markdown cells should be merged if none starts with a header.

The default CellMerger should implement reasonable heuristics between the two extremes.

Another thing: it may be possible to force a split with something like a *** in Markdown, but I don't think it should be mandatory (i.e. not writing any *** should not result in a single big cell for the whole document!)

Install problem

Hello Cyrille,

Thank you for this great contribution, I was looking for such a feature since a long time. :)
I am trying to install ipymb on my platform and have some difficulties.
I have ipython 3.0.0 installed
I have an anaconda installation.
I have installed ipymd
I have followed the instructions an add this line as mentionned in the documentation

c.NotebookApp.contents_manager_class = 'ipymd.IPymdContentsManager'

When I start :

ipython notebook

I have got an error message. Apparently the format and tests directory are not properly installed during the python setup.py install procedure.

I have fixed the problem by moving manually those 2 directories in my site-packages ipymd directory.

I fixed the problem while editing this issue. I post it anyhow, may be of help for other users.

A une prochaine IRL et merci encore pour cet outil prometteur :)

Bernard

Improve prompt

In addition to the existing rules, the prompt should be ... instead of >>> when the previous line starts with @ or #.

Further, all lines following a line starting with %% (cell magic) should be prompted with ....

Pandoc support

(assuming pandoc is installed on the user's computer)

Wrapping pandoc would bring support for many languages for free, using Markdown as an intermediate language (ipymd_cells <=> Markdown <=> pandoc languages), notably:

  • ReST
  • HTML
  • LaTeX
  • slides
  • ...

Support slides

  • All in Markdown
  • Document-level and cell-level metadata ( #38 )
  • Offers a hybrid UI to write slides: text editor for text and overall structure, Notebook for code
  • It would be nice to have the cell metadata being optional (see ioslides for example which looks nearly optimal in terms of ease-of-use)
  • Export to reveal.js

related to nbconvert and work done by @damianavila
ping @bollwyvl too

nbconvert

I'm wondering whether part or all of ipymd's functionality could/should be integrated in nbconvert, since there is some overlap currently.

The main features would be:

  • reverse conversion from ipynb notebooks to various formats (markdown, ODT, etc.). Round-trip conversions should leave files mostly unchanged
  • configurable input/output prompts, logic for creating ipynb cells out of standard Markdown documents, etc.

Then, ipymd could leverage nbconvert and implement:

  • support for various formats/file extensions (e.g. .md) in the Notebook
  • on-the-fly conversion when loading/saving a notebook in the Notebook interface, allowing to edit .md files directly in the Notebook with no explicit conversion

cc @Carreau @minrk

Extensible architecture for readers and writers

  • Create a formats subdirectory in ipymd.
  • Each file in this subdirectory follows this structure:
class MyReader(object):
    def read(self, contents):
        """Take some contents and yield ipymd cells."""
        # cell is a dict with 'cell_type' ('markdown'/'code'), 'input', 'output', 'source' (markdown only)
        yield cell

class MyWriter(object):
    def write(self, cell):
        """Write an ipymd cell."""

    @property
    def contents(self):
        """Return the contents."""

from ipymd import register
register('my_format', MyReader, MyWriter)
  • The 'notebook' format is a special format.

  • Configurable readers/writers: readers and writers may accept keyword arguments in their constructores

  • The library dynamically loads the files in this directory and discovers the registered formats.

  • The following conversion function is provided:

    convert(contents, from_='format_0', to='format_1',
            from_args={'arg': val}, to_args=None)

    This function instanciates a reader and writer using the given keyword arguments. It converts from the source format to ipymd cells (reader), and from ipymd cells to the target format (writer). It can also be called from the CLI.

TODO

  • Refactor markdown, atlas to follow this structure

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.