X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=lib%2Fscripts%2Fprefs2prefs.py;h=493ddf57bf6a15086656ace04802379b9140b38c;hb=639b5da1afe87ffe2fa4df3f738b838d6637f11a;hp=3026d061637e0acb4f45fa9b804e59f452d5568b;hpb=0fb13b648c2bf418412b8090d21c5801f2638eba;p=lyx.git diff --git a/lib/scripts/prefs2prefs.py b/lib/scripts/prefs2prefs.py index 3026d06163..493ddf57bf 100644 --- a/lib/scripts/prefs2prefs.py +++ b/lib/scripts/prefs2prefs.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python # -*- coding: utf-8 -*- # file prefs2prefs.py @@ -11,51 +10,53 @@ # This is the main file for the user preferences conversion system. # There are two subsidiary files: -# prefs2prefs_lfuns.py -# prefs2prefs_prefs.py +# prefs2prefs_lfuns.py +# prefs2prefs_prefs.py # The former is used to convert bind and ui files; the latter, to convert # the preferences file. # -# I've organized it this way because, in many ways, converting bind and ui -# files lfuns) and converting the preferences file are the same task. It's -# very line-by-line, unlike lyx2lyx and layout2layout, where changes can be -# more "global". So we read the file, line by line, and give a bunch of +# I've organized it this way because, in many ways, converting bind and ui +# files lfuns) and converting the preferences file are the same task. It's +# very line-by-line, unlike lyx2lyx and layout2layout, where changes can be +# more "global". So we read the file, line by line, and give a bunch of # converter functions a chance to see if they want to modify that line. -# The converter functions are all in the subsidiary files. They take a line -# as argument and return a list: (Bool, NewLine), where the Bool says if +# The converter functions are all in the subsidiary files. They take a line +# as argument and return a list: (Bool, NewLine), where the Bool says if # we've modified anything and the NewLine is the new line, if so, which will # be used to replace the old line. -# The format of the existing files is format 0, as of 2.0.alpha6. We'll +# The format of the existing files is format 0, as of 2.0.alpha6. We'll # introduce new format numbers as we proceed, just as with layout2layout. # These will be different for the bind and ui files and for the preferences -# file. +# file. +from __future__ import print_function import os, re, string, sys from getopt import getopt +import io ########################################################### # Utility functions, borrowed from layout2layout.py def trim_bom(line): - " Remove byte order mark." - if line[0:3] == "\357\273\277": - return line[3:] - else: - return line + " Remove byte order mark." + if line[0:3] == u"\357\273\277": + return line[3:] + else: + return line def read(source): - " Read input file and strip lineendings." - lines = source.read().splitlines() or [''] - lines[0] = trim_bom(lines[0]) - return lines + " Read input file and strip lineendings." + lines = source.read().splitlines() or [''] + lines[0] = trim_bom(lines[0]) + return lines def write(output, lines): - " Write output file with native lineendings." - output.write(os.linesep.join(lines) + os.linesep) + " Write output file with native lineendings." + output.write(os.linesep.join(lines) + os.linesep) # for use by find_format_lines @@ -63,140 +64,138 @@ re_comment = re.compile(r'^#') re_empty = re.compile(r'^\s*$') def find_format_line(lines): - ''' - Returns (bool, int), where int is number of the line the `Format' - specification is on, or else the number of the first non-blank, - non-comment line. The bool tells whether we found a format line. - ''' - for i in range(len(lines)): - l = lines[i] - if re_comment.search(l) or re_empty.search(l): - continue - m = re_format.search(l) - if m: - return (True, i) - # we're done when we have hit a non-comment, non-empty line - break - return (False, i) + ''' + Returns (bool, int), where int is number of the line the `Format' + specification is on, or else the number of the first non-blank, + non-comment line. The bool tells whether we found a format line. + ''' + for i in range(len(lines)): + l = lines[i] + if re_comment.search(l) or re_empty.search(l): + continue + m = re_format.search(l) + if m: + return (True, i) + # we're done when we have hit a non-comment, non-empty line + break + return (False, i) # for use by get_format re_format = re.compile(r'^Format\s+(\d+)\s*$') def get_format(lines): - " Gets format of current file and replaces the format line with a new one " - (found, format_line) = find_format_line(lines) - if not found: - return 0 - line = lines[format_line] - m = re_format.search(line) - if not m: - sys.stderr.write("Couldn't match format line!\n" + line + "\n") - sys.exit(1) - return int(m.group(1)) + " Gets format of current file and replaces the format line with a new one " + (found, format_line) = find_format_line(lines) + if not found: + return 0 + line = lines[format_line] + m = re_format.search(line) + if not m: + sys.stderr.write("Couldn't match format line!\n" + line + "\n") + sys.exit(1) + return int(m.group(1)) def update_format(lines): - " Writes new format line " - (found, format_line) = find_format_line(lines) - if not found: - lines[format_line:format_line] = ("Format 1", "") - return + " Writes new format line " + (found, format_line) = find_format_line(lines) + if not found: + lines[format_line:format_line] = ("Format 1", "") + return - line = lines[format_line] - m = re_format.search(line) - if not m: - sys.stderr.write("Couldn't match format line!\n" + line + "\n") - sys.exit(1) - format = int(m.group(1)) - lines[format_line] = "Format " + str(format + 1) + line = lines[format_line] + m = re_format.search(line) + if not m: + sys.stderr.write("Couldn't match format line!\n" + line + "\n") + sys.exit(1) + format = int(m.group(1)) + lines[format_line] = "Format " + str(format + 1) +def abort(msg): + sys.stderr.write("\n%s\n" % (msg)) + sys.exit(10) + # ########################################################### def usage(): - print "%s [-l] [-p] infile outfile" % sys.argv[0] - print "or: %s [-l] [-p] outfile" % sys.argv[0] - print " -l: convert LFUNs (bind and ui files)" - print " -p: convert preferences" - print "Note that exactly one of -l and -p is required." + print ("%s [-l] [-p] infile outfile" % sys.argv[0]) + print ("or: %s [-l] [-p] outfile" % sys.argv[0]) + print (" -l: convert LFUNs (bind and ui files)") + print (" -p: convert preferences") + print ("Note that exactly one of -l and -p is required.") def main(argv): - try: - (options, args) = getopt(sys.argv[1:], "lp") - except: - usage() - print "\nUnrecognized option" - sys.exit(1) - - opened_files = False - # Open files - if len(args) == 0: - source = sys.stdin - output = sys.stdout - elif len(args) == 2: - source = open(args[0], 'rb') - output = open(args[1], 'wb') - opened_files = True - else: - usage() - print "\nEither zero or two arguments must be given." - sys.exit(1) - - conversions = False - - for (opt, param) in options: - if opt == "-l": - from prefs2prefs_lfuns import conversions - elif opt == "-p": - from prefs2prefs_prefs import conversions - - if not conversions: - usage() - print "\nNeither -l nor -p given." - sys.exit(1) - elif len(options) > 1: - usage() - print "\nOnly one of -l or -p should be given." - sys.exit(1) - - current_format = len(conversions) - lines = read(source) - format = get_format(lines) - - while format < current_format: - target_format, convert = conversions[format] - old_format = format - - # make sure the conversion list is sequential - if int(old_format) + 1 != target_format: - sys.stderr.write("Something is wrong with the conversion chain.\n") - sys.exit(1) - - for c in convert: - for i in range(len(lines)): - (update, newline) = c(lines[i]) - if update: - lines[i] = newline - - update_format(lines) - format = get_format(lines) - - # sanity check - if int(old_format) + 1 != int(format): - sys.stderr.write("Failed to convert to new format!\n") - sys.exit(1) - - write(output, lines) - - # Close files - if opened_files: - source.close() - output.close() - - return 0 + try: + (options, args) = getopt(sys.argv[1:], "lp") + except: + usage() + abort("Unrecognized option") + + opened_files = False + # Open files + if len(args) == 0: + source = sys.stdin + output = sys.stdout + elif len(args) == 2: + source = io.open(args[0], 'r', encoding='utf_8', errors='surrogateescape') + output = io.open(args[1], 'w', encoding='utf_8', newline='\n') + opened_files = True + else: + usage() + abort("Either zero or two arguments must be given.") + + conversions = False + + for (opt, param) in options: + if opt == "-l": + from prefs2prefs_lfuns import conversions + elif opt == "-p": + from prefs2prefs_prefs import conversions + + if not conversions: + usage() + abort("Neither -l nor -p given.") + elif len(options) > 1: + usage() + abort("Only one of -l or -p should be given.") + + current_format = len(conversions) + lines = read(source) + format = get_format(lines) + + while format < current_format: + target_format, convert = conversions[format] + old_format = format + + # make sure the conversion list is sequential + if int(old_format) + 1 != target_format: + abort("Something is wrong with the conversion chain.") + + for c in convert: + for i in range(len(lines)): + (update, newline) = c(lines[i]) + if update: + lines[i] = newline + + update_format(lines) + format = get_format(lines) + + # sanity check + if int(old_format) + 1 != int(format): + abort("Failed to convert to new format!") + + write(output, lines) + + # Close files + if opened_files: + source.close() + output.close() + + return 0 if __name__ == "__main__":