@@ -3,7 +3,9 @@ package site
33
44import java .io .File
55import java .nio .file .Files
6-
6+ import java .nio .file .FileVisitOption
7+ import java .nio .file .Path
8+ import java .nio .file .Paths
79
810import org .jetbrains .dokka .base .parsers .MarkdownParser
911import org .jetbrains .dokka .base .transformers .pages .comments .DocTagToContentConverter
@@ -15,14 +17,16 @@ import org.jetbrains.dokka.pages.{ContentKind, ContentNode, DCI, PageNode}
1517import org .jetbrains .dokka .plugability .DokkaContext
1618import org .jetbrains .dokka .pages .Style
1719import org .jetbrains .dokka .model .DisplaySourceSet
20+ import util .Try
1821
1922import scala .collection .JavaConverters ._
2023
2124class StaticSiteContext (val root : File , sourceSets : Set [SourceSetWrapper ]):
2225
2326 def indexPage (): Option [StaticPageNode ] =
2427 val files = List (new File (root, " index.html" ), new File (root, " index.md" )).filter { _.exists() }
25- if (files.size > 1 ) println(s " ERROR: Multiple root index pages found: ${files.map(_.getAbsolutePath)}" ) // TODO (#14): provide proper error handling
28+ // TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
29+ if (files.size > 1 ) println(s " ERROR: Multiple root index pages found: ${files.map(_.getAbsolutePath)}" )
2630 files.flatMap(loadTemplate(_, isBlog = false )).headOption.map(templateToPage)
2731
2832 lazy val layouts : Map [String , TemplateFile ] =
@@ -37,7 +41,27 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
3741
3842 lazy val templates : Seq [LoadedTemplate ] = sideBarConfig.fold(loadAllFiles())(_.map(loadSidebarContent))
3943
40- lazy val pages = templates.map(templateToPage)
44+ lazy val mainPages : Seq [StaticPageNode ] = templates.map(templateToPage)
45+
46+ lazy val allPages : Seq [StaticPageNode ] = sideBarConfig.fold(mainPages){ sidebar =>
47+ def flattenPages (p : StaticPageNode ): Set [Path ] =
48+ Set (p.template.file.toPath) ++ p.getChildren.asScala.collect { case p : StaticPageNode => flattenPages(p) }.flatten
49+
50+ val mainFiles = mainPages.toSet.flatMap(flattenPages)
51+ val docsPath = root.toPath.resolve(" docs" )
52+ val allPaths =
53+ if ! Files .exists(docsPath) then Nil
54+ else Files .walk(docsPath, FileVisitOption .FOLLOW_LINKS ).iterator().asScala.toList
55+
56+ val orphanedFiles = allPaths.filterNot(mainFiles.contains).filter { p =>
57+ val name = p.getFileName.toString
58+ name.endsWith(" .md" ) || name.endsWith(" .html" )
59+ }
60+
61+ val orphanedTemplates = orphanedFiles.flatMap(p => loadTemplate(p.toFile, isBlog = false ))
62+
63+ mainPages ++ orphanedTemplates.map(templateToPage)
64+ }
4165
4266 private def isValidTemplate (file : File ): Boolean =
4367 (file.isDirectory && ! file.getName.startsWith(" _" )) ||
@@ -52,7 +76,8 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
5276 val allFiles = topLevelFiles.filter(_.isDirectory).flatMap(_.listFiles())
5377 val (indexes, children) = allFiles.flatMap(loadTemplate(_)).partition(_.templateFile.isIndexPage())
5478 if (indexes.size > 1 )
55- println(s " ERROR: Multiple index pages for $from found in ${indexes.map(_.file)}" ) // TODO (#14): provide proper error handling
79+ // TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
80+ println(s " ERROR: Multiple index pages for $from found in ${indexes.map(_.file)}" )
5681
5782 def loadIndexPage (): TemplateFile =
5883 val indexFiles = from.listFiles { file => file.getName == " index.md" || file.getName == " index.html" }
@@ -68,7 +93,8 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
6893 Some (LoadedTemplate (templateFile, children.toList, from))
6994 catch
7095 case e : RuntimeException =>
71- e.printStackTrace() // TODO (#14): provide proper error handling
96+ // TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
97+ e.printStackTrace()
7298 None
7399
74100 def asContent (doctag : DocTag , dri : DRI ) = new DocTagToContentConverter ().buildContent(
@@ -83,10 +109,11 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
83109 case Sidebar .Page (title, url) =>
84110 val isBlog = title == " Blog"
85111 val path = if isBlog then " blog" else url.stripSuffix(" .html" ) + " .md"
86- val file = root.toPath.resolve(path) // Add support for.html files!
112+ val file = root.toPath.resolve(path) // Add support for .html files!
87113 val LoadedTemplate (template, children, tFile) = loadTemplate(file.toFile, isBlog).get // Add proper logging if file does not exisits
88114 LoadedTemplate (template.copy(settings = template.settings + (" title" -> List (title))), children, tFile)
89115 case Sidebar .Category (title, nested) =>
116+ // Add support for index.html/index.md files!
90117 val fakeFile = new File (root, title)
91118 LoadedTemplate (emptyTemplate(fakeFile), nested.map(loadSidebarContent), fakeFile)
92119
@@ -95,9 +122,15 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
95122 dir(" docs" ).flatMap(_.listFiles()).flatMap(loadTemplate(_, isBlog = false ))
96123 ++ dir(" blog" ).flatMap(loadTemplate(_, isBlog = true ))
97124
125+ def driForLink (template : TemplateFile , link : String ): Try [DRI ] = Try (driFor(
126+ if link.startsWith(" /" ) then root.toPath.resolve(link.drop(1 ))
127+ else template.file.toPath.getParent().resolve(link)
128+ ))
129+
130+ private def driFor (dest : Path ): DRI = mkDRI(s " _. ${root.toPath.relativize(dest)}" )
131+
98132 def templateToPage (myTemplate : LoadedTemplate ): StaticPageNode =
99- def pathToDRI (path : String ) = mkDRI(s " _. $path" )
100- val dri = pathToDRI(myTemplate.relativePath(root))
133+ val dri = driFor(myTemplate.file.toPath)
101134 val content = new PartiallyRenderedContent (
102135 myTemplate.templateFile,
103136 this ,
0 commit comments