Skip to content

Commit 4d2f2cc

Browse files
authored
allow '=' in values of pandoc key=value pairs (#814)
* allow '=' in values of pandoc key=value pairs * add snapshot test * actually run the test * update changelog; tweaks * remove debugging code
1 parent 2349d21 commit 4d2f2cc

File tree

7 files changed

+119
-3
lines changed

7 files changed

+119
-3
lines changed

apps/vscode/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## 1.125.0 (Unreleased)
44

5+
- Fixed an issue where attribute values containing '='s could be truncated in some scenarios (<https://github.com/quarto-dev/quarto/pull/814>).
6+
57
## 1.124.0 (Release on 2025-08-20)
68

79
- Fix Base64 leak when no empty line between text and code block (<https://github.com/quarto-dev/quarto/pull/780>).
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.html
2+
*_files
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Testing equals signs in attribute values
2+
3+
This test document validates that equals signs in attribute values are handled correctly.
4+
5+
This prose contains some equals signs, just in case. A=B=C. D=E=F. =
6+
7+
## Basic examples
8+
9+
- Basic link with equals in value: [Link text](https://example.com){key=value=with=equals}
10+
11+
- Link with URL parameter: [Query link](https://example.com?param=value){.class key=query=param}
12+
13+
- Span with complex value: [Span text]{#id .class key=complex=value}
14+
15+
- Other weird examples: [Span text](key=) [Span](===)
16+
17+
## More complex examples
18+
19+
- CSS style with equals: [Styled text]{style=color:red;font-size=12px}
20+
21+
- Math expression value: [Math formula]{formula=E=mc^2}
22+
23+
- Code with equals: `code sample`{lang=c++ key=value=val}
24+
25+
## Code blocks
26+
27+
```{python key=value=equals}
28+
print("Testing equals in attribute values")
29+
```
30+
31+
```{r eval=1+1=2}
32+
print("R code with equals in attributes")
33+
```
34+
35+
## Div with attributes
36+
37+
:::{#div-id key=value=with=multiple=equals}
38+
This is a div with multiple equals signs in attribute values.
39+
:::
40+
41+
## Image with equals signs
42+
43+
![Image caption](image.png){width=50% height=30% key=value=equals}
44+
45+
## Table with equals signs
46+
47+
| Col1 | Col2 |
48+
|------|------|
49+
| A | B |
50+
| C | D |
51+
52+
: Table caption {#tbl-id tbl-colwidths="[50,50]" key=value=with=equals}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Testing equals signs in attribute values
2+
3+
This test document validates that equals signs in attribute values are handled correctly.
4+
5+
This prose contains some equals signs, just in case. A=B=C. D=E=F. =
6+
7+
## Basic examples
8+
9+
- Basic link with equals in value: [Link text](https://example.com){key="value=with=equals"}
10+
11+
- Link with URL parameter: [Query link](https://example.com?param=value){.class key="query=param"}
12+
13+
- Span with complex value: [Span text]{#id .class key="complex=value"}
14+
15+
- Other weird examples: [Span text](key=) [Span](===)
16+
17+
## More complex examples
18+
19+
- CSS style with equals: [Styled text]{style="color:red;font-size=12px"}
20+
21+
- Math expression value: [Math formula]{formula="E=mc^2"}
22+
23+
- Code with equals: `code sample`{lang="c++" key="value=val"}
24+
25+
## Code blocks
26+
27+
```{python key=value=equals}
28+
print("Testing equals in attribute values")
29+
```
30+
31+
```{r eval=1+1=2}
32+
print("R code with equals in attributes")
33+
```
34+
35+
## Div with attributes
36+
37+
::: {#div-id key="value=with=multiple=equals"}
38+
This is a div with multiple equals signs in attribute values.
39+
:::
40+
41+
## Image with equals signs
42+
43+
![Image caption](image.png){width="50%" height="30%" key="value=equals"}
44+
45+
## Table with equals signs
46+
47+
| Col1 | Col2 |
48+
|------|------|
49+
| A | B |
50+
| C | D |
51+
52+
: Table caption {#tbl-id tbl-colwidths="\[50,50\]" key=value=with=equals}

apps/vscode/src/test/quartoDoc.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ suite("Quarto basics", function () {
3939
roundtripSnapshotTest('invalid.qmd');
4040

4141
roundtripSnapshotTest('capsule-leak.qmd');
42+
43+
roundtripSnapshotTest('attr-equals.qmd');
4244
});
4345

4446
/**

packages/editor/src/api/pandoc_attr.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,14 @@ export function pandocAttrKeyvalueFromText(text: string, separator: ' ' | '\n'):
311311

312312
const lines = text.trim().split('\n');
313313
return lines.map(line => {
314-
const parts = line.trim().split('=');
315-
return [parts[0], (parts[1] || '').replace(/^"/, '').replace(/"$/, '')];
314+
const idx = line.indexOf('=');
315+
if (idx === -1) {
316+
return [line.trim(), ""]
317+
} else {
318+
const lhs = line.substring(0, idx).trim();
319+
const rhs = line.substring(idx + 1).trim();
320+
return [lhs, rhs.replace(/^"/, '').replace(/"$/, '')];
321+
}
316322
});
317323
}
318324

packages/quarto-core/src/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ function scanForQuarto(additionalSearchPaths?: string[]): QuartoInstallation | u
206206
}
207207
scanPaths.push("C:\\Program Files\\RStudio\\bin\\quarto\\bin");
208208
} else if (os.platform() === "darwin") {
209-
scanPaths.push("/Applications/quarto/bin/");
209+
scanPaths.push("/Applications/quarto/bin");
210210
const home = process.env.HOME;
211211
if (home) {
212212
scanPaths.push(path.join(home, "Applications", "quarto", "bin"));

0 commit comments

Comments
 (0)