From 5e0293325cf3506d63abbe526753effc6d0ebf62 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Thu, 28 Mar 2024 14:06:40 -0400 Subject: [PATCH] Handle spaces better in Markdown parse.ts. --- client/src/components/Markdown/parse.test.js | 27 +++++++++++++++++++ client/src/components/Markdown/parse.ts | 28 ++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/client/src/components/Markdown/parse.test.js b/client/src/components/Markdown/parse.test.js index d8b11134410e..ae3f929cb052 100644 --- a/client/src/components/Markdown/parse.test.js +++ b/client/src/components/Markdown/parse.test.js @@ -85,6 +85,33 @@ describe("parse.ts", () => { expect(result).toBe(output); }); + it("should work with double quotes for labels and spaces in the quotes", () => { + const input = + "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(footer='cow', output=\"from this\", title=dog)\n```\n"; + const output = + "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(footer='cow', output=\"to that\", title=dog)\n```\n"; + const result = replaceLabel(input, "output", "from this", "to that"); + expect(result).toBe(output); + }); + + it("should work with single quotes for labels and spaces in the quotes", () => { + const input = + "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(footer='cow', output='from this', title=dog)\n```\n"; + const output = + "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(footer='cow', output='to that', title=dog)\n```\n"; + const result = replaceLabel(input, "output", "from this", "to that"); + expect(result).toBe(output); + }); + + it("should add quotes when refactoring to labels with spaces", () => { + const input = + "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(footer='cow', output=fromthis, title=dog)\n```\n"; + const output = + "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(footer='cow', output='to that', title=dog)\n```\n"; + const result = replaceLabel(input, "output", "fromthis", "to that"); + expect(result).toBe(output); + }); + it("should leave non-arguments alone", () => { const input = "some random\n`markdown content`\n```galaxy\nhistory_dataset_embedded(title='cow from farm', output=from)\n```\n"; diff --git a/client/src/components/Markdown/parse.ts b/client/src/components/Markdown/parse.ts index 7a2ee3d1856a..1b51f03b4d3f 100644 --- a/client/src/components/Markdown/parse.ts +++ b/client/src/components/Markdown/parse.ts @@ -9,6 +9,9 @@ type Section = DefaultSection | GalaxyDirectiveSection; type WorkflowLabelKind = "input" | "output" | "step"; +const SINGLE_QUOTE = "'"; +const DOUBLE_QUOTE = '"'; + export function splitMarkdown(markdown: string, preserveWhitespace: boolean = false) { const sections: Section[] = []; const markdownErrors = []; @@ -78,8 +81,20 @@ export function replaceLabel( const newArgs = { ...args }; newArgs[labelType] = toLabel; const argRexExp = namedArgumentRegex(labelType); - const escapedToLabel = escapeRegExpReplacement(toLabel); - const content = directiveSection.content.replace(argRexExp, `$1${escapedToLabel}`); + let escapedToLabel = escapeRegExpReplacement(toLabel); + let incomingContent = directiveSection.content; + let content: string; + const match = incomingContent.match(argRexExp); + if (match) { + const firstMatch = match[0]; + if (escapedToLabel.indexOf(" ") >= 0) { + const quoteChar = getQuoteChar(firstMatch); + escapedToLabel = `${quoteChar}${escapedToLabel}${quoteChar}`; + } + content = incomingContent.replace(argRexExp, `$1${escapedToLabel}`); + } else { + content = incomingContent; + } return { name: directiveSection.name, args: newArgs, @@ -95,6 +110,15 @@ export function replaceLabel( return rewrittenMarkdown; } +function getQuoteChar(argMatch: string): string { + // this could be a lot stronger, handling escaping and such... + let quoteChar = SINGLE_QUOTE; + if (argMatch.indexOf(DOUBLE_QUOTE) >= 0) { + quoteChar = DOUBLE_QUOTE; + } + return quoteChar; +} + export function getArgs(content: string): GalaxyDirectiveSection { const galaxy_function = FUNCTION_CALL_LINE_TEMPLATE.exec(content); if (galaxy_function == null) {