Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F61095779
snippet_helper.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, May 4, 12:34
Size
9 KB
Mime Type
text/x-python
Expires
Mon, May 6, 12:34 (2 d)
Engine
blob
Format
Raw Data
Handle
17464429
Attached To
R3683 Slides
snippet_helper.py
View Options
#!/usr/bin/env python3
import
subprocess
import
os
import
re
from
pygments
import
highlight
from
pygments.lexers
import
CppLexer
# from pygments.lexer import RegexLexer
# from pygments.lexers import MatlabLexer
from
pygments.formatters
import
HtmlFormatter
from
pygments.formatters
import
LatexFormatter
from
pygments
import
token
from
IPython.display
import
HTML
from
tempfile
import
NamedTemporaryFile
################################################################
class
Snippet
(
object
):
class
CompilationError
(
Exception
):
""" Compilation error """
pass
default_output
=
'html'
default_line_numbering
=
False
def
__init__
(
self
,
inp
,
format_flag
=
False
,
compile_flag
=
False
):
try
:
self
.
loadfile
(
inp
)
except
Exception
as
e
:
self
.
content
=
inp
.
strip
()
if
format_flag
:
self
.
clang_format
()
if
compile_flag
:
self
.
compile
()
def
save
(
self
,
filename
):
f
=
open
(
filename
,
'w'
)
f
.
write
(
self
.
content
)
f
.
close
()
def
loadfile
(
self
,
inp
):
filename
=
inp
full_filename
=
os
.
path
.
realpath
(
filename
)
f
=
open
(
full_filename
)
self
.
content
=
f
.
read
()
f
.
close
()
def
clang_format
(
self
):
f
=
NamedTemporaryFile
()
f
.
write
(
self
.
content
.
encode
())
f
.
flush
()
p
=
subprocess
.
Popen
(
'clang-format {0}'
.
format
(
f
.
name
),
shell
=
True
,
stdout
=
subprocess
.
PIPE
)
stdout
,
stderr
=
p
.
communicate
()
formatted_file
=
stdout
self
.
content
=
formatted_file
.
decode
(
'utf-8'
)
def
compile
(
self
,
working_dir
=
'/tmp'
):
f
=
NamedTemporaryFile
(
suffix
=
'.cpp'
,
delete
=
False
)
f
.
write
(
self
.
content
.
encode
())
f
.
flush
()
working_dir
=
os
.
path
.
dirname
(
f
.
name
)
# file_dir = os.path.dirname(self.full_filename)
previous_dir
=
os
.
getcwd
()
os
.
chdir
(
working_dir
)
p
=
subprocess
.
Popen
(
'g++ -Wall -Wextra -I {1} -c {0}'
.
format
(
f
.
name
,
working_dir
),
shell
=
True
,
stderr
=
subprocess
.
PIPE
)
stdout
,
stderr
=
p
.
communicate
()
ret
=
p
.
returncode
os
.
chdir
(
previous_dir
)
if
ret
!=
0
:
raise
Snippet
.
CompilationError
(
'compilation failed
\n
'
+
stderr
.
decode
(
'utf-8'
))
os
.
remove
(
f
.
name
)
o_file
=
os
.
path
.
splitext
(
f
.
name
)[
0
]
+
'.o'
os
.
remove
(
o_file
)
def
get_lines
(
self
):
return
self
.
content
.
split
(
'
\n
'
)
def
get_content
(
self
):
return
self
.
content
def
__str__
(
self
):
_content
=
self
.
content
.
split
(
'
\n
'
)
ret
=
""
for
i
,
line
in
enumerate
(
_content
):
ret
+=
'{0}: {1}
\n
'
.
format
(
i
,
line
)
return
ret
class
KeywordLexer
(
object
):
def
__init__
(
self
,
keyword
):
if
keyword
==
'curly_brackets'
:
keyword
=
'{|}'
self
.
keyword
=
keyword
def
get_tokens
(
self
,
text
):
pattern
=
'('
+
self
.
keyword
+
')'
splits
=
re
.
split
(
pattern
,
text
)
if
len
(
splits
)
==
1
:
return
[(
token
.
Text
,
text
)]
res
=
[]
for
count
,
s
in
enumerate
(
splits
):
if
count
%
2
==
0
:
res
.
append
((
token
.
Text
,
s
))
else
:
res
.
append
((
token
.
Keyword
.
Type
,
s
))
# print(res)
return
res
class
LineLexer
(
object
):
def
__init__
(
self
,
line_number
):
self
.
line_number
=
line_number
def
get_tokens
(
self
,
text
):
splits
=
text
.
split
(
'
\n
'
)
res
=
[]
splits1
=
'
\n
'
.
join
(
splits
[:
self
.
line_number
])
+
'
\n
'
splits2
=
splits
[
self
.
line_number
]
+
'
\n
'
splits3
=
'
\n
'
+
'
\n
'
.
join
(
splits
[
self
.
line_number
+
1
:])
+
'
\n
'
splits
=
[
splits1
]
+
[
splits2
]
+
[
splits3
]
# print(splits)
for
count
,
s
in
enumerate
(
splits
):
if
count
==
1
:
res
.
append
((
token
.
Keyword
.
Type
,
s
))
else
:
res
.
append
((
token
.
Text
,
s
))
# print(res)
return
res
class
CustomLatexFormatter
(
LatexFormatter
):
def
__init__
(
self
,
**
kwargs
):
LatexFormatter
.
__init__
(
self
,
**
kwargs
)
def
format
(
self
,
tokens
,
outfile
):
res
=
[]
for
t
,
s
in
tokens
:
if
t
==
token
.
Keyword
.
Type
:
import
pygments.formatters.latex
as
la
s
=
la
.
escape_tex
(
s
,
self
.
commandprefix
)
s
=
'\color{red}{\huge{'
+
s
+
'}}'
t
=
token
.
Escape
res
.
append
((
t
,
s
))
LatexFormatter
.
format
(
self
,
res
,
outfile
)
class
CustomHtmlFormatter
(
HtmlFormatter
):
def
__init__
(
self
,
**
kwargs
):
HtmlFormatter
.
__init__
(
self
,
**
kwargs
)
def
format
(
self
,
tokens
,
outfile_final
):
# HtmlFormatter.format(self, tokens, outfile_final)
# return
from
io
import
StringIO
outfile
=
StringIO
()
res
=
[]
ss
=
[]
for
t
,
s
in
tokens
:
if
t
==
token
.
Keyword
.
Type
:
ss
.
append
(
s
)
s
=
'A'
*
24
t
=
token
.
Text
res
.
append
((
t
,
s
))
HtmlFormatter
.
format
(
self
,
res
,
outfile
)
final
=
outfile
.
getvalue
()
while
ss
:
s
=
ss
.
pop
()
final
=
final
.
replace
(
'A'
*
24
,
'<span style="color:red;font-size:300%">{0}</span>'
.
format
(
s
),
1
)
outfile_final
.
write
(
final
)
def
pigment
(
self
,
keyword
=
None
,
line_highlight
=
None
,
start
=
None
,
end
=
None
,
output
=
None
,
line_numbering
=
None
):
_content
=
self
.
content
.
split
(
'
\n
'
)
_content
=
[(
c
+
'
\n
'
)
for
c
in
_content
]
if
start
is
None
:
start
=
1
if
end
is
None
:
end
=
len
(
_content
)
if
output
is
None
:
output
=
self
.
default_output
lexer
=
CppLexer
()
if
keyword
is
not
None
:
lexer
=
self
.
KeywordLexer
(
keyword
)
elif
line_highlight
is
not
None
:
if
line_highlight
<
start
or
line_highlight
>
end
:
raise
RuntimeError
(
'line_highlight out of the sub snippet'
)
line_highlight
-=
start
lexer
=
self
.
LineLexer
(
line_highlight
)
if
line_numbering
is
None
:
line_numbering
=
self
.
default_line_numbering
if
output
==
'html'
:
formatter
=
HtmlFormatter
(
full
=
False
,
linenos
=
line_numbering
,
linenostart
=
start
)
elif
output
==
'latex'
:
formatter
=
LatexFormatter
(
full
=
False
,
linenos
=
line_numbering
,
linenostart
=
start
)
if
(
keyword
is
not
None
)
or
(
line_highlight
is
not
None
):
format_class
=
self
.
CustomHtmlFormatter
if
output
==
'latex'
:
format_class
=
self
.
CustomLatexFormatter
formatter
=
format_class
(
full
=
False
,
linenos
=
line_numbering
,
linenostart
=
start
)
snip
=
_content
[
start
-
1
:
end
]
snip
=
''
.
join
(
snip
)
colored_snippet
=
highlight
(
snip
,
lexer
,
formatter
)
if
output
==
'html'
:
HTML_TEMPLATE
=
"""<style>
{}
</style>
{}
"""
css
=
formatter
.
get_style_defs
()
colored_snippet
=
HTML
(
HTML_TEMPLATE
.
format
(
css
,
colored_snippet
))
return
colored_snippet
@staticmethod
def
getLatexStyleDefs
():
return
LatexFormatter
(
full
=
True
)
.
get_style_defs
()
################################################################
class
SnippetCollection
(
Snippet
):
def
__init__
(
self
):
self
.
functions
=
dict
()
self
.
func_names
=
[]
def
addFunction
(
self
,
f_name
,
code
):
if
f_name
in
self
.
functions
:
raise
RuntimeError
(
'function already declared'
)
self
.
func_names
.
append
(
f_name
)
self
.
functions
[
f_name
]
=
Snippet
(
code
,
format_flag
=
True
)
self
.
compile
()
def
__getitem__
(
self
,
key
):
return
self
.
functions
[
key
]
def
flatten
(
self
):
global_input
=
"""
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cassert>
"""
+
'/'
*
70
+
'
\n\n
'
for
f_name
in
self
.
func_names
:
global_input
+=
"void {0}(){{
\n
"
.
format
(
f_name
)
global_input
+=
self
.
functions
[
f_name
]
.
content
global_input
+=
'
\n
}
\n\n
'
+
'/'
*
70
+
'
\n\n
'
global_input
+=
"""
int main(int argc, char ** argv){\n"""
for
f_name
in
self
.
func_names
:
global_input
+=
f_name
+
'();
\n
'
global_input
+=
'
\n
}
\n
'
flat
=
Snippet
(
global_input
,
format_flag
=
True
)
return
flat
def
compile
(
self
,
**
kwargs
):
global_snippet
=
self
.
flatten
()
global_snippet
.
compile
(
**
kwargs
)
def
save
(
self
,
filename
):
global_snippet
=
self
.
flatten
()
open
(
filename
,
'w'
)
.
write
(
global_snippet
.
content
)
def
pigment
(
self
,
*
args
):
return
self
.
flatten
()
.
pigment
(
*
args
)
def
last
(
self
):
return
self
.
functions
[
self
.
func_names
[
-
1
]]
################################################################
# def printMatlab(code):
#
# html_snippet = highlight(
# code, MatlabLexer(),
# HtmlFormatter(full=True, style='colorful',
# classprefix='matlab_'))
#
# display(HTML(html_snippet))
# # return html_snippet
# ## testing
#Snippet.default_output = 'latex'
#Snippet.default_line_numbering = True
#
#snippet = SnippetCollection()
# snippet.addFunction('if_syntax', '''
# int p, q;
# if (p > q) {
# /*
# Statement1;
# Statement2;
# */
# }
#''')
#
#print (snippet['if_syntax'].pigment())
Event Timeline
Log In to Comment