| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 """ Command-line tool to parse scss file. |  | 
| 2 """ |  | 
| 3 import optparse |  | 
| 4 import sys, os |  | 
| 5 import time |  | 
| 6 |  | 
| 7 from os.path import abspath, dirname, join, normpath |  | 
| 8 |  | 
| 9 COMMANDS = ['import', 'option', 'mixin', 'include', 'for', 'if', 'else'] |  | 
| 10 |  | 
| 11 |  | 
| 12 def complete(text, state): |  | 
| 13     """ Auto complete scss constructions |  | 
| 14         in interactive mode. |  | 
| 15     """ |  | 
| 16     for cmd in COMMANDS: |  | 
| 17         if cmd.startswith(text): |  | 
| 18             if not state: |  | 
| 19                 return cmd |  | 
| 20             else: |  | 
| 21                 state -= 1 |  | 
| 22 |  | 
| 23 def main(argv=None): |  | 
| 24     from scss import parser, VERSION |  | 
| 25 |  | 
| 26     try: |  | 
| 27         # Upgrade shell in interactive mode |  | 
| 28         import atexit |  | 
| 29         import readline |  | 
| 30         history = os.path.join(os.environ['HOME'], ".scss-history") |  | 
| 31         atexit.register(readline.write_history_file, history) |  | 
| 32         readline.parse_and_bind("tab: complete") |  | 
| 33         readline.set_completer(complete) |  | 
| 34         readline.read_history_file(history) |  | 
| 35     except ( ImportError, IOError ): |  | 
| 36         pass |  | 
| 37 |  | 
| 38     # Create options |  | 
| 39     p = optparse.OptionParser( |  | 
| 40         usage="%prog [OPTION]... [INFILE] [OUTFILE] [DARTCLASS]", |  | 
| 41         version="%prog " + VERSION, |  | 
| 42         epilog="SCSS compiler.", |  | 
| 43         description="Compile INFILE or standard input, to OUTFILE or standard ou
     tput, if --dart specified DARTCLASS is the dart file name and class name.") |  | 
| 44 |  | 
| 45     p.add_option( |  | 
| 46         '-c', '--cache', action='store_true', dest='cache', |  | 
| 47         help="Create and use cache file. Only for files.") |  | 
| 48 |  | 
| 49     p.add_option( |  | 
| 50         '-i', '--interactive', action='store_true', dest='shell', |  | 
| 51         help="Run in interactive shell mode.") |  | 
| 52 |  | 
| 53     p.add_option( |  | 
| 54         '-m', '--compress', action='store_true', dest='compress', |  | 
| 55         help="Compress css output.") |  | 
| 56 |  | 
| 57     p.add_option( |  | 
| 58         '-d', '--dart', action='store_true', dest='dart', |  | 
| 59         help="Pre-process css output css file and dart class file.") |  | 
| 60 |  | 
| 61     p.add_option( |  | 
| 62         '-w', '--watch', dest='watch', |  | 
| 63         help="""Watch files or directories for changes. |  | 
| 64 The location of the generated CSS can be set using a colon: |  | 
| 65     scss -w input.scss:output.css |  | 
| 66 """) |  | 
| 67 |  | 
| 68     p.add_option( |  | 
| 69         '-S', '--no-sorted', action='store_false', dest='sort', |  | 
| 70         help="Do not sort declaration.") |  | 
| 71 |  | 
| 72     p.add_option( |  | 
| 73         '-C', '--no-comments', action='store_false', dest='comments', |  | 
| 74         help="Clear css comments.") |  | 
| 75 |  | 
| 76     p.add_option( |  | 
| 77         '-W', '--no-warnings', action='store_false', dest='warn', |  | 
| 78         help="Disable warnings.") |  | 
| 79 |  | 
| 80     opts, args = p.parse_args(argv or sys.argv[1:]) |  | 
| 81     precache = opts.cache |  | 
| 82 |  | 
| 83     # TODO(terry): Handle dart option in interactive shell. |  | 
| 84     # Interactive mode |  | 
| 85     if opts.shell: |  | 
| 86         p = parser.Stylesheet() |  | 
| 87         print 'SCSS v. %s interactive mode' % VERSION |  | 
| 88         print '================================' |  | 
| 89         print 'Ctrl+D or quit for exit' |  | 
| 90         while True: |  | 
| 91             try: |  | 
| 92                 s = raw_input('>>> ').strip() |  | 
| 93                 if s == 'quit': |  | 
| 94                     raise EOFError |  | 
| 95                 print p.loads(s) |  | 
| 96             except (EOFError, KeyboardInterrupt): |  | 
| 97                 print '\nBye bye.' |  | 
| 98                 break |  | 
| 99 |  | 
| 100         sys.exit() |  | 
| 101 |  | 
| 102     # Watch mode |  | 
| 103     elif opts.watch: |  | 
| 104         self, target = opts.watch.partition(':') |  | 
| 105         files = [] |  | 
| 106         if not os.path.exists(self): |  | 
| 107             print >> sys.stderr, "Path don't exist: %s" % self |  | 
| 108             sys.exit(1) |  | 
| 109 |  | 
| 110         if os.path.isdir(self): |  | 
| 111             for f in os.listdir(self): |  | 
| 112                 path = os.path.join(self, f) |  | 
| 113                 if os.path.isfile(path) and f.endswith('.scss'): |  | 
| 114                     tpath = os.path.join(target or self, f[:-5] + '.css') |  | 
| 115                     files.append([ path, tpath, 0 ]) |  | 
| 116         else: |  | 
| 117             files.append([ self, target or self[:-5] + '.css', 0 ]) |  | 
| 118 |  | 
| 119         s = parser.Stylesheet( |  | 
| 120             options=dict( |  | 
| 121                 comments = opts.comments, |  | 
| 122                 compress = opts.compress, |  | 
| 123                 dart = opts.dart, |  | 
| 124                 warn = opts.warn, |  | 
| 125                 sort = opts.sort, |  | 
| 126                 cache = precache, |  | 
| 127             )) |  | 
| 128 |  | 
| 129         def parse(f): |  | 
| 130             infile, outfile, mtime = f |  | 
| 131             ttime = os.path.getmtime(infile) |  | 
| 132             if mtime < ttime: |  | 
| 133                 print " Parse '%s' to '%s' .. done" % ( infile, outfile ) |  | 
| 134                 out = s.load(open(infile, 'r')) |  | 
| 135                 open(outfile, 'w').write(out) |  | 
| 136                 f[2] = os.path.getmtime(outfile) |  | 
| 137 |  | 
| 138         print 'SCSS v. %s watch mode' % VERSION |  | 
| 139         print '================================' |  | 
| 140         print 'Ctrl+C for exit\n' |  | 
| 141         while True: |  | 
| 142             try: |  | 
| 143                 for f in files: |  | 
| 144                     parse(f) |  | 
| 145                 time.sleep(0.3) |  | 
| 146             except OSError: |  | 
| 147                 pass |  | 
| 148             except KeyboardInterrupt: |  | 
| 149                 print "\nSCSS stoped." |  | 
| 150                 break |  | 
| 151 |  | 
| 152         sys.exit() |  | 
| 153 |  | 
| 154     # Default compile files |  | 
| 155     elif not args: |  | 
| 156         infile = sys.stdin |  | 
| 157         outfile = sys.stdout |  | 
| 158         precache = False |  | 
| 159 |  | 
| 160     elif len(args) == 1: |  | 
| 161         try: |  | 
| 162             infile = open(args[0], 'r') |  | 
| 163             outfile = sys.stdout |  | 
| 164         except IOError, e: |  | 
| 165             sys.stderr.write(str(e)) |  | 
| 166             sys.exit() |  | 
| 167 |  | 
| 168     elif len(args) == 2 or len(args) == 3: |  | 
| 169         try: |  | 
| 170             infile = open(os.path.abspath(args[0]), 'r') |  | 
| 171             outfile = open(os.path.abspath(args[1]), 'w') |  | 
| 172         except IOError, e: |  | 
| 173             sys.stderr.write(str(e)) |  | 
| 174             sys.exit() |  | 
| 175     else: |  | 
| 176         p.print_help(sys.stdout) |  | 
| 177         sys.exit() |  | 
| 178 |  | 
| 179     try: |  | 
| 180         s = parser.Stylesheet( |  | 
| 181             options=dict( |  | 
| 182                 comments = opts.comments, |  | 
| 183                 compress = opts.compress, |  | 
| 184                 dart = opts.dart, |  | 
| 185                 warn = opts.warn, |  | 
| 186                 sort = opts.sort, |  | 
| 187                 cache = precache, |  | 
| 188             )) |  | 
| 189         if (opts.dart and len(args) == 3): |  | 
| 190           try: |  | 
| 191               dartClass = args[2] |  | 
| 192               dartfn = os.path.abspath('%s.dart' % dartClass) |  | 
| 193               dartfile = open(dartfn, 'w') |  | 
| 194           except IOError, e: |  | 
| 195               sys.stderr.write(str(e)) |  | 
| 196               sys.exit() |  | 
| 197 |  | 
| 198           # Parse the scss file. |  | 
| 199           nodes = s.loadReturnNodes(infile) |  | 
| 200 |  | 
| 201           # Add the main CSS file to list of files pre-processed. |  | 
| 202           s.addInclude(args[0], nodes) |  | 
| 203 |  | 
| 204           # Write out CSS file. |  | 
| 205           print 'Generating CSS file %s' % os.path.abspath(args[1]) |  | 
| 206 |  | 
| 207           cssIncludes = [] |  | 
| 208           # Output all includes first. |  | 
| 209           for include in s.scssIncludes: |  | 
| 210             cssIncludes.append( |  | 
| 211                 '/* ---------- Included %s file ---------- */\n\n' % include[0]) |  | 
| 212             cssIncludes.append(''.join(map(str, include[1]))) |  | 
| 213 |  | 
| 214           outfile.write('/* File generated by SCSS from source %s\n' % args[0]) |  | 
| 215           outfile.write(' * Do not edit.\n') |  | 
| 216 |  | 
| 217           outfile.write(' */\n\n%s' % ''.join(cssIncludes)) |  | 
| 218 |  | 
| 219           #Write out dart class file. |  | 
| 220           dartfile.write(s.dartClass(args[0], dartClass, s.scssIncludes)) |  | 
| 221           print 'Generating Dart Class %s' % dartfn |  | 
| 222         else: |  | 
| 223           outfile.write(s.load(infile)) |  | 
| 224     except ValueError, e: |  | 
| 225         raise SystemExit(e) |  | 
| 226 |  | 
| 227 |  | 
| 228 if __name__ == '__main__': |  | 
| 229     # Setup PYTHONPATH when starting tool (from main) to needed modules. |  | 
| 230     TOOL_PATH = dirname(dirname(abspath(__file__))) |  | 
| 231     THIRDPARTY_PATH = normpath('{0}/..'.format(TOOL_PATH)) |  | 
| 232     sys.path.append(join(THIRDPARTY_PATH, 'pyparsing/src')) |  | 
| 233     sys.path.append(TOOL_PATH) |  | 
| 234 |  | 
| 235     main() |  | 
| OLD | NEW | 
|---|