From 1e58be72b3ac295bc883406432f2fc0070f6a917 Mon Sep 17 00:00:00 2001 From: Alexander Kachkaev Date: Thu, 20 Dec 2018 21:06:59 +0000 Subject: [PATCH] Fix tuple parsing in elm-string-representation Closes #15 --- .../src/parse.test.ts | 37 +++++++++++++++++++ .../elm-string-representation/src/parse.ts | 32 +++++++++++----- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/packages/elm-string-representation/src/parse.test.ts b/packages/elm-string-representation/src/parse.test.ts index 6aacab9..87b2241 100644 --- a/packages/elm-string-representation/src/parse.test.ts +++ b/packages/elm-string-representation/src/parse.test.ts @@ -28,6 +28,17 @@ export const testCases: Array<{ b: 42, }, }, + { + input: ["{ x = True, y = False }"], + output: { + x: true, + y: false, + }, + }, + { + input: ['"{ x = True, y = False }"'], + output: "{ x = True, y = False }", + }, { input: [ '{ type = "geoshape", filled = False, visible = True, stroke = "#000", strokeWidth = 0.1 }', @@ -102,6 +113,32 @@ export const testCases: Array<{ b: 42, }, }, + { + input: ["( 1, 2 )", "(1,2)"], + output: [1, 2], + }, + { + input: ["[ ( 1, 2 ) ]", "[(1,2)]"], + output: [[1, 2]], + }, + { + input: ["[ ( 1, 2, 3 ), ( 4, 5, 6 ) ]", "[(1,2,3),(4,5,6)]"], + output: [[1, 2, 3], [4, 5, 6]], + }, + { + input: ['{ a = "test", b = (1, 2, 3) }'], + output: { + a: "test", + b: [1, 2, 3], + }, + }, + { + input: ['{ a = "(1, 2, 3)", b = (1, 2, 3) }'], + output: { + a: "(1, 2, 3)", + b: [1, 2, 3], + }, + }, { input: [ "{ x = {", diff --git a/packages/elm-string-representation/src/parse.ts b/packages/elm-string-representation/src/parse.ts index ddd0fca..cba72f1 100644 --- a/packages/elm-string-representation/src/parse.ts +++ b/packages/elm-string-representation/src/parse.ts @@ -20,21 +20,35 @@ export default (text: string): any => { return null; } - // Replacing using regexps is error-prone when searched - // strings are contained in values. - // The method should be rewritten as a tokenizer + // Replacing using regexps is potentially error-prone. + // The method may be rewritten as a tokenizer // and a grammar parser to avoid this. - const patchedInput = - text.charAt(0) !== "{" - ? text - : text + const inputChunks = text.split('"'); + const outputChunks: string[] = []; + + let insideString = false; + inputChunks.forEach((chunk) => { + if (insideString) { + outputChunks.push(chunk); + if (!chunk.endsWith("\\")) { + insideString = false; + } + } else { + outputChunks.push( + chunk .replace(/ = True/g, " = true") .replace(/ = False/g, " = false") - .replace(/(,|{)(| ([$a-zA-Z_0-9]+)) = /g, '$1 "$3": '); + .replace(/(,|{)(| ([$a-zA-Z_0-9]+)) = /g, '$1 "$3": ') + .replace(/\(/g, "[") + .replace(/\)/g, "]"), + ); + insideString = true; + } + }); try { return recursivelyConvertApplicableObjectsToArrays( - JSON.parse(patchedInput), + JSON.parse(outputChunks.join('"')), ); } catch (e) { throw new Error(