-
+
Edit this page on GitHub
diff --git a/scala3doc/scala3-docs/logo.svg b/scala3doc/scala3-docs/logo.svg
new file mode 100644
index 000000000000..44c8b71850ce
--- /dev/null
+++ b/scala3doc/scala3-docs/logo.svg
@@ -0,0 +1,30 @@
+
diff --git a/scala3doc/src/dotty/dokka/DottyDokkaConfig.scala b/scala3doc/src/dotty/dokka/DottyDokkaConfig.scala
index 16b47ff266c3..d97d0fc475da 100644
--- a/scala3doc/src/dotty/dokka/DottyDokkaConfig.scala
+++ b/scala3doc/src/dotty/dokka/DottyDokkaConfig.scala
@@ -17,10 +17,15 @@ case class DottyDokkaConfig(docConfiguration: DocConfiguration) extends DokkaCon
override def getModuleName(): String = "ModuleName"
override def getModuleVersion(): String = ""
- lazy val staticSiteContext = docConfiguration.args.docsRoot.map(path => StaticSiteContext(File(path).getAbsoluteFile(), Set(mkSourceSet.asInstanceOf[SourceSetWrapper])))
-
lazy val sourceLinks: SourceLinks = SourceLinks.load(docConfiguration)
+ lazy val staticSiteContext = docConfiguration.args.docsRoot.map(path => StaticSiteContext(
+ File(path).getAbsoluteFile(),
+ Set(mkSourceSet.asInstanceOf[SourceSetWrapper]),
+ docConfiguration.args,
+ sourceLinks
+ ))
+
override def getPluginsConfiguration: JList[DokkaConfiguration.PluginConfiguration] = JList()
lazy val mkSourceSet: DokkaSourceSet =
diff --git a/scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala b/scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala
index f1d34132416c..08fa3456611f 100644
--- a/scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala
+++ b/scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala
@@ -9,7 +9,6 @@ import org.jetbrains.dokka.transformers.documentation.DocumentableToPageTranslat
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.{ DokkaConfiguration$DokkaSourceSet => DokkaSourceSet }
import org.jetbrains.dokka.model._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
import org.jetbrains.dokka.base.parsers._
import org.jetbrains.dokka.plugability.DokkaContext
@@ -70,7 +69,7 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
val scalaResourceInstaller = extend(
_.extensionPoint(dokkaBase.getHtmlPreprocessors)
- .fromInstance(new ScalaResourceInstaller())
+ .fromRecipe(ctx => new ScalaResourceInstaller(ctx.args))
.after(dokkaBase.getCustomResourceInstaller)
)
@@ -110,7 +109,7 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
val ourRenderer = extend(
_.extensionPoint(CoreExtensions.INSTANCE.getRenderer)
- .fromRecipe(ScalaHtmlRenderer(_))
+ .fromRecipe(ctx => ScalaHtmlRenderer(ctx, ctx.args))
.overrideExtension(dokkaBase.getHtmlRenderer)
)
@@ -170,9 +169,8 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
)
extension (ctx: DokkaContext):
- def siteContext: Option[StaticSiteContext] = ctx.getConfiguration match
- case d: DottyDokkaConfig => d.staticSiteContext
- case _ => None
+ def siteContext: Option[StaticSiteContext] = ctx.getConfiguration.asInstanceOf[DottyDokkaConfig].staticSiteContext
+ def args: Args = ctx.getConfiguration.asInstanceOf[DottyDokkaConfig].docConfiguration.args
// TODO (https://github.com/lampepfl/scala3doc/issues/232): remove once problem is fixed in Dokka
extension [T] (builder: ExtensionBuilder[T]):
diff --git a/scala3doc/src/dotty/dokka/Main.scala b/scala3doc/src/dotty/dokka/Main.scala
index aa9e5ec15899..7a568c73aa94 100644
--- a/scala3doc/src/dotty/dokka/Main.scala
+++ b/scala3doc/src/dotty/dokka/Main.scala
@@ -64,7 +64,7 @@ class RawArgs:
classpath,
new File(output),
Option(docsRoot),
- projectVersion,
+ Option(projectVersion),
Option(projectTitle),
Option(projectLogo),
parsedSyntax,
@@ -79,7 +79,7 @@ case class Args(
classpath: String,
output: File,
docsRoot: Option[String],
- projectVersion: String,
+ projectVersion: Option[String],
projectTitle: Option[String],
projectLogo: Option[String],
defaultSyntax: Option[Args.CommentSyntax],
diff --git a/scala3doc/src/dotty/dokka/ScalaModuleCreator.scala b/scala3doc/src/dotty/dokka/ScalaModuleCreator.scala
index e8ba83931d7a..30e217fc23ad 100644
--- a/scala3doc/src/dotty/dokka/ScalaModuleCreator.scala
+++ b/scala3doc/src/dotty/dokka/ScalaModuleCreator.scala
@@ -10,7 +10,6 @@ import dotty.dokka.tasty.{DokkaTastyInspector, SbtDokkaTastyInspector}
import org.jetbrains.dokka.pages._
import dotty.dokka.model.api._
import org.jetbrains.dokka.model._
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.base.parsers.MarkdownParser
import collection.JavaConverters._
import kotlin.coroutines.Continuation
diff --git a/scala3doc/src/dotty/dokka/SourceLinks.scala b/scala3doc/src/dotty/dokka/SourceLinks.scala
index 11e3c517bb2b..be66d794a7c1 100644
--- a/scala3doc/src/dotty/dokka/SourceLinks.scala
+++ b/scala3doc/src/dotty/dokka/SourceLinks.scala
@@ -85,12 +85,12 @@ case class SourceLinks(links: Seq[SourceLink], projectRoot: Path):
else resolveRelativePath(rawPath)
def pathTo(member: Member): Option[String] =
- member.sources.flatMap(s => pathTo(Paths.get(s.path), Option(s.lineNumber)))
+ member.sources.flatMap(s => pathTo(Paths.get(s.path), Option(s.lineNumber).map(_ + 1)))
object SourceLinks:
val usage =
- """Source links provide a mapping between file in documentation and code repositry (usual)." +
+ """Source links provide a mapping between file in documentation and code repositry.
|Accepted formats:
|
=
|
@@ -135,5 +135,6 @@ object SourceLinks:
load(
config.args.sourceLinks,
config.args.revision,
+ // TODO (https://github.com/lampepfl/scala3doc/issues/240): configure source root
Paths.get("").toAbsolutePath
)
\ No newline at end of file
diff --git a/scala3doc/src/dotty/dokka/compat.scala b/scala3doc/src/dotty/dokka/compat.scala
index c45ff57692b2..f68476cb631c 100644
--- a/scala3doc/src/dotty/dokka/compat.scala
+++ b/scala3doc/src/dotty/dokka/compat.scala
@@ -1,6 +1,6 @@
package dotty.dokka
-import org.jetbrains.dokka.links.{DRI, PointingToDeclaration}
+import org.jetbrains.dokka.links.PointingToDeclaration
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
import collection.JavaConverters._
@@ -21,13 +21,14 @@ val U: kotlin.Unit = kotlin.Unit.INSTANCE
def JList[T](e: T*): JList[T] = e.asJava
def JSet[T](e: T*): JSet[T] = e.toSet.asJava
def JMap[K, V](e: (K, V)*): JMap[K, V] = e.toMap.asJava
-def JMap2[K, V](): JMap[K, V] = ??? // e.toMap.asJava
-def newHMap[K, V](m: JMap[K, V]): HMap[K, V] = new HMap[K, V](m)
type JList[T] = java.util.List[T]
type JSet[T] = java.util.Set[T]
type JMap[K, V] = java.util.Map[K, V]
-type HMap[K, V] = java.util.HashMap[K, V]
+type JHashMap[K, V] = java.util.HashMap[K, V]
+type JMapEntry[K, V] = java.util.Map.Entry[K, V]
+
+type DRI = org.jetbrains.dokka.links.DRI
type SourceSetWrapper = DokkaConfiguration$DokkaSourceSet
type DokkaSourceSet = DokkaConfiguration.DokkaSourceSet
@@ -62,14 +63,18 @@ extension [V](jlist: JList[V]):
def ++ (other: JList[V]): JList[V] =
Stream.of(jlist, other).flatMap(_.stream).collect(Collectors.toList())
+extension [V](jset: JSet[V]):
+ def ++ (other: JSet[V]): JSet[V] =
+ Stream.of(jset, other).flatMap(_.stream).collect(Collectors.toSet())
+
object PluginUtils:
import scala.reflect.ClassTag
import scala.reflect._
- def plugin[T <: DokkaPlugin: ClassTag](ctx: DokkaContext) =
+ def plugin[T <: DokkaPlugin: ClassTag](ctx: DokkaContext) =
ctx.plugin[T](getKotlinClass(implicitly[ClassTag[T]].runtimeClass.asInstanceOf[Class[T]]))
- def query[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): List[E] =
+ def query[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): List[E] =
ctx.get(queryFunction(plugin[T](ctx))).asScala.toList
- def querySingle[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): E =
+ def querySingle[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): E =
ctx.single(queryFunction(plugin[T](ctx)))
diff --git a/scala3doc/src/dotty/dokka/model/api/api.scala b/scala3doc/src/dotty/dokka/model/api/api.scala
index 4ba85604945a..a6cbae170c32 100644
--- a/scala3doc/src/dotty/dokka/model/api/api.scala
+++ b/scala3doc/src/dotty/dokka/model/api/api.scala
@@ -3,10 +3,8 @@ package model
package api
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model._
import collection.JavaConverters._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.pages._
diff --git a/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala b/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala
index 6cf9a8f18d0b..d6236a3f3631 100644
--- a/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala
+++ b/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala
@@ -3,7 +3,6 @@ package model
package api
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.{Projection => JProjection}
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.DFunction
@@ -18,7 +17,6 @@ import org.jetbrains.dokka.model.DPackage
import org.jetbrains.dokka.model.DModule
import collection.JavaConverters._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc.DocumentationNode
import org.jetbrains.dokka.model.properties._
diff --git a/scala3doc/src/dotty/dokka/model/extras.scala b/scala3doc/src/dotty/dokka/model/extras.scala
index f11fffe24d07..5e49f617c929 100644
--- a/scala3doc/src/dotty/dokka/model/extras.scala
+++ b/scala3doc/src/dotty/dokka/model/extras.scala
@@ -1,12 +1,10 @@
package dotty.dokka
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.{Projection => JProjection}
import org.jetbrains.dokka.model._
import org.jetbrains.dokka.pages._
import collection.JavaConverters._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
import org.jetbrains.dokka.model.properties._
import dotty.dokka.model.api._
diff --git a/scala3doc/src/dotty/dokka/model/scalaModel.scala b/scala3doc/src/dotty/dokka/model/scalaModel.scala
index bfaa37085035..0973bb5c8d4b 100644
--- a/scala3doc/src/dotty/dokka/model/scalaModel.scala
+++ b/scala3doc/src/dotty/dokka/model/scalaModel.scala
@@ -1,10 +1,8 @@
package dotty.dokka
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model._
import collection.JavaConverters._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.pages._
diff --git a/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala b/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala
index 7d55a5972f30..17879af5073a 100644
--- a/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala
+++ b/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala
@@ -5,13 +5,15 @@ import org.jetbrains.dokka.pages.{RootPageNode, RendererSpecificResourcePage, Re
import scala.jdk.CollectionConverters._
import com.fasterxml.jackson.databind.ObjectMapper
import dotty.dokka.translators.FilterAttributes
+import java.nio.file.Paths
-class ScalaResourceInstaller extends PageTransformer:
+class ScalaResourceInstaller(args: Args) extends PageTransformer:
private def dottyRes(resourceName: String) =
new RendererSpecificResourcePage(resourceName, java.util.ArrayList(), RenderingStrategy$Copy(s"/dotty_res/$resourceName"))
override def invoke(input: RootPageNode): RootPageNode =
- val newResources = input.getChildren.asScala ++ Seq("fonts", "images", "styles", "scripts", "hljs").map(dottyRes) ++ Seq(dynamicJsData)
+ val defaultResources = input.getChildren.asScala ++ Seq("fonts", "images", "styles", "scripts", "hljs").map(dottyRes)
+ val newResources = projectLogo ++ defaultResources ++ Seq(dynamicJsData)
input.modified(input.getName, newResources.asJava)
private def dynamicJsData =
@@ -20,3 +22,9 @@ class ScalaResourceInstaller extends PageTransformer:
val str = new ObjectMapper().writeValueAsString(data.transform((_, v) => v.asJava).asJava)
new RendererSpecificResourcePage("scripts/data.js", java.util.ArrayList(), RenderingStrategy$Write(s"var scala3DocData = $str"))
+
+ private def projectLogo = args.projectLogo.toSeq.map { path =>
+ val fileName = Paths.get(path).getFileName()
+ val strategy = new RenderingStrategy$Copy(path)
+ new RendererSpecificResourcePage(s"project-logo/$fileName", JList(), strategy)
+ }
diff --git a/scala3doc/src/dotty/dokka/site/LoadedTemplate.scala b/scala3doc/src/dotty/dokka/site/LoadedTemplate.scala
new file mode 100644
index 000000000000..dad0136b375d
--- /dev/null
+++ b/scala3doc/src/dotty/dokka/site/LoadedTemplate.scala
@@ -0,0 +1,48 @@
+package dotty.dokka
+package site
+
+import java.io.File
+import java.nio.file.Files
+import java.nio.file.Paths
+
+import org.jetbrains.dokka.base.renderers.html.{NavigationNode, NavigationPage}
+import org.jetbrains.dokka.model.Documentable
+import org.jetbrains.dokka.pages._
+import org.jetbrains.dokka.transformers.pages.PageTransformer
+import org.jsoup.Jsoup
+import scala.collection.JavaConverters._
+
+
+case class LazyEntry(getKey: String, value: () => String) extends JMapEntry[String, Object]:
+ lazy val getValue: Object = value()
+ def setValue(x$0: Object): Object = ???
+
+case class LoadedTemplate(templateFile: TemplateFile, children: List[LoadedTemplate], file: File):
+
+ private def brief(ctx: StaticSiteContext): String =
+ val code = Jsoup.parse(resolveToHtml(ctx).code)
+ code.select("p").first().outerHtml()
+
+ def lazyTemplateProperties(ctx: StaticSiteContext): JMap[String, Object] = new java.util.AbstractMap[String, Object]():
+ def entrySet(): JSet[JMapEntry[String, Object]] =
+ val site = templateFile.settings.getOrElse("page", Map.empty).asInstanceOf[Map[String, Object]]
+ site.asJava.entrySet() ++ JSet(
+ LazyEntry("url", () => ctx.relativePath(LoadedTemplate.this).toString),
+ LazyEntry("title", () => templateFile.title),
+ LazyEntry("excerpt", () => brief(ctx))
+ )
+
+ def resolveToHtml(ctx: StaticSiteContext): ResolvedPage =
+ val posts = children.map(_.lazyTemplateProperties(ctx))
+ val site = templateFile.settings.getOrElse("site", Map.empty).asInstanceOf[Map[String, Object]]
+ val sourceLinks = if !file.exists() then Nil else
+ // TODO (https://github.com/lampepfl/scala3doc/issues/240): configure source root
+ // toRealPath is used to turn symlinks into proper paths
+ val actualPath = Paths.get("").toAbsolutePath.relativize(file.toPath.toRealPath())
+ ctx.sourceLinks.pathTo(actualPath).map("viewSource" -> _ ) ++
+ ctx.sourceLinks.pathTo(actualPath, operation = "edit").map("editSource" -> _ )
+
+ val updatedSettings = templateFile.settings ++ ctx.projectWideProperties +
+ ("site" -> (site + ("posts" -> posts))) + ("urls" -> sourceLinks.toMap)
+
+ templateFile.resolveInner(RenderingContext(updatedSettings, ctx.layouts))
diff --git a/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala b/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala
index 88ca16e1146a..a0b6a3e45349 100644
--- a/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala
+++ b/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala
@@ -7,9 +7,12 @@ import org.jetbrains.dokka.pages.{ContentNode, DCI, Style}
import org.jetbrains.dokka.base.resolvers.local.LocationProvider
import com.vladsch.flexmark.convert.html.FlexmarkHtmlParser
import org.jsoup.Jsoup
+import scala.collection.JavaConverters._
+import scala.util.Try
+import java.net.URL
case class PartiallyRenderedContent(
- template: TemplateFile,
+ template: LoadedTemplate,
context: StaticSiteContext,
override val getChildren: JList[ContentNode],
override val getDci: DCI,
@@ -27,7 +30,13 @@ case class PartiallyRenderedContent(
lazy val resolved = template.resolveToHtml(context)
- def procsesHtml(linkTo: String => String): String =
+ def procsesHtml(linkTo: String => String, absoluteResource: String => String): String =
val document = Jsoup.parse(resolved.code)
- document.select("a").forEach(element => element.attr("href", linkTo(element.attr("href"))))// forrach does not work here
+ document.select("a").forEach(element => element.attr("href", linkTo(element.attr("href"))))
+ document.select("img").forEach { element =>
+ val link = element.attr("src")
+ Try(new URL(link)).getOrElse {
+ if(link.startsWith("/")) element.attr("src", absoluteResource(link.drop(1)))
+ }
+ }// forrach does not work here
document.outerHtml()
diff --git a/scala3doc/src/dotty/dokka/site/StaticPageNode.scala b/scala3doc/src/dotty/dokka/site/StaticPageNode.scala
index b543ee82ff54..58f35f1961f4 100644
--- a/scala3doc/src/dotty/dokka/site/StaticPageNode.scala
+++ b/scala3doc/src/dotty/dokka/site/StaticPageNode.scala
@@ -5,13 +5,10 @@ import java.io.File
import java.nio.file.Files
import org.jetbrains.dokka.base.renderers.html.{NavigationNode, NavigationPage}
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.pages._
import org.jetbrains.dokka.transformers.pages.PageTransformer
-case class LoadedTemplate(templateFile: TemplateFile, children: List[LoadedTemplate], file: File)
-
case class StaticPageNode(
template: TemplateFile,
override val getName: String,
diff --git a/scala3doc/src/dotty/dokka/site/StaticSiteContext.scala b/scala3doc/src/dotty/dokka/site/StaticSiteContext.scala
index 3ba27f23f512..d4acc738e197 100644
--- a/scala3doc/src/dotty/dokka/site/StaticSiteContext.scala
+++ b/scala3doc/src/dotty/dokka/site/StaticSiteContext.scala
@@ -10,7 +10,6 @@ import java.nio.file.Paths
import org.jetbrains.dokka.base.parsers.MarkdownParser
import org.jetbrains.dokka.base.transformers.pages.comments.DocTagToContentConverter
import org.jetbrains.dokka.DokkaConfiguration
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.doc.{DocTag, Text}
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.pages.{ContentKind, ContentNode, DCI, PageNode}
@@ -21,7 +20,9 @@ import util.Try
import scala.collection.JavaConverters._
-class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
+class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper], args: Args, val sourceLinks: SourceLinks):
+
+ var memberLinkResolver: String => Option[DRI] = _ => None
def indexPage():Option[StaticPageNode] =
val files = List(new File(root, "index.html"), new File(root, "index.md")).filter { _.exists() }
@@ -78,7 +79,6 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
if (indexes.size > 1)
// TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
println(s"ERROR: Multiple index pages for $from found in ${indexes.map(_.file)}")
-
def loadIndexPage(): TemplateFile =
val indexFiles = from.listFiles { file =>file.getName == "index.md" || file.getName == "index.html" }
indexFiles.size match
@@ -90,7 +90,13 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
val templateFile = if (from.isDirectory) loadIndexPage() else loadTemplateFile(from)
- Some(LoadedTemplate(templateFile, children.toList, from))
+ val processedChildren = if !isBlog then children else
+ def dateFrom(p: LoadedTemplate): String =
+ val pageSettings = p.templateFile.settings.get("page").collect{ case m: Map[String @unchecked, _] => m }
+ pageSettings.flatMap(_.get("date").collect{ case s: String => s}).getOrElse("1900-01-01") // blogs without date are last
+ children.sortBy(dateFrom).reverse
+
+ Some(LoadedTemplate(templateFile, processedChildren.toList, from))
catch
case e: RuntimeException =>
// TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
@@ -111,7 +117,7 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
val path = if isBlog then "blog" else url.stripSuffix(".html") + ".md"
val file = root.toPath.resolve(path) // Add support for .html files!
val LoadedTemplate(template, children, tFile) = loadTemplate(file.toFile, isBlog).get // Add proper logging if file does not exisits
- LoadedTemplate(template.copy(settings = template.settings + ("title" -> title)), children, tFile)
+ LoadedTemplate(template.copy(settings = template.settings + ("title" -> title)), children, tFile)
case Sidebar.Category(title, nested) =>
// Add support for index.html/index.md files!
val fakeFile = new File(root, title)
@@ -122,17 +128,23 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
dir("docs").flatMap(_.listFiles()).flatMap(loadTemplate(_, isBlog = false))
++ dir("blog").flatMap(loadTemplate(_, isBlog = true))
- def driForLink(template: TemplateFile, link: String): Try[DRI] = Try(driFor(
+ def driForLink(template: TemplateFile, link: String): Option[DRI] =
+ val pathDri = Try {
+ val path =
if link.startsWith("/") then root.toPath.resolve(link.drop(1))
else template.file.toPath.getParent().resolve(link)
- ))
+ if Files.exists(path) then Some(driFor(path)) else None
+ }.toOption.flatten
+ pathDri.orElse(memberLinkResolver(link))
- private def driFor(dest: Path): DRI = mkDRI(s"_.${root.toPath.relativize(dest)}")
+ def driFor(dest: Path): DRI = mkDRI(s"_.${root.toPath.relativize(dest)}")
+
+ def relativePath(myTemplate: LoadedTemplate) = root.toPath.relativize(myTemplate.file.toPath)
def templateToPage(myTemplate: LoadedTemplate): StaticPageNode =
val dri = driFor(myTemplate.file.toPath)
val content = new PartiallyRenderedContent(
- myTemplate.templateFile,
+ myTemplate,
this,
JList(),
new DCI(Set(dri).asJava, ContentKind.Empty),
@@ -147,3 +159,8 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
JList(),
(myTemplate.children.map(templateToPage)).asJava
)
+
+ val projectWideProperties =
+ Seq("projectName" -> args.name) ++
+ args.projectVersion.map("projectVersion" -> _) ++
+ args.projectTitle.map("projectTitle" -> _)
diff --git a/scala3doc/src/dotty/dokka/site/common.scala b/scala3doc/src/dotty/dokka/site/common.scala
index 7d21243c05c2..9f93d75c51a6 100644
--- a/scala3doc/src/dotty/dokka/site/common.scala
+++ b/scala3doc/src/dotty/dokka/site/common.scala
@@ -13,7 +13,7 @@ import com.vladsch.flexmark.ext.tables.TablesExtension
import com.vladsch.flexmark.ext.yaml.front.matter.{AbstractYamlFrontMatterVisitor, YamlFrontMatterExtension}
import com.vladsch.flexmark.parser.{Parser, ParserEmulationProfile}
import com.vladsch.flexmark.util.options.{DataHolder, MutableDataSet}
-import org.jetbrains.dokka.links.{DRI, PointingToDeclaration}
+import com.vladsch.flexmark.ext.wikilink.WikiLinkExtension
import org.jetbrains.dokka.model.doc.Text
import scala.collection.JavaConverters._
@@ -25,20 +25,19 @@ val apiPageDRI: DRI = mkDRI(packageName = "api", extra = "__api__")
val defaultMarkdownOptions: DataHolder =
new MutableDataSet()
.setFrom(ParserEmulationProfile.KRAMDOWN.getOptions)
- .set(
- Parser.EXTENSIONS, List(
- TablesExtension.create(),
- TaskListExtension.create(),
- AutolinkExtension.create(),
- AnchorLinkExtension.create(),
- EmojiExtension.create(),
- YamlFrontMatterExtension.create(),
- StrikethroughExtension.create()
- ).asJava)
- .set(
- EmojiExtension.ROOT_IMAGE_PATH,
- "https://github.global.ssl.fastly.net/images/icons/emoji/"
- )
+ .set(AnchorLinkExtension.ANCHORLINKS_WRAP_TEXT, false)
+ .set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
+ .set(EmojiExtension.ROOT_IMAGE_PATH, "https://github.global.ssl.fastly.net/images/icons/emoji/")
+ .set(Parser.EXTENSIONS, java.util.Arrays.asList(
+ TablesExtension.create(),
+ TaskListExtension.create(),
+ AutolinkExtension.create(),
+ AnchorLinkExtension.create(),
+ EmojiExtension.create(),
+ YamlFrontMatterExtension.create(),
+ StrikethroughExtension.create(),
+ WikiLinkExtension.create()
+ ))
def emptyTemplate(file: File, title: String): TemplateFile = TemplateFile(
file = file,
@@ -84,11 +83,11 @@ def loadTemplateFile(file: File): TemplateFile = {
case elem: String => elem
case other => throw new RuntimeException(s"Expected a string setting for $name in $file but got $other")
}.map(_.stripPrefix("\"").stripSuffix("\""))
-
+
def listSetting(settings: Map[String, Object], name: String): Option[List[String]] = settings.get(name).map {
case elems: List[_] => elems.zipWithIndex.map {
case (s: String, _) => s
- case (other, index) =>
+ case (other, index) =>
throw new RuntimeException(s"Expected a string at index $index for $name in $file but got $other")
}
case elem: String => List(elem)
diff --git a/scala3doc/src/dotty/dokka/site/processors.scala b/scala3doc/src/dotty/dokka/site/processors.scala
index 27375978c706..fcccd9f02f4f 100644
--- a/scala3doc/src/dotty/dokka/site/processors.scala
+++ b/scala3doc/src/dotty/dokka/site/processors.scala
@@ -6,7 +6,6 @@ import java.nio.file.Files
import java.nio.file.FileVisitOption
import org.jetbrains.dokka.base.renderers.html.{NavigationNode, NavigationPage}
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.pages._
import org.jetbrains.dokka.transformers.pages.PageTransformer
diff --git a/scala3doc/src/dotty/dokka/site/templates.scala b/scala3doc/src/dotty/dokka/site/templates.scala
index eecab0a286f6..bc2f754fe8fb 100644
--- a/scala3doc/src/dotty/dokka/site/templates.scala
+++ b/scala3doc/src/dotty/dokka/site/templates.scala
@@ -55,8 +55,6 @@ case class TemplateFile(
):
def isIndexPage() = file.isFile && (file.getName == "index.md" || file.getName == "index.html")
- def resolveToHtml(ctx: StaticSiteContext): ResolvedPage = resolveInner(RenderingContext(settings, ctx.layouts))
-
private[site] def resolveInner(ctx: RenderingContext): ResolvedPage =
if (ctx.resolving.contains(file.getAbsolutePath))
throw new RuntimeException(s"Cycle in templates involving $file: ${ctx.resolving}")
@@ -64,19 +62,19 @@ case class TemplateFile(
val layoutTemplate = layout.map(name =>
ctx.layouts.getOrElse(name, throw new RuntimeException(s"No layouts named $name in ${ctx.layouts}")))
- def asJavaElement(k: String, v: Object): Object = v match
+ def asJavaElement(o: Object): Object = o match
case m: Map[_, _] => m.transform {
- case (k: String, v: Object) => asJavaElement(k, v)
+ case (k: String, v: Object) => asJavaElement(v)
}.asJava
- case l: List[_] => l.asJava
+ case l: List[_] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava
case other => other
// Library requires mutable maps..
- val mutableProperties = HMap(ctx.properties.transform(asJavaElement).asJava)
+ val mutableProperties = JHashMap(ctx.properties.transform((_, v) => asJavaElement(v)).asJava)
val rendered = Template.parse(this.rawCode).render(mutableProperties)
// We want to render markdown only if next template is html
val code = if (isHtml || layoutTemplate.exists(!_.isHtml)) rendered else
- val parser: Parser = Parser.builder().build()
+ val parser: Parser = Parser.builder(defaultMarkdownOptions).build()
HtmlRenderer.builder(defaultMarkdownOptions).build().render(parser.parse(rendered))
layoutTemplate match
diff --git a/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala b/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala
index e49244678e44..d33fac7752c0 100644
--- a/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala
+++ b/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala
@@ -1,6 +1,6 @@
-package dotty.dokka.tasty
+package dotty.dokka
+package tasty
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model._
import collection.JavaConverters._
import dotty.dokka._
@@ -47,7 +47,4 @@ trait BasicSupport:
def getAnnotations(): List[Annotation] =
sym.annots.filterNot(_.symbol.packageName.startsWith("scala.annotation.internal")).map(parseAnnotation).reverse
- private val emptyDRI = DRI.Companion.getTopLevel
-
-
diff --git a/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala b/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala
index 6de72f1fb18d..8a25aa7a86a2 100644
--- a/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala
+++ b/scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala
@@ -1,7 +1,6 @@
package dotty.dokka.tasty
import org.jetbrains.dokka.model.{TypeConstructor => DTypeConstructor, _}
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
import collection.JavaConverters._
diff --git a/scala3doc/src/dotty/dokka/tasty/PackageSupport.scala b/scala3doc/src/dotty/dokka/tasty/PackageSupport.scala
index 6dd08843364f..5ebff3b556f0 100644
--- a/scala3doc/src/dotty/dokka/tasty/PackageSupport.scala
+++ b/scala3doc/src/dotty/dokka/tasty/PackageSupport.scala
@@ -2,7 +2,7 @@ package dotty.dokka
package tasty
import org.jetbrains.dokka.model._
-import org.jetbrains.dokka.links._
+import org.jetbrains.dokka.links.PointingToDeclaration
import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.model.doc.DocumentationNode
import dotty.dokka._
diff --git a/scala3doc/src/dotty/dokka/tasty/TastyParser.scala b/scala3doc/src/dotty/dokka/tasty/TastyParser.scala
index 67985b4626b9..4d88ed152470 100644
--- a/scala3doc/src/dotty/dokka/tasty/TastyParser.scala
+++ b/scala3doc/src/dotty/dokka/tasty/TastyParser.scala
@@ -6,7 +6,6 @@ import org.jetbrains.dokka.transformers.sources._
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.model._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
import org.jetbrains.dokka.base.parsers._
import org.jetbrains.dokka.plugability.DokkaContext
@@ -18,6 +17,9 @@ import org.jetbrains.dokka.model.properties.{WithExtraProperties}
import quoted.QuoteContext
import scala.tasty.inspector.TastyInspector
import dotty.dokka.model.api.withNewMembers
+import dotty.dokka.tasty.comments.MemberLookup
+import dotty.dokka.tasty.comments.QueryParser
+import scala.util.Try
/** Responsible for collectively inspecting all the Tasty files we're interested in.
*
@@ -101,6 +103,15 @@ trait DokkaBaseTastyInspector:
def processCompilationUnit(using qctx: QuoteContext)(root: qctx.reflect.Tree): Unit =
val parser = new TastyParser(qctx, this, config)
+
+ def driFor(link: String): Option[DRI] =
+ val symOps = new SymOps[qctx.type](qctx)
+ import symOps._
+ Try(QueryParser(link).readQuery()).toOption.flatMap(q =>
+ MemberLookup.lookupOpt(q, None).map{ case (sym, _) => sym.dri}
+ )
+
+ config.staticSiteContext.foreach(_.memberLinkResolver = driFor)
topLevels ++= parser.parseRootTree(root.asInstanceOf[parser.qctx.reflect.Tree])
def result(): List[DPackage] =
diff --git a/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala b/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala
index f07a5350debd..0b3acbb025be 100644
--- a/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala
+++ b/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala
@@ -12,47 +12,52 @@ trait MemberLookup {
def lookupOpt(using QuoteContext)(
query: Query,
ownerOpt: Option[qctx.reflect.Symbol],
- ): Option[(qctx.reflect.Symbol, String)] = {
- import qctx.reflect._
-
- def nearestClass(sym: Symbol): Symbol =
- if sym.isClassDef then sym else nearestClass(sym.owner)
-
- def nearestPackage(sym: Symbol): Symbol =
- if sym.flags.is(Flags.Package) then sym else nearestPackage(sym.owner)
-
- def nearestMembered(sym: Symbol): Symbol =
- if sym.isClassDef || sym.flags.is(Flags.Package) then sym else nearestMembered(sym.owner)
-
- val res =
- ownerOpt match {
- case Some(owner) =>
- val nearest = nearestMembered(owner)
- val nearestCls = nearestClass(owner)
- val nearestPkg = nearestPackage(owner)
- query match {
- case Query.StrictMemberId(id) => localLookup(id, nearest).map(_ -> id)
- case Query.Id(id) =>
- (localLookup(id, nearest) orElse localLookup(id, nearestPkg)).map(_ -> id)
- case Query.QualifiedId(Query.Qual.This, _, rest) =>
- downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
- case Query.QualifiedId(Query.Qual.Package, _, rest) =>
- downwardLookup(rest.asList, nearestPkg).map(_ -> rest.join)
- case Query.QualifiedId(Query.Qual.Id(id), _, rest) if id == nearestCls.name =>
- downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
- case Query.QualifiedId(Query.Qual.Id(id), _, rest) if id == nearestPkg.name =>
- downwardLookup(rest.asList, nearestPkg).map(_ -> rest.join)
- case query: Query.QualifiedId => downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join)
- }
-
- case None =>
- downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join)
- }
-
- // println(s"looked up `$query` in ${owner.show}[${owner.flags.show}] as ${res.map(_.show)}")
-
- res
- }
+ ): Option[(qctx.reflect.Symbol, String)] =
+ try
+ import qctx.reflect._
+
+ def nearestClass(sym: Symbol): Symbol =
+ if sym.isClassDef then sym else nearestClass(sym.owner)
+
+ def nearestPackage(sym: Symbol): Symbol =
+ if sym.flags.is(Flags.Package) then sym else nearestPackage(sym.owner)
+
+ def nearestMembered(sym: Symbol): Symbol =
+ if sym.isClassDef || sym.flags.is(Flags.Package) then sym else nearestMembered(sym.owner)
+
+ val res =
+ ownerOpt match {
+ case Some(owner) =>
+ val nearest = nearestMembered(owner)
+ val nearestCls = nearestClass(owner)
+ val nearestPkg = nearestPackage(owner)
+ query match {
+ case Query.StrictMemberId(id) => localLookup(id, nearest).map(_ -> id)
+ case Query.Id(id) =>
+ (localLookup(id, nearest) orElse localLookup(id, nearestPkg)).map(_ -> id)
+ case Query.QualifiedId(Query.Qual.This, _, rest) =>
+ downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
+ case Query.QualifiedId(Query.Qual.Package, _, rest) =>
+ downwardLookup(rest.asList, nearestPkg).map(_ -> rest.join)
+ case Query.QualifiedId(Query.Qual.Id(id), _, rest) if id == nearestCls.name =>
+ downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
+ case Query.QualifiedId(Query.Qual.Id(id), _, rest) if id == nearestPkg.name =>
+ downwardLookup(rest.asList, nearestPkg).map(_ -> rest.join)
+ case query: Query.QualifiedId => downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join)
+ }
+
+ case None =>
+ downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join)
+ }
+
+ // println(s"looked up `$query` in ${owner.show}[${owner.flags.show}] as ${res.map(_.show)}")
+
+ res
+ catch
+ case e: Exception =>
+ // TODO (https://github.com/lampepfl/scala3doc/issues/238): proper reporting
+ println(s"[WARN] Unable to find a link for ${query} ${ownerOpt.fold("")(o => "in " + o.name)}")
+ None
private def hackMembersOf(using QuoteContext)(rsym: qctx.reflect.Symbol) = {
import qctx.reflect._
diff --git a/scala3doc/src/dotty/dokka/transformers/ImplicitMembersExtensionTransformer.scala b/scala3doc/src/dotty/dokka/transformers/ImplicitMembersExtensionTransformer.scala
index cac96da63409..676fcd49d079 100644
--- a/scala3doc/src/dotty/dokka/transformers/ImplicitMembersExtensionTransformer.scala
+++ b/scala3doc/src/dotty/dokka/transformers/ImplicitMembersExtensionTransformer.scala
@@ -5,7 +5,6 @@ import org.jetbrains.dokka.model._
import collection.JavaConverters
import collection.JavaConverters._
import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.properties._
import dotty.dokka.model._
diff --git a/scala3doc/src/dotty/dokka/transformers/InheritanceInformationTransformer.scala b/scala3doc/src/dotty/dokka/transformers/InheritanceInformationTransformer.scala
index 2dd864ad7bc4..0382fb609955 100644
--- a/scala3doc/src/dotty/dokka/transformers/InheritanceInformationTransformer.scala
+++ b/scala3doc/src/dotty/dokka/transformers/InheritanceInformationTransformer.scala
@@ -4,7 +4,6 @@ import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer
import org.jetbrains.dokka.model._
import collection.JavaConverters._
import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.properties._
import dotty.dokka.model._
diff --git a/scala3doc/src/dotty/dokka/translators/FilterAttributes.scala b/scala3doc/src/dotty/dokka/translators/FilterAttributes.scala
index fbef51408e4b..ced94b5a3f96 100644
--- a/scala3doc/src/dotty/dokka/translators/FilterAttributes.scala
+++ b/scala3doc/src/dotty/dokka/translators/FilterAttributes.scala
@@ -12,7 +12,6 @@ import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
import org.jetbrains.dokka.base.resolvers.anchors._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.model.doc._
import dotty.dokka.model.api._
diff --git a/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala b/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala
index e15296aa88a8..a555d678491c 100644
--- a/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala
+++ b/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala
@@ -13,7 +13,6 @@ import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
import org.jetbrains.dokka.base.resolvers.anchors._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.model.doc._
import dotty.dokka.model.api.{Kind => _, Link => SLink, _}
diff --git a/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala b/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala
index 6f2fabeaf713..38981dd5dc1a 100644
--- a/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala
+++ b/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala
@@ -16,9 +16,7 @@ import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions
import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet
import org.jetbrains.dokka.base.resolvers.anchors._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.model.doc._
-import org.jetbrains.dokka.links.DRIKt.getParent
import dotty.dokka.model.api._
import dotty.dokka.model.api.Kind
import dotty.dokka.model.api.Link
diff --git a/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala b/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala
index 35911cbd1e18..6a6e3b1f0c1a 100644
--- a/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala
+++ b/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala
@@ -12,7 +12,6 @@ import org.jetbrains.dokka.base.translators.documentables._
import org.jetbrains.dokka.model.properties.PropertyContainer
import java.util.function.Consumer
import kotlin.jvm.functions.Function2
-import org.jetbrains.dokka.links.DRI
import dotty.dokka.model.api.{Kind, _}
diff --git a/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala b/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala
index f091e6a1f118..c6e9fab30846 100644
--- a/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala
+++ b/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala
@@ -2,7 +2,6 @@ package dotty.dokka
import org.jetbrains.dokka.base.signatures._
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model._
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages._
diff --git a/scala3doc/src/dotty/dokka/utils.scala b/scala3doc/src/dotty/dokka/utils.scala
index 31a6afae752a..5763eddde4a4 100644
--- a/scala3doc/src/dotty/dokka/utils.scala
+++ b/scala3doc/src/dotty/dokka/utils.scala
@@ -4,7 +4,6 @@ import org.jetbrains.dokka.model.properties._
import org.jetbrains.dokka.base.signatures._
import org.jetbrains.dokka.model._
import org.jetbrains.dokka.pages._
-import org.jetbrains.dokka.links._
import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider
import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
import org.jetbrains.dokka.utilities.DokkaLogger
diff --git a/scala3doc/src/dotty/renderers/DotDiagramBuilder.scala b/scala3doc/src/dotty/renderers/DotDiagramBuilder.scala
index 0c680aa0f012..226d4e6ae394 100644
--- a/scala3doc/src/dotty/renderers/DotDiagramBuilder.scala
+++ b/scala3doc/src/dotty/renderers/DotDiagramBuilder.scala
@@ -2,7 +2,6 @@ package dotty.dokka
import dotty.dokka.model._
import org.jetbrains.dokka.model._
-import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.pages._
import dotty.dokka.model.api.Kind
import HTML._
diff --git a/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala b/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala
index 277a030eb7eb..ada77dc0d100 100644
--- a/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala
+++ b/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala
@@ -16,7 +16,6 @@ import kotlinx.html.Gen_consumer_tagsKt
import kotlinx.html.ApiKt
import kotlinx.html.HTMLTag
import kotlinx.html.DIV
-import org.jetbrains.dokka.links.DRI
import dotty.dokka.model.api.Link
import dotty.dokka.model.api.HierarchyGraph
import org.jetbrains.dokka.base.resolvers.local.LocationProvider
@@ -24,6 +23,8 @@ import dotty.dokka.site.StaticPageNode
import dotty.dokka.site.PartiallyRenderedContent
import scala.util.Try
import org.jetbrains.dokka.base.renderers.html.SearchbarDataInstaller
+import org.jsoup.Jsoup
+import java.nio.file.Paths
class SignatureRenderer(pageContext: ContentPage, sourceSetRestriciton: JSet[DisplaySourceSet], locationProvider: LocationProvider):
def link(dri: DRI): Option[String] = Option(locationProvider.resolve(dri, sourceSetRestriciton, pageContext))
@@ -41,7 +42,7 @@ class SignatureRenderer(pageContext: ContentPage, sourceSetRestriciton: JSet[Dis
def renderElement(e: String | (String, DRI) | Link) = renderElementWith(e)
-class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
+class ScalaHtmlRenderer(ctx: DokkaContext, args: Args) extends HtmlRenderer(ctx) {
// TODO #239
val hackScalaSearchbarDataInstaller: SearchbarDataInstaller = {
@@ -252,12 +253,15 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
page.getContent match
case prc: PartiallyRenderedContent =>
def processLocalLink(str: String): String =
+ Try(URL(str)).map(_ => str).getOrElse{
// TODO (https://github.com/lampepfl/scala3doc/issues/238) error handling
- prc.context.driForLink(prc.template, str).toOption
- .flatMap(dri => Option(getLocationProvider.resolve(dri, sourceSets, page)))
- .getOrElse(str)
+ prc.context.driForLink(prc.template.templateFile, str)
+ .flatMap(dri => Option(getLocationProvider.resolve(dri, sourceSets, page)))
+ .getOrElse(str)
+ }
- withHtml(context, prc.procsesHtml(url => Try(URL(url)).fold(_ => processLocalLink(url), _ => url)))
+ val html = prc.procsesHtml(processLocalLink, resolveLink(page))
+ withHtml(context, html)
case content =>
build(content, context, page, /*sourceSetRestriction=*/null)
@@ -269,6 +273,12 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
case _ =>
(page.getName, false)
+ val projectLogo =
+ args.projectLogo.map { path =>
+ val fileName = Paths.get(path).getFileName()
+ span(img(src := resolveRoot(page, s"project-logo/$fileName")))
+ }.toSeq
+
html(
head(
meta(charset := "utf-8"),
@@ -281,7 +291,13 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
if noFrame then raw(buildWithKotlinx(kotlinxContent)) else
div(id := "container")(
div(id := "leftColumn")(
- div(id := "logo"),
+ div(id := "logo")(
+ projectLogo,
+ span(
+ div(cls:="projectName")(args.name),
+ args.projectVersion.map(v => div(cls:="projectVersion")(v)).toList
+ )
+ ),
div(id := "paneSearch"),
nav(id := "sideMenu"),
),
@@ -300,9 +316,9 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
raw(" Back to top")
)
),
- span(cls := "pull-right")(
- raw("Generated by "),
- a(href := "https://github.com/lampepfl/scala3doc")("Scala3doc")
+ raw("Generated by "),
+ a(href := "https://github.com/lampepfl/dotty/tree/master/scala3doc")(
+ img(src := resolveRoot(page, "images/scala3doc_logo.svg"), alt := "Scala3doc", cls := "scala3doc_logo")
)
)
)
@@ -315,6 +331,9 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
private def resolveRoot(page: PageNode, path: String) =
getLocationProvider.pathToRoot(page) + path
+ private def resolveLink(page: PageNode)(url: String): String =
+ if URI(url).isAbsolute then url else resolveRoot(page, url)
+
private def linkResources(page: PageNode, resources: Iterable[String]): Iterable[AppliedTag] =
def fileExtension(url: String): String =
val param = url.indexOf('?')
@@ -322,13 +341,10 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
val point = url.lastIndexOf('.', end)
url.substring(point+1, end)
- def resolveLink(url: String): String =
- if URI(url).isAbsolute then url else resolveRoot(page, url)
-
for res <- resources yield
fileExtension(res) match
- case "css" => link(rel := "stylesheet", href := resolveLink(res))
- case "js" => script(`type` := "text/javascript", src := resolveLink(res), defer := "true")
+ case "css" => link(rel := "stylesheet", href := resolveLink(page)(res))
+ case "js" => script(`type` := "text/javascript", src := resolveLink(page)(res), defer := "true")
case _ => raw(res)
private def buildWithKotlinx(node: ContentNode, pageContext: ContentPage, sourceSetRestriction: JSet[DisplaySourceSet]): String =
diff --git a/scala3doc/src/dotty/renderers/html.scala b/scala3doc/src/dotty/renderers/html.scala
index f19b0ac288d9..b5cd9668fa5f 100644
--- a/scala3doc/src/dotty/renderers/html.scala
+++ b/scala3doc/src/dotty/renderers/html.scala
@@ -76,6 +76,7 @@ object HTML:
val title = Tag("title")
val body = Tag("body")
val nav = Tag("nav")
+ val img = Tag("img")
val cls = Attr("class")
val href = Attr("href")
@@ -90,6 +91,7 @@ object HTML:
val name = Attr("name")
val content = Attr("content")
val testId = Attr("data-test-id")
+ val alt = Attr("alt")
def raw(content: String): AppliedTag = AppliedTag(content)
diff --git a/scala3doc/test/dotty/dokka/ScaladocTest.scala b/scala3doc/test/dotty/dokka/ScaladocTest.scala
index b657af779a50..d54c3c132d44 100644
--- a/scala3doc/test/dotty/dokka/ScaladocTest.scala
+++ b/scala3doc/test/dotty/dokka/ScaladocTest.scala
@@ -26,7 +26,7 @@ abstract class ScaladocTest(val name: String):
classpath = System.getProperty("java.class.path"),
None,
output = getTempDir().getRoot,
- projectVersion = "1.0",
+ projectVersion = Some("1.0"),
projectTitle = None,
projectLogo = None,
defaultSyntax = None,
diff --git a/scala3doc/test/dotty/dokka/SignatureTestCases.scala b/scala3doc/test/dotty/dokka/SignatureTestCases.scala
index eb8f8731d691..299737b4e82a 100644
--- a/scala3doc/test/dotty/dokka/SignatureTestCases.scala
+++ b/scala3doc/test/dotty/dokka/SignatureTestCases.scala
@@ -58,3 +58,5 @@ class InheritedMembers extends SignatureTest("inheritedMembers2", SignatureTest.
sourceFiles = List("inheritedMembers1", "inheritedMembers2"))
class ComplexNames extends SignatureTest("complexNames", Seq("def"))
+
+class WrongDocumentationLinks extends SignatureTest("links", Seq("def"))
\ No newline at end of file
diff --git a/scala3doc/test/dotty/dokka/SourceLinksTests.scala b/scala3doc/test/dotty/dokka/SourceLinksTests.scala
index f54493d583cf..9b72b9053f36 100644
--- a/scala3doc/test/dotty/dokka/SourceLinksTests.scala
+++ b/scala3doc/test/dotty/dokka/SourceLinksTests.scala
@@ -56,6 +56,7 @@ class SourceLinkTest:
}
class SourceLinksTest:
+ // TODO (https://github.com/lampepfl/scala3doc/issues/240): configure source root
val projectRoot = Paths.get("").toAbsolutePath()
val edit: Operation = "edit" // union types need explicit singletons
diff --git a/scala3doc/test/dotty/dokka/site/TemplateFileTests.scala b/scala3doc/test/dotty/dokka/site/TemplateFileTests.scala
index 7a66810eae36..97682256e2aa 100644
--- a/scala3doc/test/dotty/dokka/site/TemplateFileTests.scala
+++ b/scala3doc/test/dotty/dokka/site/TemplateFileTests.scala
@@ -133,9 +133,9 @@ class TemplateFileTests:
val expected =
- """Test page
+ """
Test page
|
Hello world!!
- |
Test page end
+ |
Test page end
|
""".stripMargin
testContent(
@@ -203,7 +203,9 @@ class TemplateFileTests:
"""# Hello {{ msg }}!""",
ext = "md"
) { t =>
- assertEquals("
Hello there!
", t.resolveInner(RenderingContext(Map("msg" -> "there"))).code.trim())
+ assertEquals(
+ """
Hello there!
""",
+ t.resolveInner(RenderingContext(Map("msg" -> "there"))).code.trim())
}
@Test
@@ -212,7 +214,8 @@ class TemplateFileTests:
"""# Hello {{ msg }}!""",
ext = "md"
) { t =>
- assertEquals("
Hello there!
", t.resolveInner(RenderingContext(Map("msg" -> "there"))).code.trim())
+ assertEquals("""
Hello there!
""",
+ t.resolveInner(RenderingContext(Map("msg" -> "there"))).code.trim())
}
@Test