Skip to content

Commit 9124767

Browse files
committed
Blog improvments
- add links - implement more generic children mechanism
1 parent f0bfd07 commit 9124767

File tree

7 files changed

+77
-35
lines changed

7 files changed

+77
-35
lines changed

scala3doc/src/dotty/dokka/compat.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ val U: kotlin.Unit = kotlin.Unit.INSTANCE
2121
def JList[T](e: T*): JList[T] = e.asJava
2222
def JSet[T](e: T*): JSet[T] = e.toSet.asJava
2323
def JMap[K, V](e: (K, V)*): JMap[K, V] = e.toMap.asJava
24-
def JMap2[K, V](): JMap[K, V] = ??? // e.toMap.asJava
25-
def newHMap[K, V](m: JMap[K, V]): HMap[K, V] = new HMap[K, V](m)
2624

2725
type JList[T] = java.util.List[T]
2826
type JSet[T] = java.util.Set[T]
2927
type JMap[K, V] = java.util.Map[K, V]
30-
type HMap[K, V] = java.util.HashMap[K, V]
28+
type JHashMap[K, V] = java.util.HashMap[K, V]
29+
type JMapEntry[K, V] = java.util.Map.Entry[K, V]
3130

3231
type SourceSetWrapper = DokkaConfiguration$DokkaSourceSet
3332
type DokkaSourceSet = DokkaConfiguration.DokkaSourceSet
@@ -62,14 +61,18 @@ extension [V](jlist: JList[V]):
6261
def ++ (other: JList[V]): JList[V] =
6362
Stream.of(jlist, other).flatMap(_.stream).collect(Collectors.toList())
6463

64+
extension [V](jset: JSet[V]):
65+
def ++ (other: JSet[V]): JSet[V] =
66+
Stream.of(jset, other).flatMap(_.stream).collect(Collectors.toSet())
67+
6568
object PluginUtils:
6669
import scala.reflect.ClassTag
6770
import scala.reflect._
68-
def plugin[T <: DokkaPlugin: ClassTag](ctx: DokkaContext) =
71+
def plugin[T <: DokkaPlugin: ClassTag](ctx: DokkaContext) =
6972
ctx.plugin[T](getKotlinClass(implicitly[ClassTag[T]].runtimeClass.asInstanceOf[Class[T]]))
7073

71-
def query[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): List[E] =
74+
def query[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): List[E] =
7275
ctx.get(queryFunction(plugin[T](ctx))).asScala.toList
7376

74-
def querySingle[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): E =
77+
def querySingle[T <: DokkaPlugin: ClassTag, E](ctx: DokkaContext, queryFunction: (T) => ExtensionPoint[E]): E =
7578
ctx.single(queryFunction(plugin[T](ctx)))
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package dotty.dokka
2+
package site
3+
4+
import java.io.File
5+
import java.nio.file.Files
6+
7+
import org.jetbrains.dokka.base.renderers.html.{NavigationNode, NavigationPage}
8+
import org.jetbrains.dokka.links.DRI
9+
import org.jetbrains.dokka.model.Documentable
10+
import org.jetbrains.dokka.pages._
11+
import org.jetbrains.dokka.transformers.pages.PageTransformer
12+
import org.jsoup.Jsoup
13+
import scala.collection.JavaConverters._
14+
15+
16+
case class LazyEntry(val getKey: String, value: () => String) extends JMapEntry[String, Object]:
17+
lazy val getValue: Object = value()
18+
def setValue(x$0: Object): Object = ???
19+
20+
case class LoadedTemplate(templateFile: TemplateFile, children: List[LoadedTemplate], file: File):
21+
22+
private def brief(ctx: StaticSiteContext): String =
23+
val code = Jsoup.parse(resolveToHtml(ctx).code)
24+
code.select("p").first().outerHtml()
25+
26+
def lazyTemplateProperties(ctx: StaticSiteContext): JMap[String, Object] = new java.util.AbstractMap[String, Object]():
27+
def entrySet(): JSet[JMapEntry[String, Object]] =
28+
val site = templateFile.settings.getOrElse("page", Map.empty).asInstanceOf[Map[String, Object]]
29+
site.asJava.entrySet() ++ JSet(
30+
LazyEntry("url", () => ctx.relativePath(LoadedTemplate.this).toString),
31+
LazyEntry("title", () => templateFile.title),
32+
LazyEntry("excerpt", () => brief(ctx))
33+
)
34+
35+
def resolveToHtml(ctx: StaticSiteContext): ResolvedPage =
36+
val posts = children.map(_.lazyTemplateProperties(ctx))
37+
val site = templateFile.settings.getOrElse("site", Map.empty).asInstanceOf[Map[String, Object]]
38+
val updatedSettings = templateFile.settings + ("site" -> (site + ("posts" -> posts)))
39+
40+
templateFile.resolveInner(RenderingContext(updatedSettings, ctx.layouts))

scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import org.jsoup.Jsoup
1010
import scala.collection.JavaConverters._
1111

1212
case class PartiallyRenderedContent(
13-
template: TemplateFile,
13+
template: LoadedTemplate,
1414
context: StaticSiteContext,
1515
override val getChildren: JList[ContentNode],
1616
override val getDci: DCI,

scala3doc/src/dotty/dokka/site/StaticPageNode.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import org.jetbrains.dokka.model.Documentable
1010
import org.jetbrains.dokka.pages._
1111
import org.jetbrains.dokka.transformers.pages.PageTransformer
1212

13-
case class LoadedTemplate(templateFile: TemplateFile, children: List[LoadedTemplate], file: File)
14-
1513
case class StaticPageNode(
1614
template: TemplateFile,
1715
override val getName: String,

scala3doc/src/dotty/dokka/site/StaticSiteContext.scala

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,20 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
8282
val indexFiles = from.listFiles { file =>file.getName == "index.md" || file.getName == "index.html" }
8383
indexFiles.size match
8484
case 0 => emptyTemplate(from, from.getName)
85-
case 1 =>
86-
val index = loadTemplateFile(indexFiles.head)
87-
index.copy(
88-
file = from,
89-
settings = index.settings ++ Map("site" -> Map("posts" -> children.map(_.templateFile.settings("page"))))
90-
)
85+
case 1 => loadTemplateFile(indexFiles.head).copy(file = from)
9186
case _ =>
9287
val msg = s"ERROR: Multiple index pages found under ${from.toPath}"
9388
throw new java.lang.RuntimeException(msg)
9489

9590
val templateFile = if (from.isDirectory) loadIndexPage() else loadTemplateFile(from)
9691

97-
Some(LoadedTemplate(templateFile, children.toList, from))
92+
val processedChildren = if !isBlog then children else
93+
def dateFrom(p: LoadedTemplate): String =
94+
val pageSettings = p.templateFile.settings.get("page").collect{ case m: Map[String @unchecked, _] => m }
95+
pageSettings.flatMap(_.get("date").collect{ case s: String => s}).getOrElse("1900-01-01") // blogs without date are last
96+
children.sortBy(dateFrom).reverse
97+
98+
Some(LoadedTemplate(templateFile, processedChildren.toList, from))
9899
catch
99100
case e: RuntimeException =>
100101
// TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
@@ -115,7 +116,7 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
115116
val path = if isBlog then "blog" else url.stripSuffix(".html") + ".md"
116117
val file = root.toPath.resolve(path) // Add support for .html files!
117118
val LoadedTemplate(template, children, tFile) = loadTemplate(file.toFile, isBlog).get // Add proper logging if file does not exisits
118-
LoadedTemplate(template.copy(settings = template.settings + ("title" -> title)), children, tFile)
119+
LoadedTemplate(template.copy(settings = template.settings + ("title" -> title)), children, tFile)
119120
case Sidebar.Category(title, nested) =>
120121
// Add support for index.html/index.md files!
121122
val fakeFile = new File(root, title)
@@ -131,12 +132,14 @@ class StaticSiteContext(val root: File, sourceSets: Set[SourceSetWrapper]):
131132
else template.file.toPath.getParent().resolve(link)
132133
))
133134

