Skip to content

Commit 8c8e7bb

Browse files
committed
Revamped options: should work with existing backends
1 parent 2752eed commit 8c8e7bb

File tree

16 files changed

+223
-121
lines changed

16 files changed

+223
-121
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { RegexEngine, RegexOption } from "@/engines/RegexEngine";
2+
import { PiArrowSquareOut } from "react-icons/pi";
3+
4+
5+
type OptionInputProps = {
6+
engine: RegexEngine;
7+
options: string[];
8+
};
9+
10+
function getBackendValue(option: RegexOption): string {
11+
12+
if (option.legacyCode) {
13+
return option.legacyCode;
14+
}
15+
return option.code;
16+
}
17+
18+
export default function OptionsInput({ engine, options }: OptionInputProps) {
19+
20+
const optionCheckboxes = engine.options.map((option) => {
21+
const optionValue = getBackendValue(option);
22+
23+
return (
24+
<div className="form-check" key={option.code}>
25+
<input className="form-check-input" type="checkbox" id={`option-${option.code}`} name="option" value={optionValue} defaultChecked={options.includes(option.code)} />
26+
<label className="form-check-label" htmlFor={`option-${option.code}`}>{option.description} (<code>{option.code}</code>)</label>
27+
</div>
28+
)});
29+
30+
return (
31+
<div className="mb-3">
32+
<label className="form-label">Options <small><a href="options.html" target="_new">Help<PiArrowSquareOut className="ms-2" /></a></small></label>
33+
<div className="row ms-1">
34+
{optionCheckboxes}
35+
</div>
36+
</div>
37+
);
38+
}

src/app/advanced/[engine]/index.html/TestForm.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
'use client'
22
import React, { useState } from 'react';
3-
import { PiArrowSquareOut } from "react-icons/pi";
43
import { runTest } from '@/engines';
54
import { TestInput } from '@/types/TestInput';
65
import { TestOutput } from '@/types/TestOutput';
76
import { TestResults } from '@/components/TestResults';
87
import { RegexEngine } from '@/engines/RegexEngine';
8+
import OptionsInput from './OptionsInput';
99

