Package cssutils :: Package scripts :: Module csscombine' |
[hide private]
[frames] | no frames]

# Source Code for Module cssutils.scripts.csscombine'

      1  """combines sheets referred to by @import rules in a given CSS proxy sheet
      2  into a single new sheet.
      3
      4  - proxy currently is a path (no URI)
      5  - in @import rules only relative paths do work for now but should be used
      6    anyway
      7  - currently no nested @imports are resolved
      8  - messages are send to stderr
      9  - output to stdout.
     10
     11  Example::
     12
     13      csscombine sheets\csscombine-proxy.css -m -t ascii -s utf-8
     14          1>combined.css 2>log.txt
     15
     16  results in log.txt::
     17
     18      COMBINING sheets\csscombine-proxy.css
     19      USING SOURCE ENCODING: utf-8
     20      * PROCESSING @import sheets\csscombine-1.css
     21      * PROCESSING @import sheets\csscombine-2.css
     22      SETTING TARGET ENCODING: ascii
     23
     24  and combined.css::
     25
     26      @charset "ascii";a{color:green}body{color:#fff;background:#000}
     27
     28  or without option -m::
     29
     30      @charset "ascii";
     31      /* proxy sheet which imports sheets which should be combined \F6 \E4 \FC  */
     32      /* @import "csscombine-1.css"; */
     33      /* combined sheet 1 */
     34      a {
     35          color: green
     36          }
     37      /* @import url(csscombine-2.css); */
     38      /* combined sheet 2 */
     39      body {
     40          color: #fff;
     41          background: #000
     42          }
     43
     44  issues
     45
     46  - URL or file hrefs? URI should be default and therefor baseURI is needed
     47  - no nested @imports are resolved yet
     48  - namespace rules are not working yet!
     49      - @namespace must be resolved (all should be moved to top of main sheet?
     50        but how are different prefixes resolved???)
     51
     52  - maybe add a config file which is used?
     53
     54  """
     55  import os
     56  import sys
     57  import cssutils
     58  from cssutils.serialize import CSSSerializer
     59
     60
     61 -def csscombine(proxypath, sourceencoding='css', targetencoding='utf-8',
     62                 minify=True):
     63      """
     64      :returns: combined cssText
     65      :Parameters:
     66          `proxypath`:
     67              url or path to a CSSStyleSheet which imports other sheets which
     68              are then combined into one sheet
     69          `sourceencoding` = 'css':
     70              encoding of the source sheets including the proxy sheet
     71
     72          `targetencoding` = 'utf-8':
     73              encoding of the combined stylesheet
     74          `minify` = True:
     75              defines if the combined sheet should be minified
     76      """
     77      sys.stderr.write('COMBINING %s\n' % proxypath)
     78      if sourceencoding != 'css':
     79          sys.stderr.write('USING SOURCE ENCODING: %s\n' % sourceencoding)
     80      src = cssutils.parse(proxypath, encoding=sourceencoding)
     81      srcpath = os.path.dirname(proxypath)
     82      r = cssutils.css.CSSStyleSheet()
     83      for rule in src.cssRules:
     84          if rule.type == rule.IMPORT_RULE:
     85              fn = os.path.join(srcpath, rule.href)
     86              sys.stderr.write('* PROCESSING @import %s\n' % fn)
     87              importsheet = cssutils.parse(fn, encoding=sourceencoding)
     88              importsheet.encoding = None # remove @charset
     89              r.insertRule(cssutils.css.CSSComment(cssText=u'/* %s */' %
     90                                                   rule.cssText))
     91              for x in importsheet.cssRules:
     92                  if x.type == x.IMPORT_RULE:
     93                      sys.stderr.write('WARN\tNo nested @imports: %s\n' % x.cssText)
     94                  # TODO: too simple if prefixes different in sheets!
     95  #                elif x.type == x.NAMESPACE_RULE:
     96  #                    print 'INFO\tMoved to begin of sheet', x.cssText
     97  #                    r.insertRule(x, 0)
     98                  else:
     99                      r.insertRule(x)
    100              #r.insertRule(importsheet.cssRules)
    101
    102  #        elif rule.type == rule.NAMESPACE_RULE:
    103  #            print 'INFO\tMoved to begin of sheet', rule.cssText
    104  #            r.insertRule(rule, 0)
    105          else:
    106              r.insertRule(rule)
    107
    108      sys.stderr.write('SETTING TARGET ENCODING: %s\n' % targetencoding)
    109      r.encoding = targetencoding
    110      if minify:
    111          # save old setting and use own serializer
    112          oldser = cssutils.ser
    113          cssutils.setSerializer(CSSSerializer())
    114          cssutils.ser.prefs.useMinified()
    115          cssText = r.cssText
    116          cssutils.setSerializer(oldser)
    117      else:
    118          cssText = r.cssText
    119      return cssText
    120
    121 -def main(args=None):
    122      import optparse
    123
    124      usage = "usage: %prog [options] path"
    125      parser = optparse.OptionParser(usage=usage)
    126      parser.add_option('-s', '--sourceencoding', action='store',
    127                        dest='sourceencoding', default='css',
    128          help='encoding of input, defaulting to "css". If given overwrites other encoding information like @charset declarations')
    129      parser.add_option('-t', '--targetencoding', action='store',
    130                        dest='targetencoding',
    131          help='encoding of output, defaulting to "UTF-8"', default='utf-8')
    132      parser.add_option('-m', '--minify', action='store_true', dest='minify',
    133                        default=False,
    134          help='saves minified version of combined files, defaults to False')
    135      options, path = parser.parse_args()
    136
    137      if not path:
    138          parser.error('no path given')
    139      else:
    140          path = path[0]
    141
    142      print csscombine(path, options.sourceencoding, options.targetencoding,
    143                       options.minify)
    144
    145
    146  if __name__ == '__main__':
    147      sys.exit(main())
    148