134-
private def driFor(dest: Path): DRI = mkDRI(s"_.${root.toPath.relativize(dest)}")
135+
def driFor(dest: Path): DRI = mkDRI(s"_.${root.toPath.relativize(dest)}")
136+
137+
def relativePath(myTemplate: LoadedTemplate) = root.toPath.relativize(myTemplate.file.toPath)
135138

136139
def templateToPage(myTemplate: LoadedTemplate): StaticPageNode =
137140
val dri = driFor(myTemplate.file.toPath)
138141
val content = new PartiallyRenderedContent(
139-
myTemplate.templateFile,
142+
myTemplate,
140143
this,
141144
JList(),
142145
new DCI(Set(dri).asJava, ContentKind.Empty),

scala3doc/src/dotty/dokka/site/templates.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,22 @@ case class TemplateFile(
5555
):
5656
def isIndexPage() = file.isFile && (file.getName == "index.md" || file.getName == "index.html")
5757

58-
def resolveToHtml(ctx: StaticSiteContext): ResolvedPage = resolveInner(RenderingContext(settings, ctx.layouts))
59-
6058
private[site] def resolveInner(ctx: RenderingContext): ResolvedPage =
6159
if (ctx.resolving.contains(file.getAbsolutePath))
6260
throw new RuntimeException(s"Cycle in templates involving $file: ${ctx.resolving}")
6361

6462
val layoutTemplate = layout.map(name =>
6563
ctx.layouts.getOrElse(name, throw new RuntimeException(s"No layouts named $name in ${ctx.layouts}")))
6664

67-
def asJavaElement(o: Object): Object = o match
65+
def asJavaElement(o: Object): Object = o match
6866
case m: Map[_, _] => m.transform {
6967
case (k: String, v: Object) => asJavaElement(v)
7068
}.asJava
7169
case l: List[_] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava
7270
case other => other
7371

7472
// Library requires mutable maps..
75-
val mutableProperties = HMap(ctx.properties.transform((_, v) => asJavaElement(v)).asJava)
73+
val mutableProperties = JHashMap(ctx.properties.transform((_, v) => asJavaElement(v)).asJava)
7674
val rendered = Template.parse(this.rawCode).render(mutableProperties)
7775
// We want to render markdown only if next template is html
7876
val code = if (isHtml || layoutTemplate.exists(!_.isHtml)) rendered else

scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
254254
case prc: PartiallyRenderedContent =>
255255
def processLocalLink(str: String): String =
256256
// TODO (https://github.com/lampepfl/scala3doc/issues/238) error handling
257-
prc.context.driForLink(prc.template, str).toOption
257+
prc.context.driForLink(prc.template.templateFile, str).toOption
258258
.flatMap(dri => Option(getLocationProvider.resolve(dri, sourceSets, page)))
259259
.getOrElse(str)
260260

@@ -265,17 +265,17 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
265265
val html = prc.procsesHtml(url => Try(URL(url)).fold(_ => processLocalLink(url), _ => url))
266266
val htmlAst = Jsoup.parse(html)
267267

268-
childrenContent.foreach { c =>
269-
val code = Jsoup.parse(c.resolved.code)
270-
val brief = code.select("p").first()
271-
try {
272-
val li = htmlAst.select(s"li:contains(${c.template.title})")
273-
val div = li.select(s"div.excerpt")
274-
div.html(brief.toString)
275-
} catch {
276-
_ =>
277-
}
278-
}
268+
// childrenContent.foreach { c =>
269+
// val code = Jsoup.parse(c.resolved.code)
270+
// val brief = code.select("p").first()
271+
// try {
272+
// val li = htmlAst.select(s"li:contains(${c.template.title})")
273+
// val div = li.select(s"div.excerpt")
274+
// div.html(brief.toString)
275+
// } catch {
276+
// _ =>
277+
// }
278+
// }
279279

280280
withHtml(context, htmlAst.toString)
281281
case content =>

0 commit comments

Comments
 (0)