Reputation: 39889
I'd like to use CoffeeScript(CS) and the CS Compiler but without having to install Node.js.
I saw that the core compiler of CS is in JavaScript, so there's no need for Node.js to be installed, but I can't find any compiler written in Python/Java or any other languages, only Node.js.
Am I missing something? Will I have to write my own implementation in Python?
Upvotes: 4
Views: 3101
Reputation: 649
In my opinion DukPy is the best javascript interpreter written in Python! It can compile CoffeeScript
, TypeScript
, BabelJS
and JSX
. Usage is very simple:
import dukpy
dukpy.coffee_compile("CoffeeScript goes here!")
DukPy is the successor to the Python-CoffeeScript package witch is no longer maintained.
Upvotes: 0
Reputation: 149
You can use something like this: http://hovet.biz/blog/?p=27 It's a Python2 based compiler using the Js version of the CoffeScript compiler and Qt WebKit. Note, no Qt GUI is involved, it's text only.
And here's the source, as requested:
import sys, os, glob
import time, htmllib
from os.path import splitext
from PyQt5.QtCore import QUrl
from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWidgets import QApplication
coffee_script_js = os.path.expanduser('~/src/coffee-monitor/coffee-script.js')
assert os.path.exists(coffee_script_js)
sleep_time = 0.05
class CoffeeMonitor(QWebPage):
def __init__(self, src_dir):
self._cs_src = None
self._div_start = '<div id="cssrc">'
self._app = QApplication(sys.argv)
QWebPage.__init__(self)
self.loadFinished.connect(self.load_finished)
self._cs_src_dir = src_dir
if not self.prep_compile_file():
exit()
self._app.exec_()
def prep_compile_file(self):
while 1:
try:
src = self.get_cs_src()
if src:
self.mainFrame().load(QUrl(src))
return True
time.sleep(sleep_time)
except KeyboardInterrupt:
break
return False
def create_cs_html(self, f):
f_html = f + '.html'
src = open(f).read()
fil = open(f_html, 'w')
fil.write('''<html>
<body>
'''+ self._div_start +''' </div>
<script type="text/coffeescript">
''')
fil.write('try\n')
#fil.write(" src = CoffeeScript.compile '" + src.replace('\n', '\\n').replace("'", "\\'") + "', bare: on\n")
fil.write(" src = CoffeeScript.compile '" + src.replace('\n', '\\n').replace("'", "\\'") + "', bare: off\n")
fil.write(''' document.getElementById("cssrc").textContent = src
catch {location, message}
if location?
message = "'''+f+''': Error on line #{location.first_line + 1}: #{message}"
document.getElementById("cssrc").textContent = message
</script>
<script src="''' + coffee_script_js + '''"></script>
</body>
</html>
''')
fil.close()
return 'file://' + f_html
def get_cs_src(self):
#files = []
#for exts in [ 'coffee', 'cof', 'coffe', 'cofee', 'cofe', 'kaffe' ]:
# files += glob.glob(self._cs_src_dir + '/*.' + exts)
files = glob.glob(self._cs_src_dir + '/*.coffee')
self._cs_src = None
for f in files:
name,ext = splitext(f)
js = name + '.js'
if not os.path.exists(js):
self._cs_src = f
return self.create_cs_html(f)
c_time_cof = os.stat(f).st_ctime
c_time_js = os.stat(js).st_ctime
if c_time_cof > c_time_js:
self._cs_src = f
return self.create_cs_html(f)
def get_compiled_js_src(self):
html = self.mainFrame().toHtml()
js_src = ''
error = False
for line in html.split('\n'):
if line.startswith(self._div_start):
js_src = line[len(self._div_start):]
if js_src.find('Error on line ') > 0:
js_src = '!'*5 + ' ' + js_src.rstrip('</div>\n')
js_src = 'alert("'+ js_src.replace('"', "'") +'");'
error = True
#print js_src
break
elif js_src:
js_src += line.rstrip('</div>\n')
if line.find('</div>') >= 0:
break
js_src = unescape(js_src)
return js_src, error
def load_finished(self, result):
js_src, error = self.get_compiled_js_src()
name,ext = splitext(self._cs_src)
js = name + '.js'
print '*** updating', js
if error:
print js_src
fil = open(js, 'w')
fil.write(js_src.replace(';',';\n'))
fil.close()
if not self.prep_compile_file():
self._app.quit()
def unescape(s):
p = htmllib.HTMLParser(None)
p.save_bgn()
p.feed(s)
return p.save_end()
if __name__ == '__main__':
print 'This Python script comes with absolutely no warranty.'
print 'Ctrl+C to quit'
if len(sys.argv) == 1:
print 'coffee-monitor.py cs-src-dir (note: recursive search is not implemented)'
exit()
cs_dir = os.path.abspath(os.path.expanduser(sys.argv[1]))
assert os.path.isdir(cs_dir)
CoffeeMonitor(cs_dir)
Upvotes: 2
Reputation: 73590
If you don't want to install node.js, you could compile them in your web browser. Rough details of how to do that are in the docs.
If you don't want to use your browser you can run that script in anything capable of running javascript, e.g. Rhino on Java, pyv8 in python, etc.
Upvotes: 2
Reputation: 140236
You can run javascript in python with http://code.google.com/p/pyv8/.
You would run the javascript code for CoffeeScript compiler, and then compile CoffeeScript with that.
Upvotes: 3