Skip to content

Commit 863f02b

Browse files
committed
fix: トリプルブラケットリンクの*prefixがpipe付きで機能しない問題を修正
[[[*http://url|label]]]で*が除去されず、URLが正しく認識されない バグを修正。*prefixの除去をpipeの有無に関わらず実行するよう変更。 外部URL(http/https)の場合のみtarget="_blank"を設定。
1 parent 06ada51 commit 863f02b

File tree

5 files changed

+102
-10
lines changed

5 files changed

+102
-10
lines changed

packages/parser/src/parser/rules/inline/link-triple.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
* - Interwiki links: `[[[wikipedia:Article]]]` (for known prefixes)
1313
*
1414
* Special syntax:
15-
* - `[[[*page]]]` -- `*` prefix is treated as a label prefix (ignored in target)
15+
* - `[[[*target]]]` -- `*` prefix is stripped from target; for external URLs,
16+
* adds `target="_blank"` (new tab)
1617
* - `[[[*|label]]]` -- links to root `/` with the given label
1718
* - `[[[page|]]]` -- empty label after pipe defaults to the page name
1819
*
@@ -86,7 +87,7 @@ function hasClosingLinkMarker(ctx: ParseContext, startPos: number): boolean {
8687
* - Empty target with pipe (`[[[|text]]]`) is invalid
8788
* - Multiple consecutive `#` in the target (`[[[page##anchor]]]`) is invalid
8889
* - `[[[*|label]]]` links to root `/`
89-
* - `[[[*page]]]` strips the `*` prefix from the target
90+
* - `[[[*target]]]` strips `*`; adds `target="_blank"` for external URLs
9091
* - Category pages show only the text after the colon when no label is given
9192
*/
9293
export const linkTripleRule: InlineRule = {
@@ -174,13 +175,11 @@ export const linkTripleRule: InlineRule = {
174175
};
175176
}
176177

177-
// Special case: [[[*|label]]] means link to root "/" with label
178+
// `*` prefix: stripped from target; sets target="_blank" for external URLs
178179
let finalTarget = trimmedTarget;
179-
if (trimmedTarget === "*" && foundPipe) {
180-
finalTarget = "";
181-
}
182-
// Special case: [[[*page]]] - * is a label prefix, page is the target
183-
if (trimmedTarget.startsWith("*") && !foundPipe) {
180+
let hasStar = false;
181+
if (trimmedTarget.startsWith("*")) {
182+
hasStar = true;
184183
finalTarget = trimmedTarget.slice(1);
185184
}
186185

@@ -194,8 +193,9 @@ export const linkTripleRule: InlineRule = {
194193
displayText = trimmedLabel || finalTarget;
195194
} else {
196195
// For category pages (system:Recent Changes), use only the part after colon
196+
// Use trimmedTarget (preserves * prefix) for display when no pipe
197197
const colonIdx = trimmedTarget.indexOf(":");
198-
if (colonIdx !== -1 && !trimmedTarget.startsWith("http")) {
198+
if (colonIdx !== -1 && !trimmedTarget.startsWith("http") && !trimmedTarget.startsWith("*")) {
199199
displayText = trimmedTarget.slice(colonIdx + 1).trim();
200200
} else {
201201
displayText = trimmedTarget;
@@ -214,7 +214,7 @@ export const linkTripleRule: InlineRule = {
214214
link,
215215
extra: null,
216216
label,
217-
target: null,
217+
target: hasStar && linkType === "direct" ? "new-tab" : null,
218218
},
219219
},
220220
],

tests/fixtures/link/triple/expected.json

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,84 @@
530530
]
531531
}
532532
},
533+
{
534+
"element": "container",
535+
"data": {
536+
"type": "paragraph",
537+
"attributes": {},
538+
"elements": [
539+
{
540+
"element": "container",
541+
"data": {
542+
"type": "bold",
543+
"attributes": {},
544+
"elements": [
545+
{
546+
"element": "text",
547+
"data": "Star"
548+
},
549+
{
550+
"element": "text",
551+
"data": " "
552+
},
553+
{
554+
"element": "text",
555+
"data": "prefix"
556+
}
557+
]
558+
}
559+
}
560+
]
561+
}
562+
},
563+
{
564+
"element": "list",
565+
"data": {
566+
"type": "bullet",
567+
"attributes": {},
568+
"items": [
569+
{
570+
"item-type": "elements",
571+
"attributes": {},
572+
"elements": [
573+
{
574+
"element": "link",
575+
"data": {
576+
"type": "direct",
577+
"link": "http://example.com",
578+
"extra": null,
579+
"label": {
580+
"text": "example"
581+
},
582+
"target": "new-tab"
583+
}
584+
}
585+
]
586+
},
587+
{
588+
"item-type": "elements",
589+
"attributes": {},
590+
"elements": [
591+
{
592+
"element": "link",
593+
"data": {
594+
"type": "page",
595+
"link": {
596+
"site": null,
597+
"page": "test"
598+
},
599+
"extra": null,
600+
"label": {
601+
"text": "*test"
602+
},
603+
"target": null
604+
}
605+
}
606+
]
607+
}
608+
]
609+
}
610+
},
533611
{
534612
"element": "footnote-block",
535613
"data": {

tests/fixtures/link/triple/input.ftml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@
2323

2424
**URL**
2525
* [[[https://example.com/|Example]]]
26+
27+
**Star prefix**
28+
* [[[*http://example.com|example]]]
29+
* [[[*test|*test]]]

tests/fixtures/link/triple/output.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,8 @@
3131
<ul>
3232
<li><a href="https://example.com/">Example</a></li>
3333
</ul>
34+
<p><strong>Star prefix</strong></p>
35+
<ul>
36+
<li><a href="http://example.com" target="_blank" rel="noopener noreferrer">example</a></li>
37+
<li><a class="newpage" href="/test">*test</a></li>
38+
</ul>

tests/fixtures/link/triple/wikidot.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,8 @@
3131
<ul>
3232
<li><a href="https://example.com/">Example</a></li>
3333
</ul>
34+
<p><strong>Star prefix</strong></p>
35+
<ul>
36+
<li><a target="_blank" href="http://example.com">example</a></li>
37+
<li><a href="/test">*test</a></li>
38+
</ul>

0 commit comments

Comments
 (0)