Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/Application/CommonMark/WikiLinkNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ public function __construct(
parent::__construct();
}

/**
* Pipe-less links keep the target text exactly as typed (colon-stripped and
* trimmed by the parser), matching how MediaWiki wikitext and Obsidian render
* them. The resolved title drives the href and link registration, not the label.
*/
public function displayLabel(): string {
if ( $this->label !== null && $this->label !== '' ) {
return $this->label;
}

if ( $this->resolvedTitle !== null ) {
return $this->resolvedTitle->textWithFragment();
}

return $this->target;
}

Expand Down
49 changes: 49 additions & 0 deletions tests/phpunit/Application/MarkdownRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,55 @@ public function testWikiLinkRendersAndIsCollected(): void {
$this->assertSame( 'Some Page', $result->links[0]->prefixedText );
}

public function testPipelessWikiLinkDisplaysTypedTextNotNormalizedTitle(): void {
$result = $this->render( 'See [[page]] here' );

$this->assertSame(
"<p>See <a href=\"/wiki/Page\">page</a> here</p>\n",
$result->html
);
$this->assertSame( 'Page', $result->links[0]->prefixedText );
}

public function testPipelessWikiLinkKeepsTypedTextWithFragment(): void {
$result = $this->render( '[[page#section]]' );

$this->assertSame(
"<p><a href=\"/wiki/Page#section\">page#section</a></p>\n",
$result->html
);
$this->assertSame( 'section', $result->links[0]->fragment );
}

public function testColonPrefixedCategoryLinkUsesTypedTextWithoutLeadingColon(): void {
$result = $this->render( '[[:Category:some category]]' );

$this->assertSame(
"<p><a href=\"/wiki/Category:Some category\">Category:some category</a></p>\n",
$result->html
);
$this->assertSame( [], $result->categories );
$this->assertCount( 1, $result->links );
}

public function testColonPrefixedFileLinkUsesTypedTextWithoutLeadingColon(): void {
$result = $this->render( '[[:File:some file.png]]' );

$this->assertSame(
"<p><a href=\"/wiki/File:Some file.png\">File:some file.png</a></p>\n",
$result->html
);
$this->assertSame( [], $result->files );
$this->assertCount( 1, $result->links );
}

public function testPipedWikiLinkUsesLabelNotTypedTarget(): void {
$this->assertSame(
"<p><a href=\"/wiki/Page\">Label</a></p>\n",
$this->render( '[[page|Label]]' )->html
);
}

public function testWikiLinkWithLabelUsesLabel(): void {
$this->assertSame(
"<p><a href=\"/wiki/Some Page\">the label</a></p>\n",
Expand Down
7 changes: 7 additions & 0 deletions tests/phpunit/EntryPoints/MarkdownContentHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public function testRegistersInternalLinks(): void {
$this->assertArrayHasKey( 'Another_One', $output->getLinks()[NS_MAIN] );
}

public function testPipelessLinkDisplaysTypedTextWhileRegisteringNormalizedTitle(): void {
$output = $this->getParserOutput( 'See [[phase one matrix]] here' );

$this->assertStringContainsString( '>phase one matrix</a>', $output->getRawText() );
$this->assertArrayHasKey( 'Phase_one_matrix', $output->getLinks()[NS_MAIN] );
}

public function testRendersMissingPageAsRedLink(): void {
$output = $this->getParserOutput( '[[Surely This Page Is Missing]]' );

Expand Down
12 changes: 11 additions & 1 deletion tests/phpunit/TestDoubles/FakeWikiTitleParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
/**
* Pure-PHP stand-in for the MediaWiki TitleParser adapter. Understands just enough
* title syntax for the pipeline tests: Category:/File: prefixes (case-insensitive,
* like MediaWiki), the "wikipedia" interwiki prefix, #fragments, and rejection of
* like MediaWiki), the "wikipedia" interwiki prefix, #fragments, first-letter
* capitalization (MediaWiki's $wgCapitalLinks default), and rejection of
* characters MediaWiki considers invalid in titles.
*/
final class FakeWikiTitleParser implements WikiTitleParser {
Expand Down Expand Up @@ -48,6 +49,7 @@ public function parse( string $titleText ): ?WikiTitle {
}

[ $namespace, $prefix, $text ] = $this->splitNamespace( $pageText );
$text = $this->capitalizeFirst( $text );

return new WikiTitle(
namespace: $namespace,
Expand Down Expand Up @@ -84,4 +86,12 @@ private function splitNamespace( string $pageText ): array {
return [ self::MAIN_NAMESPACE, '', $pageText ];
}

private function capitalizeFirst( string $text ): string {
if ( $text === '' ) {
return '';
}

return mb_strtoupper( mb_substr( $text, 0, 1 ) ) . mb_substr( $text, 1 );
}

}
Loading