File indexing completed on 2024-05-19 04:56:28

0001 #!/usr/bin/env python3
0002 #
0003 # qmlpp - QML and JavaScript preprocessor
0004 # Based on https://katastrophos.net/andre/blog/2013/09/20/qml-preprocessor-the-qnd-and-kiss-way/
0005 # Converted to Python because it is already required to build Kid3.
0006 #
0007 # This library is free software; you can redistribute it and/or modify
0008 # it under the terms of the GNU Lesser General Public License version
0009 # 2.1 as published by the Free Software Foundation.
0010 
0011 import sys
0012 import os
0013 import re
0014 
0015 
0016 class QmlPreprocessor(object):
0017     def __init__(self, rewrite_qtquick_version, defines, process_inline):
0018         self.rewrite_qtquick_version = rewrite_qtquick_version
0019         self.definesre = re.compile(defines)
0020         self.process_inline = process_inline
0021         self.importre = re.compile(r'import QtQuick\s*\d.\d')
0022         self.uncommentre = re.compile(r'^(\s*)(//)?(.*)//@(.*)')
0023         self.deflinere = re.compile(r'^(\s*)(.*)//(@.*)')
0024 
0025     def preprocess_file(self, fn):
0026         lines = []
0027         with open(fn) as fh:
0028             for line in fh:
0029                 if '//!noRewrite' not in line:
0030                     line = self.importre.sub('import QtQuick ' +
0031                                              self.rewrite_qtquick_version, line)
0032                 line = self.uncommentre.sub(r'\1\3//@\4', line)
0033                 if not self.definesre.search(line):
0034                     line = self.deflinere.sub(r'\1//\2//\3', line)
0035                 if self.process_inline:
0036                     lines.append(line)
0037                 else:
0038                     sys.stdout.write(line)
0039         if self.process_inline:
0040             fh = open(fn, 'w')
0041             fh.writelines(lines)
0042             fh.close()
0043 
0044     def preprocess_directory(self, dirname):
0045         for root, dirs, files in os.walk(dirname):
0046             try:
0047                 dirs.remove('.git')
0048             except ValueError:
0049                 pass
0050             try:
0051                 dirs.remove('.svn')
0052             except ValueError:
0053                 pass
0054             for fn in files:
0055                 if fn.endswith(('.qml', '.js')):
0056                     self.preprocess_file(os.path.join(root, fn))
0057 
0058     def run(self, inp):
0059         if os.path.isfile(inp) or inp == '-':
0060             self.preprocess_file(inp)
0061         elif os.path.isdir(inp):
0062             if not self.process_inline:
0063                 raise Exception('Please specify -i when trying to preprocess '
0064                                 'a whole folder recursively.')
0065             self.preprocess_directory(inp)
0066         else:
0067             raise Exception('Please specify a valid file or folder.')
0068 
0069 
0070 def usage():
0071     print("""usage: %s [options] <filename JS or QML or directoryname>
0072 
0073 OPTIONS:
0074    -h                Show this message.
0075    -q <major.minor>  The version of QtQuick to rewrite to. Example: -q 2.1
0076    -d <defines>      The defines to set, separated by |. Example: -d "@QtQuick1|@Meego|@Debug"
0077    -i                Modify file in-place instead of dumping to stdout.
0078 """ % sys.argv[0])
0079 
0080 
0081 def main(argv):
0082     import getopt
0083     try:
0084         opts, args = getopt.getopt(argv, "hiq:d:")
0085     except getopt.GetoptError as err:
0086         print(str(err))
0087         usage()
0088         sys.exit(1)
0089     rewrite_qt_quick_version = ''
0090     defines = ''
0091     process_inline = False
0092     for o, a in opts:
0093         if o == '-q':
0094             rewrite_qt_quick_version = a
0095         elif o == '-d':
0096             defines = a
0097         elif o == '-i':
0098             process_inline = True
0099         elif o == '-h':
0100             usage()
0101             sys.exit(0)
0102     inp = args[0] if args else '.'
0103 
0104     # Shortcuts for Kid3: 4, 5 and U for Qt4, Qt5 and Ubuntu.
0105     if inp == '4':
0106         rewrite_qt_quick_version = '1.1'
0107         defines = '@QtQuick1|@!Ubuntu'
0108         process_inline = True
0109         inp = '.'
0110     elif inp == '5':
0111         rewrite_qt_quick_version = '2.2'
0112         defines = '@QtQuick2|@!Ubuntu'
0113         process_inline = True
0114         inp = '.'
0115     elif inp == 'U':
0116         rewrite_qt_quick_version = '2.2'
0117         defines = '@QtQuick2|@Ubuntu'
0118         process_inline = True
0119         inp = '.'
0120 
0121     qmlpp = QmlPreprocessor(rewrite_qt_quick_version, defines, process_inline)
0122     try:
0123         qmlpp.run(inp)
0124     except Exception as e:
0125         print(str(e))
0126         usage()
0127         sys.exit(1)
0128 
0129 if __name__ == '__main__':
0130     main(sys.argv[1:])