1 import sys
, os
, re
, logging
3 # Languages mapping as used by markdown/pandoc
4 shortname2language
= dict(
18 def read(text
, argv
=sys
.argv
[2:]):
19 lines
= text
.splitlines()
20 # First read all include statements
21 for i
in range(len(lines
)):
22 if lines
[i
].startswith('#include "'):
23 filename
= lines
[i
].split('"')[1]
24 with open(filename
, 'r') as f
:
25 include_text
= f
.read()
26 lines
[i
] = include_text
27 text
= '\n'.join(lines
)
28 logging
.info('******* text after include:\n{}'.format(text
))
33 key
, value
= arg
.split('=')
34 mako_kwargs
[key
] = value
40 print('Cannot import mako - mako is not run')
44 from mako
.template
import Template
45 from mako
.lookup
import TemplateLookup
46 lookup
= TemplateLookup(directories
=[os
.curdir
])
47 text
= text
.encode('utf-8')
48 temp
= Template(text
=text
, lookup
=lookup
, strict_undefined
=True)
49 logging
.info('******* mako_kwargs: {}'.format(str(mako_kwargs
)))
50 text
= temp
.render(**mako_kwargs
)
52 logging
.info('******* text after mako:\n{}'.format(text
))
55 lines
= text
.splitlines()
57 inside
= None # indicates which type of cell we are inside
58 fullname
= None # full language name in code cells
60 if line
.startswith('-----'):
61 # New cell, what type?
62 m
= re
.search(r
'-----([a-z0-9-]+)?', line
)
64 shortname
= m
.group(1)
66 # Check if code is to be typeset as static
67 # Markdown code (e.g., shortname=py-t)
68 logging
.info('******* found shortname {}'
70 astext
= shortname
[-2:] == '-t'
71 logging
.info('******* cell: astext={} shortname={}'
72 .format(astext
, shortname
))
75 shortname
= shortname
[:-2]
77 cells
.append(['markdown', 'code', ['\n']])
78 cells
[-1][2].append('```%s\n' % fullname
)
81 if shortname
in shortname2language
:
82 fullname
= shortname2language
[shortname
]
84 cells
.append(['codecell', fullname
, []])
86 logging
.info('******* cell: markdown')
89 cells
.append(['markdown', 'text', ['\n']])
91 raise SyntaxError('Wrong syntax of cell delimiter:\n{}'
94 # Ordinary line in a cell
95 if inside
in ('markdown', 'codecell'):
96 cells
[-1][2].append(line
)
98 raise SyntaxError('line\n {}\nhas no beginning cell delimiter'
100 # Merge the lines in each cell to a string
101 for i
in range(len(cells
)):
102 if cells
[i
][0] == 'markdown' and cells
[i
][1] == 'code':
103 # Add an ending ``` of code
104 cells
[i
][2].append('```\n')
105 cells
[i
][2] = '\n'.join(cells
[i
][2])
106 # TODO: optional logging
108 logging
.info('******* cell data structure:\b%s' % pprint
.pformat(cells
))
112 """Turn cells list into valid IPython notebook code."""
113 # Use Jupyter nbformat functionality for writing the notebook
115 from nbformat
.v4
import (
116 new_code_cell
, new_markdown_cell
, new_notebook
, writes
)
119 for cell_tp
, language
, block
in cells
:
120 if cell_tp
== 'markdown':
122 new_markdown_cell(source
=block
))
123 elif cell_tp
== 'codecell':
124 nb_cells
.append(new_code_cell(source
=block
))
126 nb
= new_notebook(cells
=nb_cells
)
131 """Compile a document and its variables."""
133 filename
= sys
.argv
[1]
134 with open(filename
, 'r') as f
:
136 except (IndexError, IOError) as e
:
137 print('Usage: %s filename' % (sys
.argv
[0]))
140 cells
= read(text
, argv
=sys
.argv
[2:])
141 filestr
= write(cells
)
142 # Assuming file extension .gj (generate Jupyter); TODO: less strict
143 filename
= filename
[:-3] + '.ipynb'
144 with open(filename
, 'w') as f
:
147 if __name__
== '__main__':
151 logging
.basicConfig(format
='%(message)s', level
=logging
.DEBUG
,