Skip to content

Commit

Permalink
[FEATURE] Support Hyperlinks to local pages in rst and md
Browse files Browse the repository at this point in the history
local pages can be linked by source name, target name or pure name without ending. Links can be relative to the current file or absolute to the project root
  • Loading branch information
linawolf committed Dec 10, 2023
1 parent 54670ba commit ab77ba0
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Psr\Log\LoggerInterface;
use RuntimeException;

use function ltrim;
use function md5;
use function sprintf;
use function strtolower;
Expand Down Expand Up @@ -54,7 +55,7 @@ public function parse(ParserContext $parserContext, string $contents): DocumentN

private function parseDocument(NodeWalker $walker, string $hash): DocumentNode
{
$document = new DocumentNode($hash, $this->getParserContext()->getCurrentAbsolutePath());
$document = new DocumentNode($hash, ltrim($this->getParserContext()->getCurrentAbsolutePath(), '/'));
$this->document = $document;

while ($event = $walker->next()) {
Expand Down
3 changes: 3 additions & 0 deletions packages/guides/resources/config/guides.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use phpDocumentor\Guides\ReferenceResolvers\ExternalReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\InterlinkReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\InternalReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\PageHyperlinkResolver;
use phpDocumentor\Guides\ReferenceResolvers\ReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\ReferenceResolverPreRender;
use phpDocumentor\Guides\ReferenceResolvers\SluggerAnchorReducer;
Expand Down Expand Up @@ -124,6 +125,8 @@

->set(AnchorHyperlinkResolver::class)

->set(PageHyperlinkResolver::class)

->set(AnchorReferenceResolver::class)

->set(InternalReferenceResolver::class)
Expand Down
57 changes: 57 additions & 0 deletions packages/guides/src/ReferenceResolvers/PageHyperlinkResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\ReferenceResolvers;

use phpDocumentor\Guides\Nodes\Inline\HyperLinkNode;
use phpDocumentor\Guides\Nodes\Inline\LinkInlineNode;
use phpDocumentor\Guides\RenderContext;
use phpDocumentor\Guides\Renderer\UrlGenerator\UrlGeneratorInterface;

use function rtrim;

/**
* Resolves named and anonymous references to source files
*
* `Link Text <../page.rst>`_ or [Link Text](path/to/another/page.md)
*/
class PageHyperlinkResolver implements ReferenceResolver
{
// Named links and anchors take precedence
public final const PRIORITY = -200;

public function __construct(
private readonly UrlGeneratorInterface $urlGenerator,
private readonly DocumentNameResolverInterface $documentNameResolver,
) {
}

public function resolve(LinkInlineNode $node, RenderContext $renderContext): bool
{
if (!$node instanceof HyperLinkNode) {
return false;
}

$canonicalDocumentName = $this->documentNameResolver->canonicalUrl($renderContext->getDirName(), $node->getTargetReference());
$canonicalDocumentName = rtrim($canonicalDocumentName, '.' . $renderContext->getOutputFormat());
$canonicalDocumentName = rtrim($canonicalDocumentName, '.rst');
$canonicalDocumentName = rtrim($canonicalDocumentName, '.md');
$document = $renderContext->getProjectNode()->findDocumentEntry($canonicalDocumentName);
if ($document === null) {
return false;
}

$node->setUrl($this->urlGenerator->generateCanonicalOutputUrl($renderContext, $document->getFile()));
if ($node->getValue() === '') {
$node->setValue($document->getTitle()->toString());
}

return true;
}

public static function getPriority(): int
{
return self::PRIORITY;
}
}
16 changes: 16 additions & 0 deletions tests/Integration/tests/hyperlink-to-page/expected/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- content start -->
<div class="section" id="some-file">
<h1>Some file</h1>



<ul>
<li><a href="/page1.html">link page 1</a></li>

<li><a href="/subpages/subpage1.html">link subpage 1</a></li>

</ul>

</div>

<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!-- content start -->
<div class="section" id="some-file">
<h1>Some file</h1>

<a id="page1"></a>


<ul>
<li><a href="/page1.html">link page 1</a></li>

<li><a href="/subpages/subpage1.html">link subpage 1</a></li>

<li><a href="/page1.html">link page 1</a></li>

<li><a href="/page1.html">link page 1</a></li>

<li><a href="/subpages/subpage1.html">link subpage 1</a></li>

<li><a href="/page1.html">link page 1</a></li>

<li><a href="/subpages/index.html#page1">link page 1</a></li>

<li><a href="/subpages/subpage1.html">link subpage 1</a></li>

<li><a href="/subpages/index.html#page1">link page 1</a></li>

</ul>

</div>

<!-- content end -->
6 changes: 6 additions & 0 deletions tests/Integration/tests/hyperlink-to-page/input/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Some file
=========

* `link page 1 <page1.rst>`_

* `link subpage 1 <subpages/subpage1.rst>`_
2 changes: 2 additions & 0 deletions tests/Integration/tests/hyperlink-to-page/input/page1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Page 1
======
17 changes: 17 additions & 0 deletions tests/Integration/tests/hyperlink-to-page/input/subpages/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.. _page1:

Some file
=========

* `link page 1 </page1.rst>`_
* `link subpage 1 <subpage1.rst>`_
* `link page 1 <../page1.rst>`_


* `link page 1 </page1.html>`_
* `link subpage 1 <subpage1.html>`_
* `link page 1 <../page1.html>`_

* `link page 1 </page1>`_
* `link subpage 1 <subpage1>`_
* `link page 1 <../page1>`_
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Subpage 1
=========
16 changes: 16 additions & 0 deletions tests/Integration/tests/markdown/link-page-md/expected/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- content start -->
<h1>Markdown with links</h1>

<p>This is a Markdown document with some basic formatting.</p>


<ul>
<li><p><a href="/page1.html">Page 1</a></p></li>

<li><p><a href="/page1.html">Page 1</a></p></li>

<li><p><a href="/subpages/subpage1.html">Subpage 1</a></p></li>

</ul>

<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- content start -->
<h1>Markdown with links</h1>

<p>This is a Markdown document with some basic formatting.</p>


<ul>
<li><p><a href="/subpages/subpage1.html">Subpage 1</a></p></li>

<li><p><a href="/page1.html">Page 1</a></p></li>

<li><p><a href="/page1.html">Page 1</a></p></li>

<li><p><a href="/page1.html">Page 1</a></p></li>

<li><p><a href="/page1.html">Page 1</a></p></li>

</ul>

<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<guides xmlns="https://www.phpdoc.org/guides"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.phpdoc.org/guides packages/guides-cli/resources/schema/guides.xsd"
input-format="md"
>
<project title="Project Title" version="6.4"/>
</guides>
7 changes: 7 additions & 0 deletions tests/Integration/tests/markdown/link-page-md/input/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Markdown with links

This is a Markdown document with some basic formatting.

* [Page 1](page1.md)
* [Page 1](/page1.md)
* [Subpage 1](subpages/subpage1.md)
3 changes: 3 additions & 0 deletions tests/Integration/tests/markdown/link-page-md/input/page1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Page 1

This is a Markdown document with some basic formatting.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Markdown with links

This is a Markdown document with some basic formatting.

* [Subpage 1](subpage1.md)
* [Page 1](../page1.md)
* [Page 1](/page1.md)
* [Page 1](/page1.html)
* [Page 1](/page1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Subpage 1

This is a Markdown document with some basic formatting.

0 comments on commit ab77ba0

Please sign in to comment.