diff options
Diffstat (limited to 'toolkit/src2xml/source/src2xml.py')
-rw-r--r-- | toolkit/src2xml/source/src2xml.py | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/toolkit/src2xml/source/src2xml.py b/toolkit/src2xml/source/src2xml.py new file mode 100644 index 000000000000..b03c5e61ede1 --- /dev/null +++ b/toolkit/src2xml/source/src2xml.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +import getopt +import os +import re +import sys +# +from srclexer import SrcLexer +from srcparser import SrcParser +from boxer import Boxer +# FIXME +from globals import * + +def option_parser (): + import optparse + p = optparse.OptionParser () + + p.usage = '''src2xml.py [OPTION]... SRC-FILE...''' + + examples = ''' +Examples: + src2xml.py --output-dir=. --post-process --ignore-includes zoom.src + src2xml.py --dry-run -I svx/inc -I svx/source/dialog zoom.src +''' + + def format_examples (self): + return examples + + if 'epilog' in p.__dict__: + p.formatter.format_epilog = format_examples + p.epilog = examples + else: + p.formatter.format_description = format_examples + p.description = examples + + p.description = '''OOo SRC To Layout XML Converter. + +Convert OO.o's existing dialog resource files into XML layout files. +''' + + p.add_option ('-l', '--debug-lexer', action='store_true', + dest='debug_lexer', default=False, + help='debug lexer') + + p.add_option ('-p', '--debug-parser', action='store_true', + dest='debug_parser', default=False, + help='debug parser') + + p.add_option ('-m', '--debug-macro', action='store_true', + dest='debug_macro', default=False, + help='debug macro') + + p.add_option ('-n', '--dry-run', action='store_true', + dest='dry_run', default=False, + help='dry run') + + p.add_option ('-k', '--keep-going', action='store_true', + dest='keep_going', default=False, + help='continue after error') + + p.add_option ('-i', '--ignore-includes', action='store_true', + dest='ignore_includes', default=False, + help='ignore #include directives') + + p.add_option ('-I', '--include-dir', action='append', + dest='include_path', + default=[], + metavar='DIR', + help='append DIR to include path') + + def from_file (option, opt_str, value, parser): + lst = getattr (parser.values, option.dest) + lst += file (value).read ().split ('\n') + setattr (parser.values, option.dest, lst) + + def from_path (option, opt_str, value, parser): + lst = getattr (parser.values, option.dest) + lst += value.split (':') + setattr (parser.values, option.dest, lst) + + # Junk me? + p.add_option ('--includes-from-file', action='callback', callback=from_file, + dest='include_path', + default=[], + type='string', + metavar='FILE', + help='append directory list from FILE to include path') + + p.add_option ('--include-path', action='callback', callback=from_path, + dest='include_path', + type='string', + default=[], + metavar='PATH', + help='append PATH to include path') + + p.add_option ('--only-expand-macros', action='store_true', + dest='only_expand_macros', default=False, + help='FIXME: better to say what NOT to expand?') + + p.add_option ('-o', '--output-dir', action='store', + dest='output_dir', default=None, + metavar='DIR', + help='Output to DIR') + + p.add_option ('-s', '--post-process', action='store_true', + dest='post_process', default=False, + help='post process output for use in Layout') + + p.add_option ('--stop-on-header', action='store_true', + dest='stopOnHeader', default=False, + help='FIXME: remove this?') + + return p + + +def convert (file_name, options): + progress ("parsing %(file_name)s ..." % locals ()) + fullpath = os.path.abspath(file_name) + if not os.path.isfile(fullpath): + error("no such file", exit=True) + + ##options.include_path.append (os.path.dirname (fullpath)) + + input = file (fullpath, 'r').read() + lexer = SrcLexer(input, fullpath) + lexer.expandHeaders = not options.ignore_includes + lexer.includeDirs = options.include_path + lexer.stopOnHeader = options.stopOnHeader + lexer.debugMacro = options.debug_macro + if options.debug_lexer: + lexer.debug = True + lexer.tokenize() + progress ("-"*68 + "\n") + progress ("** token dump\n") + lexer.dumpTokens() + progress ("** end of token dump\n") + return + + # Tokenize it using lexer + lexer.tokenize() + + parser = SrcParser(lexer.getTokens(), lexer.getDefines()) + parser.only_expand_macros = options.only_expand_macros + if options.debug_parser: + parser.debug = True + root = parser.parse() + s = root.dump() + return s + + # Parse the tokens. + root = parser.parse() + + # Box it, and return the XML tree. + root = Boxer(root).layout() + output = root.dump() + if not options.dry_run: + progress ("\n") + return output + +def dry_one_file (file_name, options): + try: + str = convert(file_name, options) + progress (" SUCCESS\n") + except Exception, e: + if options.keep_going: + progress (" FAILED\n") + else: + import traceback + print traceback.format_exc (None) + raise e + +def post_process (s): + """Make output directly usable by layout module.""" + s = re.sub ('(</?)([a-z]+)-([a-z]+)-([a-z]+)', r'\1\2\3\4', s) + s = re.sub ('(</?)([a-z]+)-([a-z]+)', r'\1\2\3', s) + s = re.sub ('(<(checkbox|(cancel|help|ignore|ok|push|more|no|radio|reset|retry|yes)button|(fixed(info|text)))[^>]*) text=', r'\1 label=', s) + s = re.sub (' (height|width|x|y)="[0-9]*"', '', s) + s = re.sub (' (label|text|title)="', r' _\1="', s) + s = re.sub ('&([^m][^p]*[^;]*)', r'&\1', s) + s = re.sub (' hide="(TRUE|true|1)"', ' show="false"', s) + + s = s.replace ('<modaldialog', '<modaldialog sizeable="true"') + s = s.replace (' rid=', ' id=') + s = s.replace (' border="true"', ' has_border="true"') + s = s.replace (' def-button="true"', ' defbutton="true"') + s = s.replace (' drop-down="', ' dropdown="') + s = s.replace (' tab-stop="', ' tabstop="') + return s + +XML_HEADER = '''<?xml version="1.0" encoding="UTF-8"?> +<!-- This is a template. i18n translation is not performed in-place; + i18n translated XML files are generated from this template by + transex3/layout/tralay. !--> +''' + +def do_one_file (file_name, options): + str = XML_HEADER + str += convert(file_name, options) + str += '\n' + + if options.post_process: + str = post_process (str) + h = sys.stdout + if options.output_dir: + base = os.path.basename (file_name) + root, ext = os.path.splitext (base) + out_name = options.output_dir + '/' + root + '.xml' + progress ("writing %(out_name)s ..." % locals ()) + h = file (out_name, 'w') + h.write (str) + h.flush () + progress ("\n") + +def main (): + p = option_parser () + (options, files) = option_parser ().parse_args () + if not files: + p.error ("no input files") + + for f in files: + if options.dry_run: + dry_one_file (f, options) + else: + do_one_file (f, options) + +if __name__ == '__main__': + main () |