Author: esr
Date: Tue Apr 24 16:35:45 2007
New Revision: 17034
URL: http://svn.gna.org/viewcvs/wesnoth?rev=17034&view=rev
Log:
Refactor the Python mapconvert.py so the file-parsing logic is
separated from the line transformations.
Modified:
trunk/data/tools/map_convert.py
Modified: trunk/data/tools/map_convert.py
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/data/tools/map_convert.py?rev=17034&r1=17033&r2=17034&view=diff
==============================================================================
--- trunk/data/tools/map_convert.py (original)
+++ trunk/data/tools/map_convert.py Tue Apr 24 16:35:45 2007
@@ -77,9 +77,6 @@
}
max_len = max(*map(len, conversion.values()))
-def printUsage():
- print "map_convert.pl map_file.cfg [new_map_file.cfg]\n"
-
def get_adjacent(x, y, map):
"Returns string of original location+adjacent locations on hex 1-char map"
odd = (x) % 2
@@ -103,144 +100,156 @@
adj = adj.replace("\n", "").replace("\r", "")
return adj
-if len(sys.argv) < 3 or len(sys.argv) > 4:
- printUsage()
- sys.exit(1)
-
-sys.argv.pop(0)
-map_file = sys.argv.pop(0)
-if not sys.argv:
- new_map_file = map_file;
- backup = map_file + ".bak";
- try:
- os.system("cp %s %s" % (map_file, backup))
- except:
- sys.stderr.write("map_convert: could not create backup file: %s\n" %
backup)
+width = max_len+2
+
+def maptransform(input, baseline, inmap, y):
+ "Transform a map line from 1.2.x to 1.3.x format."
+ format = "%%%d.%ds" % (width, max_len)
+ x = 0
+ if "," in inmap[y]:
+ sys.stderr.write("mapconvert map file %s appears "
+ "to be converted already\n" % input)
sys.exit(1)
-else:
- new_map_file = sys.argv.pop(0)
- if os.path.exists(new_map_file):
- sys.stderr.write("map_convert: new map file already exists: %s\n"
%new_map_file)
- sys.exit(1)
-
-if not os.path.exists(map_file):
- sys.stderr.write("can not read map file: %s\n" % map_file)
- sys.exit(1)
-
-width = max_len+2
-
-# This hairy regexp excludes map_data lines that contain {} file references,
-# also lines that are empty or hold just one keep character (somewhat
-# pathological, but not handling these will make the regression tests break).
-mapdata = re.compile(r'map_data="[A-Za-z0-9\/|\\&_~?\[\]\']{2,}')
-
-mfile = []
-map_only = not map_file.endswith(".cfg")
-for line in open(map_file):
- mfile.append(line);
- if mapdata.search(line):
- map_only = False
-#mfile.append("\n")
-
-cont = False
-outmap = []
-newfile = []
-lineno = baseline = 0
-while mfile:
- line = mfile.pop(0)
- lineno += 1
- if map_only or mapdata.search(line):
- baseline = 0
- cont = True
- # Assumes map is more than 1 line long.
- if not map_only:
- line = line.split('"')[1]
- if line:
- outmap.append(line)
- while cont and mfile:
- line = mfile.pop(0)
- lineno += 1
- if line and line[0] == '#':
- newfile.append(line)
- continue
- if '"' in line:
- cont = False
- line = line.split('"')[0]
- if line and not line.endswith("\n"):
- line += "\n"
+ line = ''
+ for char in inmap[y]:
+ ohex = ''
+ if char in ('\n', '\r'):
+ ohex += char
+ elif char in conversion:
+ ohex = format % conversion[char] + ','
+ else:
+ sys.stderr.write('map_convert: "%s", line %d: unrecognized
character %s (%d) at (%d, %d)\n' % \
+ (input, baseline+y+1, `char`, ord(char), x, y))
+ # ohex = format % char
+ sys.exit(1)
+ if "_K" in ohex:
+ # Convert keeps according to adjacent hexes
+ adj = get_adjacent(x, y, inmap)
+ # print "adjacent: %s" % adj
+ hexcount = {}
+ for i in range(1, len(adj)):
+ # Intentionally skipping 0 as it is original hex
+ a = adj[i];
+ if not a in conversion:
+ sys.stderr.write('map_convert: "%s", line %d: error in
adjacent hexes at (%d, %d).\n' % \
+ (input, baseline+y+1, x, y))
+ sys.exit(1)
+ ca = conversion[a]
+ if ca.startswith("C"): #this is a castle hex
+ hexcount[ca] = hexcount.get(ca, 0) + 1
+ maxc = 0;
+ maxk = "Ch";
+ # Next line is a hack to make this code pass
+ # regression testing against the Perl
+ # original. Without the sort, when there are
+ # two terrain types that occur in equal
+ # numbers greater than any others, which one
+ # gets picked will be randomly dependent on
+ # Python's dictionary hash function.
+ sorted = hexcount.keys()
+ sorted.sort()
+ for k in sorted:
+ if hexcount[k] > maxc:
+ maxc = hexcount[k]
+ maxk = k
+ #print "Dominated by %s" % maxk
+ maxk = re.sub("^C", "K", maxk)
+ ohex = ohex.replace("_K", maxk)
+ line += ohex
+ x += 1
+ return line.replace(",\n", "\n")
+
+def texttransform(input, lineno, line):
+ "Identity transform on text lines."
+ return line
+
+def translator(input, output, mapxform, textxform):
+ "Apply mapxform to map lines and textxform to non-map lines."
+ # This hairy regexp excludes map_data lines that contain {} file
+ # references, also lines that are empty or hold just one keep
+ # character (somewhat pathological, but not handling these will
+ # make the regression tests break).
+ mapdata = re.compile(r'map_data="[A-Za-z0-9\/|\\&_~?\[\]\']{2,}')
+
+ mfile = []
+ map_only = not input.endswith(".cfg")
+ for line in open(input):
+ mfile.append(line);
+ if mapdata.search(line):
+ map_only = False
+
+ cont = False
+ outmap = []
+ newfile = []
+ lineno = baseline = 0
+ while mfile:
+ line = mfile.pop(0)
+ lineno += 1
+ if map_only or mapdata.search(line):
+ baseline = 0
+ cont = True
+ # Assumes map is more than 1 line long.
+ if not map_only:
+ line = line.split('"')[1]
if line:
outmap.append(line)
- if not map_only:
- line="map_data=\"\n";
- newfile.append(line)
- y = 0
- for oldline in outmap:
- x = 0
- if "," in oldline:
- sys.stderr.write("mapconvert map file %s appears "
- "to be converted already\n" % map_file)
- sys.exit(1)
- line = ''
- for char in oldline:
- ohex = ''
- format = "%%%d.%ds" % (width, max_len)
- if char in ('\n', '\r'):
- ohex += char
- elif char in conversion:
- ohex = format % conversion[char] + ','
- else:
- sys.stderr.write('map_convert: "%s", line %d: unrecognized
character %s (%d) at (%d, %d)\n' % \
- (map_file, baseline+y+1, `char`,
ord(char), x, y))
- # ohex = format % char
- sys.exit(1)
- if "_K" in ohex:
- # Convert keeps according to adjacent hexes
- adj = get_adjacent(x,y, outmap)
- # print "adjacent: %s" % adj
- hexcount = {}
- for i in range(1, len(adj)):
- # Intentionally skipping 0 as it is original hex
- a = adj[i];
- if not a in conversion:
- sys.stderr.write('map_convert: "%s", line %d:
error in adjacent hexes at (%d, %d).\n' % \
- (map_file, baseline+y+1, x, y))
- sys.exit(1)
- ca = conversion[a]
- if ca.startswith("C"): #this is a castle hex
- hexcount[ca] = hexcount.get(ca, 0) + 1
- maxc = 0;
- maxk = "Ch";
- # Next line is a hack to make this code pass regression
- # testing against the Perl original. Without the sort, when
- # there are two terrain types that occur in equal numbers
- # greater than any others, which one gets picked will be
- # randomly dependent on Python's dictionary hash function.
- sorted = hexcount.keys()
- sorted.sort()
- for k in sorted:
- if hexcount[k] > maxc:
- maxc = hexcount[k]
- maxk = k
- #print "Dominated by %s" % maxk
- maxk = re.sub("^C", "K", maxk)
- ohex = ohex.replace("_K", maxk)
- line += ohex
- x += 1
- # We've accumulated a translated map line
- newfile.append(line.replace(",\n", "\n"))
- y += 1
- # All lines of the map are processed, add the appropriate trailer
- if map_only:
- line="\n"
- else:
- line="\"\n"
- newfile.append(line)
+ while cont and mfile:
+ line = mfile.pop(0)
+ lineno += 1
+ if line and line[0] == '#':
+ newfile.append(line)
+ continue
+ if '"' in line:
+ cont = False
+ line = line.split('"')[0]
+ if line and not line.endswith("\n"):
+ line += "\n"
+ if line:
+ outmap.append(line)
+ if not map_only:
+ line="map_data=\"\n";
+ newfile.append(line)
+ for y in range(len(outmap)):
+ newfile.append(mapxform(input, baseline, outmap, y))
+ # All lines of the map are processed, add the appropriate trailer
+ if map_only:
+ line="\n"
+ else:
+ line="\"\n"
+ newfile.append(line)
+ else:
+ newfile.append(textxform(input, lineno, line))
+
+ ofp = open(output, "w");
+ ofp.writelines(newfile)
+ ofp.close()
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3 or len(sys.argv) > 4:
+ print "map_convert.py map_file.cfg [new_map_file.cfg]\n"
+ sys.exit(1)
+
+ sys.argv.pop(0)
+ map_file = sys.argv.pop(0)
+ if not sys.argv:
+ new_map_file = map_file;
+ backup = map_file + ".bak";
+ try:
+ os.system("cp %s %s" % (map_file, backup))
+ except:
+ sys.stderr.write("map_convert: could not create backup file: %s\n"
% backup)
+ sys.exit(1)
else:
- newfile.append(line)
-
-ofp = open(new_map_file, "w");
-ofp.writelines(newfile)
-ofp.close()
+ new_map_file = sys.argv.pop(0)
+ if os.path.exists(new_map_file):
+ sys.stderr.write("map_convert: new map file already exists: %s\n"
%new_map_file)
+ sys.exit(1)
+
+ if not os.path.exists(map_file):
+ sys.stderr.write("can not read map file: %s\n" % map_file)
+ sys.exit(1)
+
+ translator(map_file, new_map_file, maptransform, texttransform)
# map_convert ends here.
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits