Skip to content

Commit 5ce8bba

Browse files
committed
Automatic detection of map/tileset format
1 parent 2395dd3 commit 5ce8bba

File tree

6 files changed

+79
-28
lines changed

6 files changed

+79
-28
lines changed

pytiled_parser/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
# pylint: disable=too-few-public-methods
1313

1414
from .common_types import OrderedPair, Size
15+
from .exception import UnknownFormat
1516
from .layer import ImageLayer, Layer, LayerGroup, ObjectLayer, TileLayer
16-
from .parser import parse_map, parse_tmx
17+
from .parser import parse_map
1718
from .properties import Properties
1819
from .tiled_map import TiledMap
1920
from .tileset import Tile, Tileset

pytiled_parser/exception.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class UnknownFormat(Exception):
2+
pass

pytiled_parser/parser.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
from pathlib import Path
22

3+
from pytiled_parser import UnknownFormat
34
from pytiled_parser.parsers.json.tiled_map import parse as json_map_parse
45
from pytiled_parser.parsers.tmx.tiled_map import parse as tmx_map_parse
56
from pytiled_parser.tiled_map import TiledMap
7+
from pytiled_parser.util import check_format
68

79

810
def parse_map(file: Path) -> TiledMap:
911
"""Parse the raw Tiled map into a pytiled_parser type
1012
1113
Args:
12-
file: Path to the map's JSON file
14+
file: Path to the map file
1315
1416
Returns:
15-
TileSet: a properly typed TileSet.
17+
Tiledmap: a properly typed TiledMap
1618
"""
17-
# I have no idea why, but mypy thinks this function returns "Any"
18-
return json_map_parse(file) # type: ignore
19+
parser = check_format(file)
1920

20-
21-
def parse_tmx(file: Path) -> TiledMap:
22-
return tmx_map_parse(file) # type: ignore
21+
# The type ignores are because mypy for some reaosn thinks those functions return Any
22+
if parser == "tmx":
23+
return tmx_map_parse(file) # type: ignore
24+
elif parser == "json":
25+
return json_map_parse(file) # type: ignore
26+
else:
27+
raise UnknownFormat(
28+
"Unknown Map Format, please use either the TMX or JSON format."
29+
)

pytiled_parser/parsers/json/tiled_map.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import json
2+
import xml.etree.ElementTree as etree
23
from pathlib import Path
34
from typing import List, Union, cast
45

56
from typing_extensions import TypedDict
67

78
from pytiled_parser.common_types import Size
9+
from pytiled_parser.exception import UnknownFormat
810
from pytiled_parser.parsers.json.layer import RawLayer
911
from pytiled_parser.parsers.json.layer import parse as parse_layer
1012
from pytiled_parser.parsers.json.properties import RawProperty
1113
from pytiled_parser.parsers.json.properties import parse as parse_properties
1214
from pytiled_parser.parsers.json.tileset import RawTileSet
13-
from pytiled_parser.parsers.json.tileset import parse as parse_tileset
15+
from pytiled_parser.parsers.json.tileset import parse as parse_json_tileset
16+
from pytiled_parser.parsers.tmx.tileset import parse as parse_tmx_tileset
1417
from pytiled_parser.tiled_map import TiledMap, TilesetDict
15-
from pytiled_parser.util import parse_color
18+
from pytiled_parser.util import check_format, parse_color
1619

1720

