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

Reply via email to