Created
February 2, 2017 15:00
-
-
Save bgrenet/060ad8cdd471f5f0e776688feff837b7 to your computer and use it in GitHub Desktop.
(Extremely basic) Python script to create jupyter notebooks from markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
############################################################################ | |
# # | |
# (Extremely basic) Python script to create jupyter notebook from markdown # | |
# Bruno Grenet, 02.02.2017 # | |
# License: Public Domain # | |
# # | |
############################################################################ | |
# Input format: | |
# ------------ | |
# Code in fenced blocks (delimited by "```" or "~~~") is put into code cells | |
# in the notebook. The rest is put in markdown cells. In particular, indented | |
# code blocks are put into markdown cells. | |
import re, sys, os, getopt | |
begincode = """ { | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
""" | |
beginmd = """ { | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
""" | |
endjson = """ ], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.5.2" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
}""" | |
def process(line): | |
s = line[:-1] | |
s = s.replace('\\', '\\\\') | |
s = s.replace('"', '\\"') | |
return ' "' + s + '\\n"' | |
def md2ipynb(inputfile, outputfile): | |
if not os.path.isfile(inputfile): | |
print("{} is not a valid input file.".format(inputfile)) | |
return 1 | |
if os.path.exists(outputfile): | |
if not os.path.isfile(outputfile): | |
print("{} already exists and is not a file.".format(outputfile)) | |
return 1 | |
answer = input("The file {} already exists. Overwrite? [Y/n] ".format(outputfile)) | |
if answer in ['n', 'N', 'no', 'NO', 'No']: | |
return 0 | |
f = open(inputfile, 'r') | |
o = open(outputfile, 'w') | |
md = False | |
code = False | |
first = True | |
first_of_code = False | |
width = 0 | |
codex = "^[~`]{3,}" | |
endblock = '\n ]\n }' | |
o.write('{\n "cells": [\n') | |
for line in f: | |
m = re.search(codex, line) | |
if m is not None: | |
w = len(m.group(0)) | |
if code and w >= width: | |
o.write(endblock) | |
code = False | |
elif code: | |
o.write(',\n') | |
o.write(process(line)) | |
else: | |
if md: | |
o.write(endblock) | |
o.write(',\n') | |
md = False | |
o.write(begincode) | |
code = True | |
code_width = w | |
first_of_code = True | |
else: | |
if not (code or md): | |
if not first: | |
o.write(',\n') | |
o.write(beginmd) | |
md = True | |
else: | |
if first_of_code: | |
first_of_code = False | |
else: | |
o.write(',\n') | |
o.write(process(line)) | |
first = False | |
if md or code: | |
o.write(endblock) | |
md = code = False | |
o.write(endjson) | |
f.close() | |
o.close() | |
return 0 | |
def main(): | |
usage = "{} [-o outfile|--output=outfile] inputfile".format(sys.argv[0]) | |
try: | |
opts, args = getopt.getopt(sys.argv[1:], "ho:", ["help", "output="]) | |
except getopt.GetoptError as err: | |
print(err) | |
print(usage) | |
sys.exit(2) | |
outputfile = '' | |
for o, a in opts: | |
if o in ('-h', '--help'): | |
print(usage) | |
sys.exit() | |
elif o in ('-o', '--output'): | |
outputfile = a | |
else: | |
print(usage) | |
sys.exit(1) | |
if len(args) != 1: | |
print(usage) | |
sys.exit(1) | |
inputfile = args[0] | |
if outputfile == '': | |
outputfile = os.path.splitext(inputfile)[0] + '.ipynb' | |
ret = md2ipynb(inputfile, outputfile) | |
if ret == 0: | |
print("{} converted into {} successfully".format(inputfile, outputfile)) | |
sys.exit() | |
else: | |
print("Conversion failed") | |
sys.exit(1) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment