Skip to content

Commit

Permalink
Fix problems with href anchors
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiju committed Aug 13, 2017
1 parent c178362 commit d2b817c
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 17 deletions.
34 changes: 20 additions & 14 deletions src/Content/Heading.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @license http://opensource.org/licenses/MIT MIT
*
*/

namespace Bookdown\Bookdown\Content;

/**
Expand Down Expand Up @@ -53,6 +54,13 @@ class Heading
*/
protected $href;

/**
* The number anchor attribute added to the href
*
* @var string
*/
protected $hrefAnchor;

/**
*
* The TOC depth level for the heading.
Expand All @@ -72,16 +80,19 @@ class Heading
*
* @param string $href The href attribute value.
*
* @param string $hrefAnchor The hrefAnchor attribute value.
*
* @param string $id The id attribute value.
*
*/
public function __construct($number, $title, $href, $id = null)
public function __construct($number, $title, $href, $hrefAnchor = null, $id = null)
{
$this->number = $number;
$this->title = $title;
$this->href = $href;
$this->id = $id;
$this->level = substr_count($number, '.');
$this->hrefAnchor = $hrefAnchor;
}

/**
Expand Down Expand Up @@ -130,29 +141,24 @@ public function getId()
public function getHref()
{
$href = $this->href;
$hrefAnchor = $this->getHrefAnchor();

if (null !== $this->getId() && null !== $hrefAnchor) {
$href .= $hrefAnchor;
if (null !== $this->getId() && !strstr($href, '#')) {
$href .= $this->getHrefAnchor();
}

return $href;
}

/**
*
* Creates a complete anchor href attribute for links.
*
* @return string|null
*
* @return string
*/
public function getHrefAnchor()
{
$hrefAnchor = $this->getAnchor();

if (null !== $hrefAnchor) {
return '#' . $this->getAnchor();
if (null === $this->hrefAnchor) {
$this->hrefAnchor = '#' . $this->getAnchor();
}
return $hrefAnchor;

return $this->hrefAnchor;
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/Content/HeadingFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ class HeadingFactory
*
* @param string $href The href attribute value.
*
* @param string $hrefAnchor The hrefAnchor attribute value.
*
* @param string $id The id attribute value.
*
* @return Heading
*
*/
public function newInstance($number, $title, $href, $id = null)
public function newInstance($number, $title, $href ,$hrefAnchor = null, $id = null)
{
return new Heading($number, $title, $href, $id);
return new Heading($number, $title, $href, $hrefAnchor, $id);
}
}
1 change: 1 addition & 0 deletions src/Content/TocHeadingIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ protected function createSourceHeadingList(array $headings)
$heading->getNumber(),
$heading->getTitle(),
$heading->getHref(),
$heading->getHrefAnchor(),
$heading->getId()
);

Expand Down
1 change: 1 addition & 0 deletions src/Process/Headings/HeadingsProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ protected function newHeading(DomNode $node)
$number,
$title,
$this->page->getHref(),
null,
$id
);
}
Expand Down
22 changes: 21 additions & 1 deletion tests/Content/HeadingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public function testHeadingWithId()
'1.2.3.',
'Example Heading',
'/foo/bar/baz',
'#1-2-3',
'1.2.3'
);

Expand All @@ -33,7 +34,8 @@ public function testHeadingWithoutId()
$heading = $this->headingFactory->newInstance(
'1.2.3.',
'Example Heading',
'/foo/bar/baz'
'/foo/bar/baz',
'#1-2-3'
);

$this->assertSame($heading->getNumber(), '1.2.3.');
Expand All @@ -44,4 +46,22 @@ public function testHeadingWithoutId()
$this->assertSame($heading->getHrefAnchor(), '#1-2-3');
$this->assertSame($heading->getAnchor(), '1-2-3');
}

