From 282fa9af82830c3a0d9525eef107f7bd6e3124c9 Mon Sep 17 00:00:00 2001 From: Daniel Soskey Date: Tue, 6 Aug 2024 13:50:54 -0700 Subject: [PATCH] added multiline support and updated default weight and mode editor indicators --- src/api/mtgql-ep/parser.test.ts | 25 ++++++++++++- src/api/mtgql-ep/parser.ts | 35 ++++++++++++++++--- .../component/editor/multiQueryActionBar.tsx | 14 ++++++-- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/api/mtgql-ep/parser.test.ts b/src/api/mtgql-ep/parser.test.ts index 224d290..e97eae4 100644 --- a/src/api/mtgql-ep/parser.test.ts +++ b/src/api/mtgql-ep/parser.test.ts @@ -1,4 +1,4 @@ -import { alias, parseQuerySet, replaceUse, venn } from './parser' +import { alias, parseQuerySet, replaceUse, unMultiline, venn } from './parser' import { Alias } from './types' import { weightAlgorithms } from '../queryRunnerCommon' @@ -10,6 +10,29 @@ describe('alias', function() { }) }) +describe('unMultiline', function() { + + it('should parse an alias real proper', function() { + const input = [ + "", + "jerp\\", + "clerp", + "shamp", + "champ \\", + "jamp \\", + "buppy", + ]; + + const result = unMultiline(input); + expect(result).toEqual([ + "", + "jerp clerp", + "shamp", + "champ jamp buppy" + ]) + }) +}) + describe('venn', function() { function newVenn(left: string, right: string) { return `@venn(${left})(${right})` diff --git a/src/api/mtgql-ep/parser.ts b/src/api/mtgql-ep/parser.ts index 1411a3e..452e82a 100644 --- a/src/api/mtgql-ep/parser.ts +++ b/src/api/mtgql-ep/parser.ts @@ -8,6 +8,8 @@ import cloneDeep from 'lodash/cloneDeep' const ALIAS_REGEXP = /^@(a|alias):/ export const VENN_REGEXP = /^@(v|venn)/ const DEFAULT_DOMAIN_REGEXP = /^@(dd|defaultDomain)\((.+)\)$/ +export const DEFAULT_WEIGHT_REGEXP = /^@(dw|defaultWeight):/ +export const DEFAULT_MODE_REGEXP = /^@(dm|defaultMode):/ export function alias(_line: string): Result { const line = _line.trim(); @@ -183,7 +185,7 @@ export function parseQueryEnv(lines: string[]): Result ({ query: "", displayMessage: e.message })) } +export function unMultiline(queries: string[]): string[] { + + const unMultilined: string[] = []; + let currentQuery: string[] = []; + for (const query of queries) { + currentQuery.push(query.replace(/\s*\\\s*$/, "")); + const trimmed = query.trim(); + if (!trimmed.endsWith("\\") && !trimmed.startsWith("#")) { + unMultilined.push(currentQuery.join(" ")); + currentQuery = []; + } + } + if (currentQuery.length) { + unMultilined.push(currentQuery.join(" ")); + } + return unMultilined +} + export function parseQuerySet( queries: string[], baseIndex: number ): Result { - return parseQueryEnv(queries) + const unMultilined = unMultiline(queries); + return parseQueryEnv(unMultilined) .andThen(queryEnv => { let selectedQueries: string[] = [] let currentIndex = baseIndex while (currentIndex < queries.length && queries[currentIndex].trim() !== "") { + // we need to get the index without collapsing multilines const query = queries[currentIndex].trim() if (ALIAS_REGEXP.test(query)) { const name = query.substring(query.indexOf(":") + 1, query.indexOf("(")) @@ -291,7 +313,9 @@ export function parseQuerySet( } currentIndex++ } - console.debug(selectedQueries) + // once we've selected our queries we can collapse multilines as we don't need the submitted index anymore + selectedQueries = unMultiline(selectedQueries); + console.debug("selected queries:", selectedQueries); if (selectedQueries.length === 0) { return err({ query: queries[baseIndex], @@ -315,7 +339,8 @@ export function parseQuerySet( .mapErr((errors) => ({ query: base, displayMessage: errors.join("\n") })); }) .mapErr((e: ParserError) => ({ query: base, displayMessage: `Error with venn query: ${e.message}\n\t${columnShower(base, e.offset)}`})) - } else if (queryEnv.defaultMode === 'allsub') { + } + if (queryEnv.defaultMode === 'allsub') { base = "" sub = selectedQueries } diff --git a/src/ui/component/editor/multiQueryActionBar.tsx b/src/ui/component/editor/multiQueryActionBar.tsx index 911b1e5..bf2cc63 100644 --- a/src/ui/component/editor/multiQueryActionBar.tsx +++ b/src/ui/component/editor/multiQueryActionBar.tsx @@ -2,6 +2,7 @@ import React from "react"; import { rankInfo } from "./infoLines"; import { useHighlightPrism } from "../../../api/local/syntaxHighlighting"; import { QuerySetButton } from "../querySetButton"; +import { DEFAULT_MODE_REGEXP, DEFAULT_WEIGHT_REGEXP } from '../../../api/mtgql-ep/parser' export const VENN_REGEXP = /^@(v|venn)\((.+)\)\((.+)\)$/; @@ -13,19 +14,28 @@ export const multiQueryInfo = } const result = []; let count = 0; + let isMultiline = false; for (const line of queries) { - if (line.trim().length === 0) { + const trimmed = line.trim(); + if (trimmed.length === 0) { result.push(" "); count = 0; - } else if (line.trimStart().startsWith("#")) { + } else if (trimmed.startsWith("#")) { result.push(" "); + } else if (count === 0 && DEFAULT_WEIGHT_REGEXP.test(trimmed)) { + result.push("WGHT"); + } else if (count === 0 && DEFAULT_MODE_REGEXP.test(trimmed)) { + result.push("MODE"); } else if (count === 0) { result.push(VENN_REGEXP.test(line.trim()) ? "VENN" : "BASE"); count += 1; + } else if (isMultiline) { + result.push(" "); } else { result.push(renderSubquery(count)); count += 1; } + isMultiline = !trimmed.startsWith("#") && trimmed.endsWith("\\"); } return result; };