-import CoreGraphics
-import Foundation
-
-let VERTEX_PATTERN = "([^\\(]+?)[\\s]*\\([\\s]*([0-9]+.?[0-9]*)[\\s]*,[\\s]*([0-9]+.?[0-9]*)[\\s]*\\)"
-let EDGE_PATTERN = "(.+?)[\\s]*->[\\s]*(.+)"
-
-struct ParsedMap {
- let vertices: [Vertex]
- let edges: [MapEdge]
-}
-
-struct Vertex {
- let id: Int
- let label: String
- let position: CGPoint
-}
-
-struct MapEdge {
- let id: Int
- let origin: CGPoint
- let destination: CGPoint
-}
+extension Map {
+ static func parse(content: String) -> ParsedMap {
-// Extracts the vertices from the text
+ let parsers = [
+ AnyMapParserStrategy(VertexParserStrategy()),
+ AnyMapParserStrategy(EdgeParserStrategy()),
+ AnyMapParserStrategy(BlockerParserStrategy()),
+ AnyMapParserStrategy(OpportunityParserStrategy()),
+ AnyMapParserStrategy(StageParserStrategy()),
+ ]
+ let builder = MapBuilder()
-func parseVertices(_ text: String) -> [String: CGPoint] {
-
- var result: [String: CGPoint] = [:]
- let regex = try! NSRegularExpression(pattern: VERTEX_PATTERN, options: .caseInsensitive)
-
- let lines = text.split(whereSeparator: \.isNewline)
-
- for line in lines {
- let range = NSRange(location: 0, length: line.utf16.count)
- let matches = regex.matches(in: String(line), options: [], range: range)
-
- if matches.count > 0 && matches[0].numberOfRanges == 4{
+ let lines = content.split(whereSeparator: \.isNewline)
- let match = matches[0];
- let key = String(line[Range(match.range(at: 1), in: line)!])
- let xString = String(line[Range(match.range(at: 2), in: line)!])
- let yString = String(line[Range(match.range(at: 3), in: line)!])
- let x = CGFloat(truncating: NumberFormatter().number(from:xString) ?? 0.0)
- let y = CGFloat(truncating: NumberFormatter().number(from:yString) ?? 0.0)
- let point = CGPoint(x: x, y: y)
-
- result[key] = point
- }
- }
-
- return result
-}
-
-// Extracts the edges from the text
-
-func parseEdges(_ text: String, vertices: [String: CGPoint]) -> [MapEdge] {
-
- var result: [MapEdge] = []
- let regex = try! NSRegularExpression(pattern: EDGE_PATTERN, options: .caseInsensitive)
-
- let lines = text.split(whereSeparator: \.isNewline)
-
for (index, line) in lines.enumerated() {
- let range = NSRange(location: 0, length: line.utf16.count)
- let matches = regex.matches(in: String(line), options: [], range: range)
-
- if matches.count > 0 && matches[0].numberOfRanges == 3 {
-
- let match = matches[0];
- let vertexA = String(line[Range(match.range(at: 1), in: line)!])
- let vertexB = String(line[Range(match.range(at: 2), in: line)!])
-
- if let origin = vertices[vertexA] {
- if let destination = vertices[vertexB] {
- result.append(MapEdge(id: index, origin: origin, destination: destination))
- }
- }
+ for parser in parsers {
+ if parser.canHandle(line: String(line)) {
+ let (type, object) = parser.handle(
+ index: index, line: String(line), vertices: builder.vertices)
+ builder.addObjectToMap(type: type, object: object)
+ break
}
+ }
}
-
- return result
-}
-
-// Converts vetex dictionary to array
-
-func mapVertices(_ vertices: [String: CGPoint]) -> [Vertex] {
- var i = 0
- return vertices.map { label, position in
- i += 1;
- return Vertex(id: i, label: label, position: position)
- }
-}
-extension Map {
- func parse() -> ParsedMap {
-
- let text = self.content ?? ""
- let vertices = parseVertices(text)
- let mappedVertices = mapVertices(vertices)
- let edges = parseEdges(text, vertices: vertices)
- print(mappedVertices)
- print(edges)
-
- return ParsedMap(vertices: mappedVertices, edges: edges)
- }
+ return builder.build()
+ }
}