Skip to content

Commit

Permalink
Parse <nav> elements nested in other HTML elements in EPUB 3 navigati…
Browse files Browse the repository at this point in the history
…on documents (#113)
  • Loading branch information
vers-one authored Jun 4, 2024
1 parent 3e8f2f6 commit 57a921e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ public class Epub3NavDocumentReaderTests
</html>
""";

private const string NAV_FILE_WITH_WITH_NON_TOP_LEVEL_NAV_ELEMENT = """
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<div>
<nav>
<h1>Test header</h1>
<ol />
</nav>
</div>
</body>
</html>
""";

private static EpubPackage MinimalEpubPackageWithNav =>
new
(
Expand Down Expand Up @@ -447,6 +460,12 @@ public async Task ReadEpub3NavDocumentAsyncWithEscapedAHrefTest()
await TestSuccessfulReadOperation(NAV_FILE_WITH_ESCAPED_HREF_IN_A_ELEMENT, expectedEpub3NavDocument);
}

[Fact(DisplayName = "Reading a NAV file with non-top-level 'nav' element should succeed")]
public async Task ReadEpub3NavDocumentAsyncWithNonTopLevelNavElementTest()
{
await TestSuccessfulReadOperation(NAV_FILE_WITH_WITH_NON_TOP_LEVEL_NAV_ELEMENT, MinimalEpub3NavDocumentWithHeader);
}

private static async Task TestSuccessfulReadOperation(string navFileContent, Epub3NavDocument expectedEpub3NavDocument, EpubReaderOptions? epubReaderOptions = null)
{
TestZipFile testZipFile = CreateTestZipFileWithNavFile(navFileContent);
Expand Down
20 changes: 16 additions & 4 deletions Source/VersOne.Epub/Readers/Epub3NavDocumentReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,24 @@ public Epub3NavDocumentReader(EpubReaderOptions? epubReaderOptions = null)
XElement htmlNode = navDocument.Element(xhtmlNamespace + "html") ?? throw new Epub3NavException("EPUB parsing error: navigation file does not contain html element.");
XElement bodyNode = htmlNode.Element(xhtmlNamespace + "body") ?? throw new Epub3NavException("EPUB parsing error: navigation file does not contain body element.");
List<Epub3Nav> navs = new();
foreach (XElement navNode in bodyNode.Elements(xhtmlNamespace + "nav"))
ReadEpub3NavsWithinContainerElement(bodyNode, navs);
return new(navFileEntryPath, navs);
}

private static void ReadEpub3NavsWithinContainerElement(XElement containerElement, List<Epub3Nav> resultNavs)
{
foreach (XElement childElement in containerElement.Elements())
{
Epub3Nav epub3Nav = ReadEpub3Nav(navNode);
navs.Add(epub3Nav);
if (childElement.GetLowerCaseLocalName() == "nav")
{
Epub3Nav epub3Nav = ReadEpub3Nav(childElement);
resultNavs.Add(epub3Nav);
}
else
{
ReadEpub3NavsWithinContainerElement(childElement, resultNavs);
}
}
return new(navFileEntryPath, navs);
}

private static Epub3Nav ReadEpub3Nav(XElement navNode)
Expand Down

0 comments on commit 57a921e

Please sign in to comment.