Skip to content

Commit 082d009

Browse files
committed
fix: QUOTED_STRINGがインラインのリンク構文を飲み込む問題を修正
"..."のQUOTED_STRINGトークン化をEQUALS直後(ブロック属性値)に限定。
1 parent 66f076f commit 082d009

File tree

4 files changed

+139
-13
lines changed

4 files changed

+139
-13
lines changed

packages/parser/src/lexer/lexer.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ export class Lexer {
176176
return result;
177177
}
178178

179+
/**
180+
* Returns the type of the last non-whitespace token, or null if none.
181+
*/
182+
private lastNonWhitespaceTokenType(): TokenType | null {
183+
for (let i = this.state.tokens.length - 1; i >= 0; i--) {
184+
const t = this.state.tokens[i]!;
185+
if (t.type !== "WHITESPACE") return t.type;
186+
}
187+
return null;
188+
}
189+
179190
/**
180191
* Add token
181192
*/
@@ -543,16 +554,23 @@ export class Lexer {
543554
return;
544555
}
545556

546-
// Quoted string
557+
// Quoted string (only after EQUALS for block attribute values)
558+
// In inline context, " is just a text character (typographic quotes)
547559
if (char === '"') {
548-
let quoted = this.advance(); // opening "
549-
while (!this.isAtEnd() && this.current() !== '"' && this.current() !== "\n") {
550-
quoted += this.advance();
551-
}
552-
if (this.current() === '"') {
553-
quoted += this.advance(); // closing "
560+
const lastNonWs = this.lastNonWhitespaceTokenType();
561+
if (lastNonWs === "EQUALS") {
562+
let quoted = this.advance(); // opening "
563+
while (!this.isAtEnd() && this.current() !== '"' && this.current() !== "\n") {
564+
quoted += this.advance();
565+
}
566+
if (this.current() === '"') {
567+
quoted += this.advance(); // closing "
568+
}
569+
this.addToken("QUOTED_STRING", quoted);
570+
return;
554571
}
555-
this.addToken("QUOTED_STRING", quoted);
572+
this.advance();
573+
this.addToken("TEXT", '"');
556574
return;
557575
}
558576

tests/fixtures/footnote/basic/expected.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,15 @@
340340
},
341341
{
342342
"element": "text",
343-
"data": "\"fruit\""
343+
"data": "\""
344+
},
345+
{
346+
"element": "text",
347+
"data": "fruit"
348+
},
349+
{
350+
"element": "text",
351+
"data": "\""
344352
},
345353
{
346354
"element": "text",
@@ -360,7 +368,15 @@
360368
},
361369
{
362370
"element": "text",
363-
"data": "\"vegetable\""
371+
"data": "\""
372+
},
373+
{
374+
"element": "text",
375+
"data": "vegetable"
376+
},
377+
{
378+
"element": "text",
379+
"data": "\""
364380
},
365381
{
366382
"element": "text",

tests/fixtures/link/triple/expected.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,23 @@
133133
},
134134
{
135135
"element": "text",
136-
"data": "\"Recent Changes\""
136+
"data": "\""
137+
},
138+
{
139+
"element": "text",
140+
"data": "Recent"
141+
},
142+
{
143+
"element": "text",
144+
"data": " "
145+
},
146+
{
147+
"element": "text",
148+
"data": "Changes"
149+
},
150+
{
151+
"element": "text",
152+
"data": "\""
137153
},
138154
{
139155
"element": "text",

tests/fixtures/misc/string/expected.json

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,15 @@
1616
},
1717
{
1818
"element": "text",
19-
"data": "\"string\""
19+
"data": "\""
20+
},
21+
{
22+
"element": "text",
23+
"data": "string"
24+
},
25+
{
26+
"element": "text",
27+
"data": "\""
2028
},
2129
{
2230
"element": "text",
@@ -41,7 +49,75 @@
4149
"elements": [
4250
{
4351
"element": "text",
44-
"data": "\"This one\\x01 has\\t escapes \\n\\b\""
52+
"data": "\""
53+
},
54+
{
55+
"element": "text",
56+
"data": "This"
57+
},
58+
{
59+
"element": "text",
60+
"data": " "
61+
},
62+
{
63+
"element": "text",
64+
"data": "one"
65+
},
66+
{
67+
"element": "text",
68+
"data": "\\"
69+
},
70+
{
71+
"element": "text",
72+
"data": "x01"
73+
},
74+
{
75+
"element": "text",
76+
"data": " "
77+
},
78+
{
79+
"element": "text",
80+
"data": "has"
81+
},
82+
{
83+
"element": "text",
84+
"data": "\\"
85+
},
86+
{
87+
"element": "text",
88+
"data": "t"
89+
},
90+
{
91+
"element": "text",
92+
"data": " "
93+
},
94+
{
95+
"element": "text",
96+
"data": "escapes"
97+
},
98+
{
99+
"element": "text",
100+
"data": " "
101+
},
102+
{
103+
"element": "text",
104+
"data": "\\"
105+
},
106+
{
107+
"element": "text",
108+
"data": "n"
109+
},
110+
{
111+
"element": "text",
112+
"data": "\\"
113+
},
114+
{
115+
"element": "text",
116+
"data": "b"
117+
},
118+
{
119+
"element": "text",
120+
"data": "\""
45121
}
46122
]
47123
}

0 commit comments

Comments
 (0)