Skip to content

Commit f5efac9

Browse files
committed
require full match for catching case convention errors. Closes #4114.
1 parent 9bd7c1f commit f5efac9

File tree

4 files changed

+121
-57
lines changed

4 files changed

+121
-57
lines changed

src/core/lib/text.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,20 @@ export function detectCaseConvention(
165165
if (key.toLocaleLowerCase() !== key) {
166166
return "capitalizationCase";
167167
}
168-
if (key.indexOf("_") !== -1) {
168+
const underscoreIndex = key.indexOf("_");
169+
if (
170+
underscoreIndex !== -1 &&
171+
underscoreIndex !== 0 &&
172+
underscoreIndex !== key.length - 1
173+
) {
169174
return "underscore_case";
170175
}
171-
if (key.indexOf("-") !== -1) {
176+
const dashIndex = key.indexOf("-");
177+
if (
178+
dashIndex !== -1 &&
179+
dashIndex !== 0 &&
180+
dashIndex !== key.length - 1
181+
) {
172182
return "dash-case";
173183
}
174184
return undefined;
@@ -236,7 +246,7 @@ export function resolveCaseConventionRegex(
236246
}
237247

238248
return {
239-
pattern: `^(?!(${disallowedNearMisses.join("|")}))`,
249+
pattern: `(?!(${disallowedNearMisses.map((c) => `^${c}$`).join("|")}))`,
240250
list: Array.from(foundConventions),
241251
};
242252
}

src/resources/editor/tools/vs-code.mjs

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20968,7 +20968,7 @@ var require_yaml_intelligence_resources = __commonJS({
2096820968
propertyNames: {
2096920969
errorMessage: "property ${value} does not match case convention path,name,register,script,stylesheet,self-contained",
2097020970
type: "string",
20971-
pattern: "^(?!(self_contained|selfContained))",
20971+
pattern: "(?!(^self_contained$|^selfContained$))",
2097220972
tags: {
2097320973
"case-convention": [
2097420974
"dash-case"
@@ -21092,7 +21092,7 @@ var require_yaml_intelligence_resources = __commonJS({
2109221092
propertyNames: {
2109321093
errorMessage: "property ${value} does not match case convention mermaid-format,theme",
2109421094
type: "string",
21095-
pattern: "^(?!(mermaid_format|mermaidFormat))",
21095+
pattern: "(?!(^mermaid_format$|^mermaidFormat$))",
2109621096
tags: {
2109721097
"case-convention": [
2109821098
"dash-case"
@@ -21363,7 +21363,8 @@ function detectCaseConvention(key) {
2136321363
if (key.toLocaleLowerCase() !== key) {
2136421364
return "capitalizationCase";
2136521365
}
21366-
if (key.indexOf("_") !== -1) {
21366+
const underscoreIndex = key.indexOf("_");
21367+
if (underscoreIndex !== -1) {
2136721368
return "underscore_case";
2136821369
}
2136921370
if (key.indexOf("-") !== -1) {
@@ -21378,8 +21379,9 @@ function resolveCaseConventionRegex(keys, conventions) {
2137821379
"Internal Error: resolveCaseConventionRegex requires nonempty `conventions`"
2137921380
);
2138021381
}
21382+
console.log({ conventions });
2138121383
return {
21382-
pattern: conventions.map((c) => `(${c})`).join("|"),
21384+
pattern: conventions.map((c) => `(?:^${c}$)`).join("|"),
2138321385
list: conventions
2138421386
};
2138521387
}
@@ -21418,7 +21420,7 @@ function resolveCaseConventionRegex(keys, conventions) {
2141821420
};
2141921421
}
2142021422
return {
21421-
pattern: `^(?!(${disallowedNearMisses.join("|")}))`,
21423+
pattern: `(?!(${disallowedNearMisses.map((c) => `^${c}$`).join("|")}))`,
2142221424
list: Array.from(foundConventions)
2142321425
};
2142421426
}
@@ -30151,30 +30153,55 @@ function isBlockShortcode(content) {
3015130153
return parseShortcode(m[1]);
3015230154
}
3015330155
}
30154-
function parseShortcode(shortCodeCapture) {
30155-
const [name, ...args] = shortCodeCapture.trim().split(" ");
30156-
const namedParams = {};
30156+
function parseShortcodeCapture(capture) {
30157+
const nameMatch = capture.match(/^[a-zA-Z0-9_]+/);
30158+
if (!nameMatch) {
30159+
return;
30160+
}
3015730161
const params = [];
30158-
const rawParams = args.map((v) => {
30159-
const p = v.indexOf("=");
30160-
let name2 = void 0;
30161-
let value;
30162-
if (p === -1) {
30163-
value = v;
30164-
params.push(value);
30162+
const namedParams = {};
30163+
const rawParams = [];
30164+
const name = nameMatch[0];
30165+
let paramStr = capture.slice(name.length).trim();
30166+
const paramName = "([a-zA-Z0-9_-]+)";
30167+
const paramValue1 = `([^"'\\s]+)`;
30168+
const paramValue2 = `"([^"]*)"`;
30169+
const paramValue3 = `'([^']*)'`;
30170+
const paramValue = `(?:${paramValue1})|(?:${paramValue2})|(?:${paramValue3})`;
30171+
const paramNameAndValue = `(?:${paramName}\\s*=\\s*${paramValue1})|(?:${paramName}\\s*=\\s*${paramValue2})|(?:${paramName}\\s*=\\s*${paramValue3})`;
30172+
const paramRe = new RegExp(`(?:${paramValue}|${paramNameAndValue})`);
30173+
while (paramStr.length) {
30174+
const paramMatch = paramStr.match(paramRe);
30175+
if (!paramMatch) {
30176+
throw new Error("invalid shortcode: " + capture);
30177+
}
30178+
const captures = paramMatch.slice(1).filter((x) => x !== void 0);
30179+
if (captures.length === 1) {
30180+
params.push(captures[0]);
30181+
rawParams.push({
30182+
value: captures[0]
30183+
});
30184+
} else if (captures.length === 2) {
30185+
namedParams[captures[0]] = captures[1];
30186+
rawParams.push({
30187+
name: captures[0],
30188+
value: captures[1]
30189+
});
3016530190
} else {
30166-
name2 = v.slice(0, p);
30167-
value = v.slice(p + 1);
30168-
namedParams[name2] = value;
30191+
throw new Error(
30192+
"Internal Error, could not determine correct shortcode capture for " + capture
30193+
);
3016930194
}
30170-
return { name: name2, value };
30171-
});
30172-
return {
30173-
name,
30174-
rawParams,
30175-
namedParams,
30176-
params
30177-
};
30195+
paramStr = paramStr.slice(paramMatch[0].length).trim();
30196+
}
30197+
return { name, params, namedParams, rawParams };
30198+
}
30199+
function parseShortcode(shortCodeCapture) {
30200+
const result = parseShortcodeCapture(shortCodeCapture);
30201+
if (!result) {
30202+
throw new Error("invalid shortcode: " + shortCodeCapture);
30203+
}
30204+
return result;
3017830205
}
3017930206

3018030207
// ../break-quarto-md.ts

src/resources/editor/tools/yaml/web-worker.js

Lines changed: 53 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/resources/editor/tools/yaml/yaml-intelligence-resources.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13944,7 +13944,7 @@
1394413944
"propertyNames": {
1394513945
"errorMessage": "property ${value} does not match case convention path,name,register,script,stylesheet,self-contained",
1394613946
"type": "string",
13947-
"pattern": "^(?!(self_contained|selfContained))",
13947+
"pattern": "(?!(^self_contained$|^selfContained$))",
1394813948
"tags": {
1394913949
"case-convention": [
1395013950
"dash-case"
@@ -14068,7 +14068,7 @@
1406814068
"propertyNames": {
1406914069
"errorMessage": "property ${value} does not match case convention mermaid-format,theme",
1407014070
"type": "string",
14071-
"pattern": "^(?!(mermaid_format|mermaidFormat))",
14071+
"pattern": "(?!(^mermaid_format$|^mermaidFormat$))",
1407214072
"tags": {
1407314073
"case-convention": [
1407414074
"dash-case"

0 commit comments

Comments
 (0)