/usr/lib/python3/dist-packages/lesscpy/scripts/compiler.py is in python3-lesscpy 0.13.0+ds-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | # -*- coding: utf8 -*-
"""
.. module:: lesscpy.scripts.compiler
CSS/LESSCSS run script
http://lesscss.org/#docs
Copyright (c)
See LICENSE for details
.. moduleauthor:: Johann T. Mariusson <jtm@robot.is>
"""
from __future__ import print_function
import os
import sys
import glob
import copy
import argparse
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
from lesscpy.lessc import parser
from lesscpy.lessc import lexer
from lesscpy.lessc import formatter
VERSION_STR = 'Lesscpy compiler 0.9h'
def ldirectory(inpath, outpath, args, scope):
"""Compile all *.less files in directory
Args:
inpath (str): Path to compile
outpath (str): Output directory
args (object): Argparse Object
scope (Scope): Scope object or None
"""
yacctab = 'yacctab' if args.debug else None
if not outpath:
sys.exit("Compile directory option needs -o ...")
else:
if not os.path.isdir(outpath):
if args.verbose:
print("Creating '%s'" % outpath, file=sys.stderr)
if not args.dry_run:
os.mkdir(outpath)
less = glob.glob(os.path.join(inpath, '*.less'))
f = formatter.Formatter(args)
for lf in less:
outf = os.path.splitext(os.path.basename(lf))
minx = '.min' if args.min_ending else ''
outf = "%s/%s%s.css" % (outpath, outf[0], minx)
if not args.force and os.path.exists(outf):
recompile = os.path.getmtime(outf) < os.path.getmtime(lf)
else:
recompile = True
if recompile:
print('%s -> %s' % (lf, outf))
p = parser.LessParser(yacc_debug=(args.debug),
lex_optimize=True,
yacc_optimize=(not args.debug),
scope=scope,
tabfile=yacctab,
verbose=args.verbose)
p.parse(filename=lf, debuglevel=0)
css = f.format(p)
if not args.dry_run:
with open(outf, 'w') as outfile:
outfile.write(css)
elif args.verbose:
print('skipping %s, not modified' % lf, file=sys.stderr)
sys.stdout.flush()
if args.recurse:
[ldirectory(os.path.join(inpath, name), os.path.join(outpath, name), args, scope)
for name in os.listdir(inpath)
if os.path.isdir(os.path.join(inpath, name)) and
not name.startswith('.') and not name == outpath]
def run():
"""Run compiler
"""
aparse = argparse.ArgumentParser(description='LessCss Compiler',
epilog='<< jtm@robot.is @_o >>')
aparse.add_argument('-v', '--version', action='version',
version=VERSION_STR)
aparse.add_argument('-I', '--include', action="store", type=str,
help="Included less-files (comma separated)")
aparse.add_argument('-V', '--verbose', action="store_true",
default=False, help="Verbose mode")
aparse.add_argument('-C', '--dont_create_dirs', action="store_true",
default=False, help="Creates directories when outputing files (lessc non-compatible)")
fgroup = aparse.add_argument_group('Formatting options')
fgroup.add_argument('-x', '--minify', action="store_true",
default=False, help="Minify output")
fgroup.add_argument('-X', '--xminify', action="store_true",
default=False, help="Minify output, no end of block newlines")
fgroup.add_argument('-t', '--tabs', help="Use tabs", action="store_true")
fgroup.add_argument(
'-s', '--spaces', help="Number of startline spaces (default 2)", default=2)
dgroup = aparse.add_argument_group('Directory options',
'Compiles all *.less files in directory that '
'have a newer timestamp than it\'s css file.')
dgroup.add_argument('-o', '--out', action="store", help="Output directory")
dgroup.add_argument(
'-r', '--recurse', action="store_true", help="Recursive into subdirectorys")
dgroup.add_argument(
'-f', '--force', action="store_true", help="Force recompile on all files")
dgroup.add_argument('-m', '--min-ending', action="store_true",
default=False, help="Add '.min' into output filename. eg, name.min.css")
dgroup.add_argument('-D', '--dry-run', action="store_true",
default=False, help="Dry run, do not write files")
group = aparse.add_argument_group('Debugging')
group.add_argument('-g', '--debug', action="store_true",
default=False, help="Debugging information")
group.add_argument('-S', '--scopemap', action="store_true",
default=False, help="Scopemap")
group.add_argument('-L', '--lex-only', action="store_true",
default=False, help="Run lexer on target")
group.add_argument('-N', '--no-css', action="store_true",
default=False, help="No css output")
aparse.add_argument('target', help="less file or directory")
aparse.add_argument('output', nargs='?', help="output file path")
args = aparse.parse_args()
try:
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
if args.lex_only:
lex = lexer.LessLexer()
ll = lex.file(args.target)
while True:
tok = ll.token()
if not tok:
break
if hasattr(tok, "lexer"): # literals don't have the lexer attribute
print(tok, "State:", tok.lexer.lexstate)
else:
print(tok)
print('EOF')
sys.exit()
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
yacctab = 'yacctab' if args.debug else None
scope = None
if args.include:
for u in args.include.split(','):
if os.path.exists(u):
p = parser.LessParser(yacc_debug=(args.debug),
lex_optimize=True,
yacc_optimize=(not args.debug),
tabfile=yacctab,
verbose=args.verbose)
p.parse(filename=u, debuglevel=args.debug)
if not scope:
scope = p.scope
else:
scope.update(p.scope)
else:
sys.exit('included file `%s` not found ...' % u)
sys.stdout.flush()
p = None
f = formatter.Formatter(args)
if not os.path.exists(args.target):
sys.exit("Target not found '%s' ..." % args.target)
if os.path.isdir(args.target):
ldirectory(args.target, args.out, args, scope)
if args.dry_run:
print('Dry run, nothing done.', file=sys.stderr)
else:
p = parser.LessParser(yacc_debug=(args.debug),
lex_optimize=True,
yacc_optimize=(not args.debug),
scope=copy.deepcopy(scope),
verbose=args.verbose)
p.parse(filename=args.target, debuglevel=args.debug)
if args.scopemap:
args.no_css = True
p.scopemap()
if not args.no_css and p:
out = f.format(p)
if args.output:
if not args.dont_create_dirs and not os.path.exists(os.path.dirname(args.output)):
try:
os.makedirs(os.path.dirname(args.output))
except OSError as exc: # Guard against race condition
if exc.errno != errno.EEXIST:
raise
with open(args.output, "w") as f:
f.write(out)
else:
print(out)
except (KeyboardInterrupt, SystemExit, IOError):
sys.exit('\nAborting...')
|