text: #!/usr/bin/env python
  
  import PyV8
  
  import os
  import sys
  import compiler
  
  from os.path import join, dirname, basename, abspath
  from optparse import OptionParser
  
  usage = """
    usage: %prog [options] <application module name or path>
  """
  
  
  currentdir = abspath(dirname(__file__))
  pyjspth = abspath(join(dirname(__file__), ".."))
  sys.path = [(join(pyjspth, "pyjs", "src"))] + sys.path
  
  import pyjs
  
  pyjs.pyjspth = pyjspth
  pyjs.path += [os.path.join(pyjspth, 'library'),
              os.path.join(pyjspth, 'addons'),
  ]
  
  #currentdir = abspath(dirname(dirname(__file__)))
  #builddir = abspath("..")
  #sys.path = [(join(builddir, "pyjs", "src"))] + sys.path
  #print sys.path
  
  #app_library_dirs = [
  #    currentdir,
  #    join(builddir, "library/builtins"),
  #    join(builddir, "library"),
  #    join(builddir, "addons")]
   
  def tostrlist(l):
      l = map(lambda x: "'%s'" % x, l)
      return "[%s]" % ', '.join(l)
  
  class FileWrapper(object):
      def __init__(self, fname, mode):
          self.f = open(fname, mode)
  
      def seek(self, seekto=None):
          if seekto is None:
              return self.f.seek()
          return self.f.seek(seekto)
  
      def close(self):
          return self.f.close()
  
      def write(self, bytes):
          return self.f.write(bytes)
  
      def read(self, bytes=None):
          if bytes is None:
              return self.f.read()
          return self.f.read(bytes)
  
  # Create a python class to be used in the context
  class Global(PyV8.JSClass):
      def pyv8_open(self, fname, mode):
          return FileWrapper(fname, mode)
  
      def pyv8_print_fn(self, arg):
          print arg
  
      def pyv8_import_module(self, parent_name, module_name):
          #print "pyv8_import_module", parent_name, module_name
          exec "import " + module_name
          return locals()[module_name]
      
      def pyv8_load(self, modules):
          for i in range(len(modules)):
              fname = modules[i]
              #print "pyv8_load", fname
              fp = open(fname, 'r')
              txt = fp.read()
              fp.close()
  
              x = self.__context__.eval(txt)
  
  
  
  
  import os
  from pyjs import linker
  from pyjs import translator
  from pyjs import util
  from optparse import OptionParser
  
  PLATFORM='pyv8'
  
  APP_TEMPLATE = """
  var $wnd = new Object();
  $wnd.document = new Object();
  var $doc = $wnd.document;
  var $moduleName = "%(app_name)s";
  var $pyjs = new Object();
  $pyjs.__modules__ = {};
  $pyjs.modules = {};
  $pyjs.modules_hash = {};
  $pyjs.available_modules = %(available_modules)s;
  $pyjs.loaded_modules = {};
  $pyjs.options = new Object();
  $pyjs.options.set_all = function (v) {
      $pyjs.options.arg_ignore = v;
      $pyjs.options.arg_count = v;
      $pyjs.options.arg_is_instance = v;
      $pyjs.options.arg_instance_type = v;
      $pyjs.options.arg_kwarg_dup = v;
      $pyjs.options.arg_kwarg_unexpected_keyword = v;
      $pyjs.options.arg_kwarg_multiple_values = v;
  };
  $pyjs.options.set_all(true);
  $pyjs.trackstack = [];
  $pyjs.track = {module:'__main__', lineno: 1};
  $pyjs.trackstack.push($pyjs.track);
  $pyjs.__last_exception_stack__ = null;
  $pyjs.__last_exception__ = null;
  
  /*
   * prepare app system vars
   */
  $pyjs.platform = 'pyv8';
  $pyjs.appname = '%(app_name)s';
  $pyjs.loadpath = './';
  
  pyv8_load(%(module_files)s);
  
  pyv8_load(%(js_lib_files)s);
  
  /* late static js libs */
  
  %(late_static_js_libs)s
  
  
  //try {
      $pyjs.loaded_modules['pyjslib']('pyjslib');
      $pyjs.loaded_modules['pyjslib'].___import___('%(app_name)s', '%(app_name)s', '__main__');
  //} catch(exception)
  //{
  //    var fullMessage = exception.name + ': ' + exception.message;
  //    var uri = exception.fileName;
  //    //var stack = exception.stack;
  //    var line = exception.lineNumber;
  //    fullMessage += "\\n at " + uri + ": " + line;
  //    print (fullMessage );
  //    //print (stack.toString() );
  //}
  """
  
  class PyV8Linker(linker.BaseLinker):
      """PyV8 linker, which links together files by using the
      load function of the spidermonkey shell."""
  
      # we derive from mozilla
      platform_parents = {
          PLATFORM:['mozilla', 'array_extras']
          }
  
      def __init__(self, *args, **kwargs):
          kwargs['platforms'] = [PLATFORM]
          super(PyV8Linker, self).__init__(*args, **kwargs)
  
      def visit_start(self):
          super(PyV8Linker, self).visit_start()
          self.js_libs.append('_pyjs.js')
          self.merged_public = set()
  
      def merge_resources(self, dir_name):
          """find the absolute paths of js includes"""
          if not self.js_libs or dir_name in self.merged_public:
              return
          public_folder = os.path.join(dir_name, 'public')
          if not os.path.isdir(public_folder):
              return
          for i, js_lib in enumerate(self.js_libs):
              p = os.path.join(public_folder, js_lib)
              if os.path.isfile(p):
                  self.js_libs[i] = p
  
      def visit_end(self):
  
          def static_code(libs, msg = None):
              code = []
              for lib in libs:
                  fname = lib
                  if not os.path.isfile(fname):
                      fname = os.path.join(self.output, lib)
                  if not os.path.isfile(fname):
                      raise RuntimeError('File not found %r' % lib)
                  if fname[len_ouput_dir:] == self.output:
                      name = fname[len_ouput_dir:]
                  else:
                      name = os.path.basename(lib)
                  if not msg is None:
                      code.append("/* start %s: %s */" % (msg, name))
                  f = file(fname)
                  code.append(f.read())
                  if not msg is None:
                      code.append("/* end %s */" % (name,))
                  self.remove_files[fname] = True
                  fname = fname.split('.')
                  if fname[-2] == '__%s__' % platform_name:
                      del fname[-2]
                      fname = '.'.join(fname)
                      if os.path.isfile(fname):
                          self.remove_files[fname] = True
              return "\n".join(code)
  
          done = self.done[PLATFORM]
  
          # locals - go into template via locals()
          module_files=tostrlist(done)
          #print "module_files", module_files
          js_lib_files=tostrlist(self.js_libs)
          early_static_js_libs=str(self.js_libs)[1:-1]
          late_static_js_libs = [] + self.late_static_js_libs
          late_static_js_libs = static_code(late_static_js_libs, "javascript lib")
  
          app_name = self.top_module
          available_modules = self.visited_modules[PLATFORM]
  
          self.out_file_mod = os.path.join(self.output, self.top_module + '.js')
          out_file = open(self.out_file_mod , 'w')
          out_file.write(APP_TEMPLATE % locals())
          out_file.close()
  
  def build_script():
      usage = """
      usage: %prog [options] module_name
      """
      parser = OptionParser(usage = usage)
      translator.add_compile_options(parser)
  
      parser.add_option(
          "--dynamic",
          dest="unlinked_modules",
          action="append",
          help="regular expression for modules that will not be linked and thus loaded dynamically"
          )
  
      # override the default because we want print
      parser.set_defaults(print_statements=True)
      linker.add_linker_options(parser)
      options, args = parser.parse_args()
      if len(args) == 0:
          parser.error("incorrect number of arguments")
  
      pyjs.path = ["."] + pyjs.path
      #top_module = args[0]
      for d in options.library_dirs:
          pyjs.path.append(os.path.abspath(d))
  
      print "paths:", pyjs.path
  
      translator_arguments=dict(
          debug=options.debug,
          print_statements = options.print_statements,
          function_argument_checking=options.function_argument_checking,
          attribute_checking=options.attribute_checking,
          source_tracking=options.source_tracking,
          line_tracking=options.line_tracking,
          store_source=options.store_source,
          inline_code = options.inline_code,
          operator_funcs = options.operator_funcs,
          number_classes = options.number_classes,
          )
  
      l = PyV8Linker(args, #[top_module],
                             output=options.output,
                             platforms=[PLATFORM],
                             path=pyjs.path,
                             compiler=compiler,
                             translator_arguments=translator_arguments)
      l()
  
      return l
  
  
  def main():
  
      l = build_script()
  
      fp = open(l.out_file_mod, 'r')
      txt = fp.read()
      fp.close()
  
      #PyV8.debugger.enabled = True
      # create a context with an explicit global
      g = Global()
      ctxt = PyV8.JSContext(g)
      g.__context__ = ctxt
      # enter the context
      ctxt.enter()
      
      x = ctxt.eval(txt)
  
  
  if __name__ == '__main__':
      main()
  
  