10-
type props = {
10+
type TestFormProps = {
1111
engine: RegexEngine;
1212
}
1313

14-
export default function TestForm({ engine }: props) {
14+
export default function TestForm({ engine }: TestFormProps) {
1515
const [testOutput, setTestOutput] = useState<TestOutput | null>();
1616
const [testInput, setTestInput] = useState<TestInput | null>();
1717

@@ -31,7 +31,7 @@ export default function TestForm({ engine }: props) {
3131
const localInput: TestInput = {
3232
regex: formData.get('regex') as string,
3333
replacement: formData.get('replacement') as string,
34-
options: formData.get('options') as string,
34+
option: formData.getAll('option') as string[],
3535
inputs: formData.getAll('input') as string[]
3636
};
3737
console.log(localInput);
@@ -58,17 +58,7 @@ export default function TestForm({ engine }: props) {
5858
<label htmlFor="replacement" className="form-label">Replacement</label>
5959
<input type="text" className="form-control" id="replacement" name="replacement" />
6060
</div>
61-
<div className="mb-3">
62-
<label htmlFor="options" className="form-label">Options</label>
63-
<div className="row">
64-
<div className="col-7 col-sm-6 col-md-4 col-lg-3 col-xl-2">
65-
<input type="text" className="form-control" id="options" name="options" />
66-
</div>
67-
<div className="col-5 col-sm-6 col-md-8 col-lg-9 col-xl-10">
68-
<a href="options.html" target="_new">Help<PiArrowSquareOut className="ms-2" /></a>
69-
</div>
70-
</div>
71-
</div>
61+
{ engine.options.length > 0 ? <OptionsInput engine={engine} options={[]} /> : <></> }
7262
<button type="submit" className="btn btn-primary">Test</button>
7363
{inputRows}
7464
<button type="submit" className="btn btn-primary">Test</button>

src/app/advanced/[engine]/options.html/page.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getEngine } from '@/engines';
2+
import { RegexOption } from '@/engines/RegexEngine';
23
import { notFound } from 'next/navigation';
34

45
export async function generateMetadata({ params }: { params: { engine: string } }) {
@@ -13,6 +14,16 @@ export async function generateMetadata({ params }: { params: { engine: string }
1314
}
1415
}
1516

17+
function OptionValue(theOption: RegexOption): string {
18+
if (theOption.numericCode) {
19+
return theOption.numericCode.toString();
20+
}
21+
if (theOption.legacyCode) {
22+
return theOption.legacyCode;
23+
}
24+
return theOption.code;
25+
}
26+
1627
export default function Page({ params }: { params: { engine: string } }) {
1728
const engine = getEngine(params.engine);
1829
if (!engine) {
@@ -29,13 +40,17 @@ export default function Page({ params }: { params: { engine: string } }) {
2940
<tr>
3041
<th>Option</th>
3142
<th>Description</th>
43+
<th>Backend value</th>
44+
<th>Portable value</th>
3245
</tr>
3346
</thead>
3447
<tbody>
3548
{engine.options.map((option) => (
3649
<tr key={option.code}>
3750
<td>{option.code}</td>
3851
<td>{option.description}</td>
52+
<td>{OptionValue(option)}</td>
53+
<td>{option.portableCode || <i className="text-muted">(not portable)</i>}</td>
3954
</tr>
4055
))}
4156
</tbody>

src/app/advanced/[engine]/results.html/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export async function GET(
3232
const testInput = {
3333
regex: "test",
3434
replacement: "test",
35-
options: "get",
35+
option: [],
3636
inputs: ["test"],
3737
};
3838

@@ -71,7 +71,7 @@ export async function POST(
7171
const testInput = {
7272
regex: (rawData.get("regex") || "") as string,
7373
replacement: (rawData.get("replacement") || "") as string,
74-
options: (rawData.get("options") || "") as string,
74+
option: (rawData.getAll("options") || "") as string[],
7575
inputs: (rawData.getAll("input") || []) as string[],
7676
};
7777

src/engines/RegexEngine.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
1-
type RegexOption = {
1+
2+
type PortableCodes = "ignorecase" | "multiline" | "comments" | "dotall";
3+
4+
export type RegexOption = {
25
code: string;
3-
value: string | number;
6+
legacyCode?: string; // for the original RegexPlanet backends
7+
portableCode?: PortableCodes; // for translating this code when switching to other engines
8+
numericCode?: number; // the value for engines that use a numeric bitmask for options
49
description: string;
5-
portable?: string;
10+
};
11+
12+
export type RegexExtraInput = {
13+
name: string; // name of the form field (used in the POST request)
14+
prompt: string; // text to display to the user
15+
element: JSX.Element; // the input element to display to gather the input
16+
help: string; // text to display to the user to help them fill out the form
17+
defaultValue: string; // the default value to use if the user doesn't provide one
618
};
719

820
type RegexEngine = {
921
description: string; // library or module name (do not include `short_name`)
1022
enabled: boolean; // always true for now
23+
extra_inputs?: RegexExtraInput[]; // A list of extra inputs to gather from the user
1124
help_label: string; // text for the help button on the testing page
1225
help_url: string; // URL destination for the help button on the testing page
1326
handle: string; // unique identifier for the language or engine used as the slug in URLs

src/engines/go.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ export const go: RegexEngine = {
1515
options: [
1616
{
1717
code: "posix",
18-
description:
19-
"POSIX ERE (egrep) syntax and leftmost-longest match semantics",
20-
value: "posix",
18+
description: "Use `CompilePOSIX` instead of `Compile`",
2119
},
2220
],
2321
option_notes: `The <code>posix</code> option is really a separate API call (<code>CompilePOSIX</code>). Other option need to be specified in the regex pattern.`,

src/engines/java.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,55 @@ export const java: RegexEngine = {
1717
options: [
1818
{
1919
code: "CANON_EQ",
20-
value: 128,
21-
description: "Enables canonical equivalence.",
20+
legacyCode: "canon",
21+
numericCode: 128,
22+
description: "Canonical equivalence.",
2223
},
2324
{
2425
code: "CASE_INSENSITIVE",
25-
value: 2,
26-
description: "Enables case-insensitive matching.",
26+
legacyCode: "ignorecase",
27+
portableCode: "ignorecase",
28+
numericCode: 2,
29+
description: "Case-insensitive matching.",
2730
},
2831
{
2932
code: "COMMENTS",
30-
value: 4,
31-
description: "Permits whitespace and comments in pattern.",
33+
legacyCode: "comments",
34+
portableCode: "comments",
35+
numericCode: 4,
36+
description: "Allow whitespace and comments in pattern.",
3237
},
33-
{ code: "DOTALL", value: 32, description: "Enables dotall mode." },
38+
{ code: "DOTALL", legacyCode: "dotall", numericCode: 32, description: "Enables dotall mode." },
3439
{
3540
code: "LITERAL",
36-
value: 16,
37-
description: "Enables literal parsing of the pattern.",
41+
legacyCode: "literal",
42+
numericCode: 16,
43+
description: "Literal parsing of the pattern.",
3844
},
39-
{ code: "MULTILINE", value: 8, description: "Enables multiline mode." },
4045
{
41-
code: "UNICODE_CASE",
42-
value: 64,
43-
description: " Enables Unicode-aware case folding.",
46+
code: "MULTILINE",
47+
legacyCode: "multiline",
48+
numericCode: 8,
49+
description: "Multiline mode.",
4450
},
4551
{
52+
code: "UNICODE_CASE",
53+
legacyCode: "unicode",
54+
numericCode: 64,
55+
description: "Unicode-aware case folding.",
56+
},
57+
/* LATER: enable when engine gets updated {
4658
code: "UNICODE_CHARACTER_CLASS",
47-
value: 256,
59+
numericCode: 256,
4860
description:
49-
"Enables the Unicode version of Predefined character classes and POSIX character classes.",
61+
"Use the Unicode version of Predefined character classes and POSIX character classes.",
62+
},*/
63+
{
64+
code: "UNIX_LINES",
65+
legacyCode: "unixline",
66+
numericCode: 1,
67+
description: "Unix lines mode.",
5068
},
51-
{ code: "UNIX_LINES", value: 1, description: "Enables Unix lines mode." },
5269
],
5370
short_name: "Java",
5471
source_url: "https://github.com/regexplanet/regexplanet-java",

src/engines/nodejs.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,44 +21,41 @@ export const nodejs: RegexEngine = {
2121
"https://nodeping.com/reports/checks/9z4pmj0b-ve3m-42s9-8s07-6c53rlel69iy",
2222
notfound: ["javascript", "typescript"],
2323
options: [
24-
{
24+
/*{
2525
code: "d",
26-
value: "d",
2726
description: "Generate indices for substring matches. (hasIndices)",
28-
},
29-
{ code: "g", value: "g", description: "Global search. (global)" },
27+
},*/
28+
{ code: "g",
29+
legacyCode: "global",
30+
description: "Global search. (global)" },
3031
{
3132
code: "i",
32-
value: "i",
33+
legacyCode: "ignorecase",
3334
description: "Case-insensitive search. (ignoreCase)",
3435
},
3536
{
3637
code: "m",
37-
value: "m",
38+
legacyCode: "multiline",
3839
description:
3940
"Allows ^ and $ to match next to newline characters. (multiline)",
4041
},
41-
{
42+
/*{
4243
code: "s",
43-
value: "s",
4444
description: "Allows . to match newline characters. (dotAll)",
4545
},
4646
{
4747
code: "u",
48-
value: "u",
4948
description: `"Unicode"; treat a pattern as a sequence of Unicode code points. (unicode)`,
5049
},
5150
{
5251
code: "v",
53-
value: "v",
5452
description:
5553
"An upgrade to the u mode with more Unicode features. (unicodeSets)",
5654
},
5755
{
5856
code: "y",
59-
value: "y",
6057
description: `Perform a "sticky" search that matches starting at the current position in the target string. (sticky)`,
61-
},
58+
},*/
6259
],
6360
short_name: "Node.js",
6461
source_url: "https://github.com/regexplanet/regexplanet-js",

src/engines/perl.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,32 @@ export const perl: RegexEngine = {
1616
nodeping_url:
1717
"https://nodeping.com/reports/checks/gkh86985-3ae2-4w7b-8opi-il8pki62v1ie",
1818
options: [
19-
{ code: "m", value: "m", description: "multiline" },
20-
{ code: "s", value: "s", description: "single line" },
21-
{ code: "i", value: "i", description: "case-insensitive" },
19+
{
20+
code: "m",
21+
legacyCode: "multiline",
22+
portableCode: "multiline",
23+
description: "Multiline",
24+
},
25+
{ code: "s", legacyCode: "dotall", description: "Single line" },
26+
{
27+
code: "i",
28+
legacyCode: "ignorecase",
29+
portableCode: "ignorecase",
30+
description: "Case-insensitive",
31+
},
2232
{
2333
code: "x",
24-
value: "x",
34+
legacyCode: "comment",
35+
portableCode: "comments",
2536
description: "Extended with whitespace and comments",
2637
},
27-
{ code: "p", value: "p", description: "Preserve matched strings" },
28-
{ code: "g", value: "g", description: "Global match" },
29-
{ code: "c", value: "c", description: "Keep current position" },
30-
{ code: "a", value: "a", description: "Use ASCII charset rules" },
31-
{ code: "d", value: "d", description: "Use default charset rules" },
32-
{ code: "l", value: "l", description: "Use locale charset rules" },
33-
{ code: "u", value: "u", description: "Use Unicode charset rules" },
38+
{ code: "p", legacyCode: "p", description: "Preserve matched strings" },
39+
{ code: "g", legacyCode: "global", description: "Global match" },
40+
{ code: "c", legacyCode: "c", description: "Keep current position" },
41+
{ code: "a", legacyCode: "a", description: "Use ASCII charset rules" },
42+
{ code: "d", legacyCode: "d", description: "Use default charset rules" },
43+
{ code: "l", legacyCode: "l", description: "Use locale charset rules" },
44+
{ code: "u", legacyCode: "u", description: "Use Unicode charset rules" },
3445
],
3546
option_notes: `When <code>m</code> and <code>s</code> together, <code>.</code> matches any char including newlines but <code>^</code> and <code>$</code> match lines.`,
3647
short_name: "Perl",

0 commit comments

Comments
 (0)