2 # This file is part of LyX, the document processor.
3 # Licence details can be found in the file COPYING.
5 # author Richard Kimberly Heck
7 # Full author contact details are available in file CREDITS
9 # This is the main file for the user preferences conversion system.
10 # There are two subsidiary files:
11 # prefs2prefs_lfuns.py
12 # prefs2prefs_prefs.py
13 # The former is used to convert bind and ui files; the latter, to convert
14 # the preferences file. The converter functions are all in the subsidiary
17 # The format of the existing files was format 0, as of 2.0.alpha6.
19 import os, re, string, sys
20 from getopt import getopt
23 ###########################################################
24 # Utility functions, borrowed from layout2layout.py
27 " Remove byte order mark."
28 if line[0:3] == "\357\273\277":
35 " Read input file and strip lineendings."
36 lines = source.read().splitlines() or ['']
37 lines[0] = trim_bom(lines[0])
41 def write(output, lines):
42 " Write output file with native lineendings."
43 output.write(os.linesep.join(lines) + os.linesep)
46 # for use by find_format_lines
47 re_comment = re.compile(r'^#')
48 re_empty = re.compile(r'^\s*$')
50 def find_format_line(lines):
52 Returns (bool, int), where int is number of the line the `Format'
53 specification is on, or else the number of the first non-blank,
54 non-comment line. The bool tells whether we found a format line.
56 for i in range(len(lines)):
58 if re_comment.search(l) or re_empty.search(l):
60 m = re_format.search(l)
63 # we're done when we have hit a non-comment, non-empty line
68 # for use by get_format
69 re_format = re.compile(r'^Format\s+(\d+)\s*$')
71 def get_format(lines):
72 " Gets format of current file and replaces the format line with a new one "
73 (found, format_line) = find_format_line(lines)
76 line = lines[format_line]
77 m = re_format.search(line)
79 sys.stderr.write("Couldn't match format line!\n" + line + "\n")
81 return int(m.group(1))
84 def update_format(lines):
85 " Writes new format line "
86 (found, format_line) = find_format_line(lines)
88 lines[format_line:format_line] = ("Format 1", "")
91 line = lines[format_line]
92 m = re_format.search(line)
94 sys.stderr.write("Couldn't match format line!\n" + line + "\n")
96 format = int(m.group(1))
97 lines[format_line] = "Format " + str(format + 1)
101 sys.stderr.write("\n%s\n" % (msg))
105 ###########################################################
108 print ("%s [-l] [-p] infile outfile" % sys.argv[0])
109 print ("or: %s [-l] [-p] <infile >outfile" % sys.argv[0])
110 print (" -l: convert LFUNs (bind and ui files)")
111 print (" -p: convert preferences")
112 print ("Note that exactly one of -l and -p is required.")
117 (options, args) = getopt(sys.argv[1:], "lp")
120 abort("Unrecognized option")
128 source = open(args[0], encoding='utf_8', errors='surrogateescape')
129 output = open(args[1], 'w', encoding='utf_8', newline='\n')
133 abort("Either zero or two arguments must be given.")
137 for (opt, param) in options:
139 from prefs2prefs_lfuns import conversions
141 from prefs2prefs_prefs import conversions
145 abort("Neither -l nor -p given.")
146 elif len(options) > 1:
148 abort("Only one of -l or -p should be given.")
150 current_format = len(conversions)
152 format = get_format(lines)
154 while format < current_format:
155 target_format, convert = conversions[format]
158 # make sure the conversion list is sequential
159 if int(old_format) + 1 != target_format:
160 abort("Something is wrong with the conversion chain.")
164 # first see if the routine will accept a list of lines
167 # if not, it wants individual lines
168 for i in range(len(lines)):
169 (update, newline) = c(lines[i])
174 format = get_format(lines)
177 if int(old_format) + 1 != int(format):
178 abort("Failed to convert to new format!")
190 if __name__ == "__main__":