From 0dac210e1e158f999dbb220d018b4e16896b9051 Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Fri, 30 Aug 2024 15:46:56 +0200 Subject: [PATCH] [scaladoc] fix: Only trim one newline when preprocessing the content of a markdown code snippet --- scaladoc-testcases/docs/_docs/index.md | 7 + .../tools/scaladoc/renderers/Renderer.scala | 131 +++++++++--------- .../snippets/FlexmarkSnippetProcessor.scala | 2 +- 3 files changed, 74 insertions(+), 66 deletions(-) diff --git a/scaladoc-testcases/docs/_docs/index.md b/scaladoc-testcases/docs/_docs/index.md index 42cb5f62dae8..9acac71a63b3 100644 --- a/scaladoc-testcases/docs/_docs/index.md +++ b/scaladoc-testcases/docs/_docs/index.md @@ -13,5 +13,12 @@ class Renderer(using RenderingContext) val renderer: Renderer = Renderer() ``` +```scala + trait Ord: + type Self + trait SemiGroup: + type Self + extension (x: Self) def combine(y: Self): Self +``` diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala index 1a43ea8648a8..0f7082fd6f49 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala @@ -30,71 +30,72 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot val rootApiPage: Option[Page] = Some(memberPage(rootPackage)).filter(_.children.nonEmpty).map(_.withTitle(ctx.args.name)) - val rootDocsPage: Option[Page] = staticSite match - case None => None - case Some(siteContext) => - val rootTemplate = siteContext.staticSiteRoot.rootTemplate - - // Below code is for walking in order the tree and modifing its nodes basing on its neighbours - - // We add dummy guards - val notHidden: Seq[Option[LoadedTemplate]] = None +: siteContext.allTemplates.filterNot(_.hidden).map(Some(_)) :+ None - - // Let's gather the list of maps for each template with its in-order neighbours - val newSettings: List[Map[String, Object]] = notHidden.sliding(size = 3, step = 1).map { - case None :: None :: Nil => - Map.empty - case prev :: mid :: next :: Nil => - def link(sibling: Option[LoadedTemplate]): Option[String] = - def realPath(path: Path) = if Files.isDirectory(path) then Paths.get(path.toString, "index.html") else path - sibling.map { n => - val realMidPath = realPath(mid.get.file.toPath) - val realSiblingPath = realPath(n.file.toPath) - realMidPath.relativize(realSiblingPath).toString.stripPrefix("../") - } - List( - for { - link <- link(prev) - p <- prev - } yield ( - "previous" -> Map( - "title" -> p.templateFile.title.name, - "url" -> link - ) - ), - for { - link <- link(next) - n <- next - } yield ( - "next" -> Map( - "title" -> n.templateFile.title.name, - "url" -> link - ) - ), - ).flatten.toMap - }.toList - - def updateSettings(templates: Seq[LoadedTemplate], additionalSettings: ListBuffer[Map[String, Object]]): List[LoadedTemplate] = - val updatedTemplates = List.newBuilder[LoadedTemplate] - for template <- templates do - val head: Map[String, Object] = - if template.hidden then Map.empty - else additionalSettings.remove(0) - val current: Map[String, Object] = template.templateFile.settings.getOrElse("page", Map.empty).asInstanceOf[Map[String, Object]] - val updatedTemplateFile = template.templateFile.copy(settings = template.templateFile.settings.updated("page", head ++ current)) - updatedTemplates += template.copy( - templateFile = updatedTemplateFile, - children = updateSettings(template.children, additionalSettings) - ) - updatedTemplates.result() - - val newTemplates = updateSettings(Seq(rootTemplate), newSettings.to(ListBuffer)) - val templatePages = newTemplates.map(templateToPage(_, siteContext)) - - val newRoot = newTemplates.head - - Some(newRoot).filter(r => r.children.nonEmpty || r.templateFile.rawCode.nonEmpty) - .map(templateToPage(_, siteContext)) + val rootDocsPage: Option[Page] = staticSite match { + case None => None + case Some(siteContext) => + val rootTemplate = siteContext.staticSiteRoot.rootTemplate + + // Below code is for walking in order the tree and modifing its nodes basing on its neighbours + + // We add dummy guards + val notHidden: Seq[Option[LoadedTemplate]] = None +: siteContext.allTemplates.filterNot(_.hidden).map(Some(_)) :+ None + + // Let's gather the list of maps for each template with its in-order neighbours + val newSettings: List[Map[String, Object]] = notHidden.sliding(size = 3, step = 1).map { + case None :: None :: Nil => + Map.empty + case prev :: mid :: next :: Nil => + def link(sibling: Option[LoadedTemplate]): Option[String] = + def realPath(path: Path) = if Files.isDirectory(path) then Paths.get(path.toString, "index.html") else path + sibling.map { n => + val realMidPath = realPath(mid.get.file.toPath) + val realSiblingPath = realPath(n.file.toPath) + realMidPath.relativize(realSiblingPath).toString.stripPrefix("../") + } + List( + for { + link <- link(prev) + p <- prev + } yield ( + "previous" -> Map( + "title" -> p.templateFile.title.name, + "url" -> link + ) + ), + for { + link <- link(next) + n <- next + } yield ( + "next" -> Map( + "title" -> n.templateFile.title.name, + "url" -> link + ) + ), + ).flatten.toMap + }.toList + + def updateSettings(templates: Seq[LoadedTemplate], additionalSettings: ListBuffer[Map[String, Object]]): List[LoadedTemplate] = + val updatedTemplates = List.newBuilder[LoadedTemplate] + for template <- templates do + val head: Map[String, Object] = + if template.hidden then Map.empty + else additionalSettings.remove(0) + val current: Map[String, Object] = template.templateFile.settings.getOrElse("page", Map.empty).asInstanceOf[Map[String, Object]] + val updatedTemplateFile = template.templateFile.copy(settings = template.templateFile.settings.updated("page", head ++ current)) + updatedTemplates += template.copy( + templateFile = updatedTemplateFile, + children = updateSettings(template.children, additionalSettings) + ) + updatedTemplates.result() + + val newTemplates = updateSettings(Seq(rootTemplate), newSettings.to(ListBuffer)) + val templatePages = newTemplates.map(templateToPage(_, siteContext)) + + val newRoot = newTemplates.head + + Some(newRoot).filter(r => r.children.nonEmpty || r.templateFile.rawCode.nonEmpty) + .map(templateToPage(_, siteContext)) + } val redirectPages: Seq[Page] = staticSite.fold(Seq.empty)(siteContext => siteContext.redirectTemplates.map { case (template, driFrom, driTo) => diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala index 33f0e089053a..c92853816d16 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala @@ -65,7 +65,7 @@ object FlexmarkSnippetProcessor: content.add(s, 0) node.setContent(content) - val fullSnippet = Seq(snippetImports, snippet).mkString("\n").trim + val fullSnippet = Seq(snippetImports, snippet).mkString("\n").stripPrefix("\n") val snippetCompilationResult = cf(fullSnippet, lineOffset, argOverride) match { case Some(result @ SnippetCompilationResult(wrapped, _, _, messages)) => node.setContentString(fullSnippet)