1821
class RawTilesetMapping(TypedDict):
@@ -70,16 +73,30 @@ def parse(file: Path) -> TiledMap:
7073
if raw_tileset.get("source") is not None:
7174
# Is an external Tileset
7275
tileset_path = Path(parent_dir / raw_tileset["source"])
76+
parser = check_format(tileset_path)
7377
with open(tileset_path) as raw_tileset_file:
74-
tilesets[raw_tileset["firstgid"]] = parse_tileset(
75-
json.load(raw_tileset_file),
76-
raw_tileset["firstgid"],
77-
external_path=tileset_path.parent,
78-
)
78+
if parser == "json":
79+
tilesets[raw_tileset["firstgid"]] = parse_json_tileset(
80+
json.load(raw_tileset_file),
81+
raw_tileset["firstgid"],
82+
external_path=tileset_path.parent,
83+
)
84+
elif parser == "tmx":
85+
raw_tileset_external = etree.parse(raw_tileset_file).getroot()
86+
tilesets[raw_tileset["firstgid"]] = parse_tmx_tileset(
87+
raw_tileset_external,
88+
raw_tileset["firstgid"],
89+
external_path=tileset_path.parent,
90+
)
91+
else:
92+
raise UnknownFormat(
93+
"Unkown Tileset format, please use either the TSX or JSON format."
94+
)
95+
7996
else:
8097
# Is an embedded Tileset
8198
raw_tileset = cast(RawTileSet, raw_tileset)
82-
tilesets[raw_tileset["firstgid"]] = parse_tileset(
99+
tilesets[raw_tileset["firstgid"]] = parse_json_tileset(
83100
raw_tileset, raw_tileset["firstgid"]
84101
)
85102

@@ -120,7 +137,7 @@ def parse(file: Path) -> TiledMap:
120137
highest_firstgid = max(map_.tilesets.keys())
121138
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
122139
new_firstgid = highest_firstgid + last_tileset_count
123-
map_.tilesets[new_firstgid] = parse_tileset(
140+
map_.tilesets[new_firstgid] = parse_json_tileset(
124141
tiled_object.new_tileset,
125142
new_firstgid,
126143
tiled_object.new_tileset_path,

pytiled_parser/parsers/tmx/tiled_map.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import json
12
import xml.etree.ElementTree as etree
23
from pathlib import Path
34

45
from pytiled_parser.common_types import OrderedPair, Size
6+
from pytiled_parser.exception import UnknownFormat
7+
from pytiled_parser.parsers.json.tileset import parse as parse_json_tileset
58
from pytiled_parser.parsers.tmx.layer import parse as parse_layer
69
from pytiled_parser.parsers.tmx.properties import parse as parse_properties
7-
from pytiled_parser.parsers.tmx.tileset import parse as parse_tileset
10+
from pytiled_parser.parsers.tmx.tileset import parse as parse_tmx_tileset
811
from pytiled_parser.tiled_map import TiledMap, TilesetDict
9-
from pytiled_parser.util import parse_color
12+
from pytiled_parser.util import check_format, parse_color
1013

1114

1215
def parse(file: Path) -> TiledMap:
@@ -18,7 +21,6 @@ def parse(file: Path) -> TiledMap:
1821
Returns:
1922
TiledMap: A parsed TiledMap.
2023
"""
21-
print(file)
2224
with open(file) as map_file:
2325
raw_map = etree.parse(map_file).getroot()
2426

@@ -31,17 +33,29 @@ def parse(file: Path) -> TiledMap:
3133
if raw_tileset.attrib.get("source") is not None:
3234
# Is an external Tileset
3335
tileset_path = Path(parent_dir / raw_tileset.attrib["source"])
36+
parser = check_format(tileset_path)
3437
with open(tileset_path) as tileset_file:
35-
raw_tileset_external = etree.parse(tileset_file).getroot()
38+
if parser == "tmx":
39+
raw_tileset_external = etree.parse(tileset_file).getroot()
40+
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tmx_tileset(
41+
raw_tileset_external,
42+
int(raw_tileset.attrib["firstgid"]),
43+
external_path=tileset_path.parent,
44+
)
45+
elif parser == "json":
46+
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_json_tileset(
47+
json.load(tileset_file),
48+
int(raw_tileset.attrib["firstgid"]),
49+
external_path=tileset_path.parent,
50+
)
51+
else:
52+
raise UnknownFormat(
53+
"Unkown Tileset format, please use either the TSX or JSON format."
54+
)
3655

37-
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tileset(
38-
raw_tileset_external,
39-
int(raw_tileset.attrib["firstgid"]),
40-
external_path=tileset_path.parent,
41-
)
4256
else:
4357
# Is an embedded Tileset
44-
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tileset(
58+
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tmx_tileset(
4559
raw_tileset, int(raw_tileset.attrib["firstgid"])
4660
)
4761

@@ -83,7 +97,7 @@ def parse(file: Path) -> TiledMap:
8397
highest_firstgid = max(map_.tilesets.keys())
8498
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
8599
new_firstgid = highest_firstgid + last_tileset_count
86-
map_.tilesets[new_firstgid] = parse_tileset(
100+
map_.tilesets[new_firstgid] = parse_tmx_tileset(
87101
tiled_object.new_tileset,
88102
new_firstgid,
89103
tiled_object.new_tileset_path,

pytiled_parser/util.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Utility Functions for PyTiled"""
2+
from pathlib import Path
23

34
from pytiled_parser.common_types import Color
45

@@ -27,3 +28,12 @@ def parse_color(color: str) -> Color:
2728
)
2829

2930
raise ValueError("Improperly formatted color passed to parse_color")
31+
32+
33+
def check_format(file_path: Path) -> str:
34+
with open(file_path) as file:
35+
line = file.readline().rstrip().strip()
36+
if line[0] == "<":
37+
return "tmx"
38+
else:
39+
return "json"

0 commit comments

Comments
 (0)