public function testHeadingWithAnchoredHref()
{
$heading = $this->headingFactory->newInstance(
'1.2.3.',
'Example Heading',
'/foo/bar/baz/test.html#7-8-9',
'#1-2-3'
);

$this->assertSame($heading->getNumber(), '1.2.3.');
$this->assertSame($heading->getTitle(), 'Example Heading');
$this->assertSame($heading->getId(), null);
$this->assertSame($heading->getLevel(), 3);
$this->assertSame($heading->getHref(), '/foo/bar/baz/test.html#7-8-9');
$this->assertSame($heading->getHrefAnchor(), '#1-2-3');
$this->assertSame($heading->getAnchor(), '1-2-3');
}
}
5 changes: 5 additions & 0 deletions tests/Process/HeadingsProcessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,31 @@ public function testHeadings()
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => null,
'level' => 2,
),
array(
'number' => '1.1.1.',
'title' => 'Subtitle <code>code</code> A',
'id' => '1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => null,
'level' => 3,
),
array(
'number' => '1.1.1.1.',
'title' => 'Sub-subtitle',
'id' => '1.1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => null,
'level' => 4,
),
array(
'number' => '1.1.2.',
'title' => 'Subtitle B',
'id' => '1.1.2',
'href' => '/chapter/section.html',
'hrefAnchor' => null,
'level' => 3,
),
);
Expand Down Expand Up @@ -104,6 +108,7 @@ public function testHeadingsOnIndex()
'title' => 'Chapter',
'id' => null,
'href' => '/chapter/',
'hrefAnchor' => null,
'level' => 1,
)
);
Expand Down
25 changes: 25 additions & 0 deletions tests/Process/TocProcessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,27 +87,31 @@ public function testTocIndex()
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
),
array(
'number' => '1.1.1.',
'title' => 'Subtitle <code>code</code> A',
'id' => '1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1',
'level' => 3,
),
array(
'number' => '1.1.1.1.',
'title' => 'Sub-subtitle',
'id' => '1.1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1-1',
'level' => 4,
),
array(
'number' => '1.1.2.',
'title' => 'Subtitle B',
'id' => '1.1.2',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-2',
'level' => 3,
),
);
Expand All @@ -132,34 +136,39 @@ public function testTocRoot()
'title' => 'Chapter',
'id' => null,
'href' => '/chapter/',
'hrefAnchor' => '#1',
'level' => 1,
),
array(
'number' => '1.1.',
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
),
array(
'number' => '1.1.1.',
'title' => 'Subtitle <code>code</code> A',
'id' => '1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1',
'level' => 3,
),
array(
'number' => '1.1.1.1.',
'title' => 'Sub-subtitle',
'id' => '1.1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1-1',
'level' => 4,
),
array(
'number' => '1.1.2.',
'title' => 'Subtitle B',
'id' => '1.1.2',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-2',
'level' => 3,
),
);
Expand Down Expand Up @@ -199,6 +208,7 @@ public function providerForTocDepthRoot()
'title' => 'Index Page',
'id' => null,
'href' => '/chapter/',
'hrefAnchor' => '#1',
'level' => 1,
],
],
Expand All @@ -211,13 +221,15 @@ public function providerForTocDepthRoot()
'title' => 'Index Page',
'id' => null,
'href' => '/chapter/',
'hrefAnchor' => '#1',
'level' => 1,
],
[
'number' => '1.1.',
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
],
],
Expand All @@ -230,27 +242,31 @@ public function providerForTocDepthRoot()
'title' => 'Index Page',
'id' => null,
'href' => '/chapter/',
'hrefAnchor' => '#1',
'level' => 1,
],
[
'number' => '1.1.',
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
],
[
'number' => '1.1.1.',
'title' => 'Subtitle <code>code</code> A',
'id' => '1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1',
'level' => 3,
],
[
'number' => '1.1.2.',
'title' => 'Subtitle B',
'id' => '1.1.2',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-2',
'level' => 3,
],
],
Expand Down Expand Up @@ -286,6 +302,7 @@ public function providerForTocDepthIndex()
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
],
],
Expand All @@ -298,20 +315,23 @@ public function providerForTocDepthIndex()
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
],
[
'number' => '1.1.1.',
'title' => 'Subtitle <code>code</code> A',
'id' => '1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1',
'level' => 3,
],
[
'number' => '1.1.2.',
'title' => 'Subtitle B',
'id' => '1.1.2',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-2',
'level' => 3,
],
],
Expand All @@ -324,34 +344,39 @@ public function providerForTocDepthIndex()
'title' => 'Title',
'id' => '1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1',
'level' => 2,
],
[
'number' => '1.1.1.',
'title' => 'Subtitle <code>code</code> A',
'id' => '1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1',
'level' => 3,
],
[
'number' => '1.1.1.1.',
'title' => 'Sub-subtitle A',
'id' => '1.1.1.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-1-1',
'level' => 4,
],
[
'number' => '1.1.2.',
'title' => 'Subtitle B',
'id' => '1.1.2',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-2',
'level' => 3,
],
[
'number' => '1.1.2.1.',
'title' => 'Sub-subtitle B',
'id' => '1.1.2.1',
'href' => '/chapter/section.html',
'hrefAnchor' => '#1-1-2-1',
'level' => 4,
],
],
Expand Down

0 comments on commit d2b817c

Please sign in to comment.