3 import sys
, os
, re
, logging
5 # Languages mapping as used by markdown/pandoc
6 shortname2language
= dict(
20 def read(text
, argv
=sys
.argv
[2:]):
21 lines
= text
.splitlines()
22 # First read all include statements
23 for i
in range(len(lines
)):
24 if lines
[i
].startswith('#include "'):
25 filename
= lines
[i
].split('"')[1]
26 with open(filename
, 'r') as f
:
27 include_text
= f
.read()
28 lines
[i
] = include_text
29 text
= '\n'.join(lines
)
30 logging
.info('******* text after include:\n{}'.format(text
))
35 key
, value
= arg
.split('=')
36 mako_kwargs
[key
] = value
42 print('Cannot import mako - mako is not run')
46 from mako
.template
import Template
47 from mako
.lookup
import TemplateLookup
48 lookup
= TemplateLookup(directories
=[os
.curdir
])
49 # text = text.encode('utf-8')
50 temp
= Template(text
=text
, lookup
=lookup
, strict_undefined
=True)
51 logging
.info('******* mako_kwargs: {}'.format(str(mako_kwargs
)))
52 text
= temp
.render(**mako_kwargs
)
54 logging
.info('******* text after mako:\n{}'.format(text
))
57 lines
= text
.splitlines()
59 inside
= None # indicates which type of cell we are inside
60 fullname
= None # full language name in code cells
62 if line
.startswith('-----'):
63 # New cell, what type?
64 m
= re
.search(r
'-----([a-z0-9-]+)?', line
)
66 shortname
= m
.group(1)
68 # Check if code is to be typeset as static
69 # Markdown code (e.g., shortname=py-t)
70 logging
.info('******* found shortname {}'
72 astext
= shortname
[-2:] == '-t'
73 logging
.info('******* cell: astext={} shortname={}'
74 .format(astext
, shortname
))
77 shortname
= shortname
[:-2]
79 cells
.append(['markdown', 'code', ['\n']])
80 cells
[-1][2].append('```%s\n' % fullname
)
83 if shortname
in shortname2language
:
84 fullname
= shortname2language
[shortname
]
86 cells
.append(['codecell', fullname
, []])
88 logging
.info('******* cell: markdown')
91 cells
.append(['markdown', 'text', ['\n']])
93 raise SyntaxError('Wrong syntax of cell delimiter:\n{}'
96 # Ordinary line in a cell
97 if inside
in ('markdown', 'codecell'):
98 cells
[-1][2].append(line
)
100 raise SyntaxError('line\n {}\nhas no beginning cell delimiter'
102 # Merge the lines in each cell to a string
103 for i
in range(len(cells
)):
104 if cells
[i
][0] == 'markdown' and cells
[i
][1] == 'code':
105 # Add an ending ``` of code
106 cells
[i
][2].append('```\n')
107 cells
[i
][2] = '\n'.join(cells
[i
][2])
108 # TODO: optional logging
110 logging
.info('******* cell data structure:\b%s' % pprint
.pformat(cells
))
114 """Turn cells list into valid IPython notebook code."""
115 # Use Jupyter nbformat functionality for writing the notebook
117 from nbformat
.v4
import (
118 new_code_cell
, new_markdown_cell
, new_notebook
, writes
)
121 for cell_tp
, language
, block
in cells
:
122 if cell_tp
== 'markdown':
124 new_markdown_cell(source
=block
))
125 elif cell_tp
== 'codecell':
126 nb_cells
.append(new_code_cell(source
=block
))
128 nb
= new_notebook(cells
=nb_cells
)
133 """Compile a document and its variables."""
135 filename
= sys
.argv
[1]
136 with open(filename
, 'r') as f
:
138 except (IndexError, IOError) as e
:
139 print('Usage: %s filename' % (sys
.argv
[0]))
142 cells
= read(text
, argv
=sys
.argv
[2:])
143 filestr
= write(cells
)
144 # Assuming file extension .gj (generate Jupyter); TODO: less strict
145 filename
= filename
[:-3] + '.ipynb'
146 with open(filename
, 'w') as f
:
149 if __name__
== '__main__':
151 if os
.path
.isfile(logfile
):
153 logging
.basicConfig(format
='%(message)s', level
=logging
.DEBUG
,