1*cdf0e10cSrcweir#!/usr/bin/env python 2*cdf0e10cSrcweir 3*cdf0e10cSrcweirimport getopt 4*cdf0e10cSrcweirimport os 5*cdf0e10cSrcweirimport re 6*cdf0e10cSrcweirimport sys 7*cdf0e10cSrcweir# 8*cdf0e10cSrcweirfrom srclexer import SrcLexer 9*cdf0e10cSrcweirfrom srcparser import SrcParser 10*cdf0e10cSrcweirfrom boxer import Boxer 11*cdf0e10cSrcweir# FIXME 12*cdf0e10cSrcweirfrom globals import * 13*cdf0e10cSrcweir 14*cdf0e10cSrcweirdef option_parser (): 15*cdf0e10cSrcweir import optparse 16*cdf0e10cSrcweir p = optparse.OptionParser () 17*cdf0e10cSrcweir 18*cdf0e10cSrcweir p.usage = '''src2xml.py [OPTION]... SRC-FILE...''' 19*cdf0e10cSrcweir 20*cdf0e10cSrcweir examples = ''' 21*cdf0e10cSrcweirExamples: 22*cdf0e10cSrcweir src2xml.py --output-dir=. --post-process --ignore-includes zoom.src 23*cdf0e10cSrcweir src2xml.py --dry-run -I svx/inc -I svx/source/dialog zoom.src 24*cdf0e10cSrcweir''' 25*cdf0e10cSrcweir 26*cdf0e10cSrcweir def format_examples (self): 27*cdf0e10cSrcweir return examples 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir if 'epilog' in p.__dict__: 30*cdf0e10cSrcweir p.formatter.format_epilog = format_examples 31*cdf0e10cSrcweir p.epilog = examples 32*cdf0e10cSrcweir else: 33*cdf0e10cSrcweir p.formatter.format_description = format_examples 34*cdf0e10cSrcweir p.description = examples 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir p.description = '''OOo SRC To Layout XML Converter. 37*cdf0e10cSrcweir 38*cdf0e10cSrcweirConvert OO.o's existing dialog resource files into XML layout files. 39*cdf0e10cSrcweir''' 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir p.add_option ('-l', '--debug-lexer', action='store_true', 42*cdf0e10cSrcweir dest='debug_lexer', default=False, 43*cdf0e10cSrcweir help='debug lexer') 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir p.add_option ('-p', '--debug-parser', action='store_true', 46*cdf0e10cSrcweir dest='debug_parser', default=False, 47*cdf0e10cSrcweir help='debug parser') 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir p.add_option ('-m', '--debug-macro', action='store_true', 50*cdf0e10cSrcweir dest='debug_macro', default=False, 51*cdf0e10cSrcweir help='debug macro') 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir p.add_option ('-n', '--dry-run', action='store_true', 54*cdf0e10cSrcweir dest='dry_run', default=False, 55*cdf0e10cSrcweir help='dry run') 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir p.add_option ('-k', '--keep-going', action='store_true', 58*cdf0e10cSrcweir dest='keep_going', default=False, 59*cdf0e10cSrcweir help='continue after error') 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir p.add_option ('-i', '--ignore-includes', action='store_true', 62*cdf0e10cSrcweir dest='ignore_includes', default=False, 63*cdf0e10cSrcweir help='ignore #include directives') 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir p.add_option ('-I', '--include-dir', action='append', 66*cdf0e10cSrcweir dest='include_path', 67*cdf0e10cSrcweir default=[], 68*cdf0e10cSrcweir metavar='DIR', 69*cdf0e10cSrcweir help='append DIR to include path') 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir def from_file (option, opt_str, value, parser): 72*cdf0e10cSrcweir lst = getattr (parser.values, option.dest) 73*cdf0e10cSrcweir lst += file (value).read ().split ('\n') 74*cdf0e10cSrcweir setattr (parser.values, option.dest, lst) 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir def from_path (option, opt_str, value, parser): 77*cdf0e10cSrcweir lst = getattr (parser.values, option.dest) 78*cdf0e10cSrcweir lst += value.split (':') 79*cdf0e10cSrcweir setattr (parser.values, option.dest, lst) 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir # Junk me? 82*cdf0e10cSrcweir p.add_option ('--includes-from-file', action='callback', callback=from_file, 83*cdf0e10cSrcweir dest='include_path', 84*cdf0e10cSrcweir default=[], 85*cdf0e10cSrcweir type='string', 86*cdf0e10cSrcweir metavar='FILE', 87*cdf0e10cSrcweir help='append directory list from FILE to include path') 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir p.add_option ('--include-path', action='callback', callback=from_path, 90*cdf0e10cSrcweir dest='include_path', 91*cdf0e10cSrcweir type='string', 92*cdf0e10cSrcweir default=[], 93*cdf0e10cSrcweir metavar='PATH', 94*cdf0e10cSrcweir help='append PATH to include path') 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir p.add_option ('--only-expand-macros', action='store_true', 97*cdf0e10cSrcweir dest='only_expand_macros', default=False, 98*cdf0e10cSrcweir help='FIXME: better to say what NOT to expand?') 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir p.add_option ('-o', '--output-dir', action='store', 101*cdf0e10cSrcweir dest='output_dir', default=None, 102*cdf0e10cSrcweir metavar='DIR', 103*cdf0e10cSrcweir help='Output to DIR') 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir p.add_option ('-s', '--post-process', action='store_true', 106*cdf0e10cSrcweir dest='post_process', default=False, 107*cdf0e10cSrcweir help='post process output for use in Layout') 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir p.add_option ('--stop-on-header', action='store_true', 110*cdf0e10cSrcweir dest='stopOnHeader', default=False, 111*cdf0e10cSrcweir help='FIXME: remove this?') 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir return p 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir 116*cdf0e10cSrcweirdef convert (file_name, options): 117*cdf0e10cSrcweir progress ("parsing %(file_name)s ..." % locals ()) 118*cdf0e10cSrcweir fullpath = os.path.abspath(file_name) 119*cdf0e10cSrcweir if not os.path.isfile(fullpath): 120*cdf0e10cSrcweir error("no such file", exit=True) 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir ##options.include_path.append (os.path.dirname (fullpath)) 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir input = file (fullpath, 'r').read() 125*cdf0e10cSrcweir lexer = SrcLexer(input, fullpath) 126*cdf0e10cSrcweir lexer.expandHeaders = not options.ignore_includes 127*cdf0e10cSrcweir lexer.includeDirs = options.include_path 128*cdf0e10cSrcweir lexer.stopOnHeader = options.stopOnHeader 129*cdf0e10cSrcweir lexer.debugMacro = options.debug_macro 130*cdf0e10cSrcweir if options.debug_lexer: 131*cdf0e10cSrcweir lexer.debug = True 132*cdf0e10cSrcweir lexer.tokenize() 133*cdf0e10cSrcweir progress ("-"*68 + "\n") 134*cdf0e10cSrcweir progress ("** token dump\n") 135*cdf0e10cSrcweir lexer.dumpTokens() 136*cdf0e10cSrcweir progress ("** end of token dump\n") 137*cdf0e10cSrcweir return 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir # Tokenize it using lexer 140*cdf0e10cSrcweir lexer.tokenize() 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir parser = SrcParser(lexer.getTokens(), lexer.getDefines()) 143*cdf0e10cSrcweir parser.only_expand_macros = options.only_expand_macros 144*cdf0e10cSrcweir if options.debug_parser: 145*cdf0e10cSrcweir parser.debug = True 146*cdf0e10cSrcweir root = parser.parse() 147*cdf0e10cSrcweir s = root.dump() 148*cdf0e10cSrcweir return s 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir # Parse the tokens. 151*cdf0e10cSrcweir root = parser.parse() 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir # Box it, and return the XML tree. 154*cdf0e10cSrcweir root = Boxer(root).layout() 155*cdf0e10cSrcweir output = root.dump() 156*cdf0e10cSrcweir if not options.dry_run: 157*cdf0e10cSrcweir progress ("\n") 158*cdf0e10cSrcweir return output 159*cdf0e10cSrcweir 160*cdf0e10cSrcweirdef dry_one_file (file_name, options): 161*cdf0e10cSrcweir try: 162*cdf0e10cSrcweir str = convert(file_name, options) 163*cdf0e10cSrcweir progress (" SUCCESS\n") 164*cdf0e10cSrcweir except Exception, e: 165*cdf0e10cSrcweir if options.keep_going: 166*cdf0e10cSrcweir progress (" FAILED\n") 167*cdf0e10cSrcweir else: 168*cdf0e10cSrcweir import traceback 169*cdf0e10cSrcweir print traceback.format_exc (None) 170*cdf0e10cSrcweir raise e 171*cdf0e10cSrcweir 172*cdf0e10cSrcweirdef post_process (s): 173*cdf0e10cSrcweir """Make output directly usable by layout module.""" 174*cdf0e10cSrcweir s = re.sub ('(</?)([a-z]+)-([a-z]+)-([a-z]+)', r'\1\2\3\4', s) 175*cdf0e10cSrcweir s = re.sub ('(</?)([a-z]+)-([a-z]+)', r'\1\2\3', s) 176*cdf0e10cSrcweir s = re.sub ('(<(checkbox|(cancel|help|ignore|ok|push|more|no|radio|reset|retry|yes)button|(fixed(info|text)))[^>]*) text=', r'\1 label=', s) 177*cdf0e10cSrcweir s = re.sub (' (height|width|x|y)="[0-9]*"', '', s) 178*cdf0e10cSrcweir s = re.sub (' (label|text|title)="', r' _\1="', s) 179*cdf0e10cSrcweir s = re.sub ('&([^m][^p]*[^;]*)', r'&\1', s) 180*cdf0e10cSrcweir s = re.sub (' hide="(TRUE|true|1)"', ' show="false"', s) 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir s = s.replace ('<modaldialog', '<modaldialog sizeable="true"') 183*cdf0e10cSrcweir s = s.replace (' rid=', ' id=') 184*cdf0e10cSrcweir s = s.replace (' border="true"', ' has_border="true"') 185*cdf0e10cSrcweir s = s.replace (' def-button="true"', ' defbutton="true"') 186*cdf0e10cSrcweir s = s.replace (' drop-down="', ' dropdown="') 187*cdf0e10cSrcweir s = s.replace (' tab-stop="', ' tabstop="') 188*cdf0e10cSrcweir return s 189*cdf0e10cSrcweir 190*cdf0e10cSrcweirXML_HEADER = '''<?xml version="1.0" encoding="UTF-8"?> 191*cdf0e10cSrcweir<!-- This is a template. i18n translation is not performed in-place; 192*cdf0e10cSrcweir i18n translated XML files are generated from this template by 193*cdf0e10cSrcweir transex3/layout/tralay. !--> 194*cdf0e10cSrcweir''' 195*cdf0e10cSrcweir 196*cdf0e10cSrcweirdef do_one_file (file_name, options): 197*cdf0e10cSrcweir str = XML_HEADER 198*cdf0e10cSrcweir str += convert(file_name, options) 199*cdf0e10cSrcweir str += '\n' 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir if options.post_process: 202*cdf0e10cSrcweir str = post_process (str) 203*cdf0e10cSrcweir h = sys.stdout 204*cdf0e10cSrcweir if options.output_dir: 205*cdf0e10cSrcweir base = os.path.basename (file_name) 206*cdf0e10cSrcweir root, ext = os.path.splitext (base) 207*cdf0e10cSrcweir out_name = options.output_dir + '/' + root + '.xml' 208*cdf0e10cSrcweir progress ("writing %(out_name)s ..." % locals ()) 209*cdf0e10cSrcweir h = file (out_name, 'w') 210*cdf0e10cSrcweir h.write (str) 211*cdf0e10cSrcweir h.flush () 212*cdf0e10cSrcweir progress ("\n") 213*cdf0e10cSrcweir 214*cdf0e10cSrcweirdef main (): 215*cdf0e10cSrcweir p = option_parser () 216*cdf0e10cSrcweir (options, files) = option_parser ().parse_args () 217*cdf0e10cSrcweir if not files: 218*cdf0e10cSrcweir p.error ("no input files") 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir for f in files: 221*cdf0e10cSrcweir if options.dry_run: 222*cdf0e10cSrcweir dry_one_file (f, options) 223*cdf0e10cSrcweir else: 224*cdf0e10cSrcweir do_one_file (f, options) 225*cdf0e10cSrcweir 226*cdf0e10cSrcweirif __name__ == '__main__': 227*cdf0e10cSrcweir main () 228