Skip to content

Commit

Permalink
CRs from review. Add hidden property to hide page configured throug…
Browse files Browse the repository at this point in the history
…h sidebar.yaml
  • Loading branch information
pikinier20 committed Feb 8, 2022
1 parent e196b51 commit 513088c
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 77 deletions.
10 changes: 8 additions & 2 deletions scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
Using(Files.walk(file)) { stream =>
stream.iterator().asScala.toSeq
.map(from => Resource.File(resourceFile.toPath.relativize(from).toString, from))
}.get
}.fold (
{ t =>
report.warn(s"Error occured while processing _assets file.", t)
Seq.empty
},
identity
)
}
}
val resources = staticSiteResources ++ allResources(allPages) ++ onlyRenderedResources
Expand Down Expand Up @@ -115,7 +121,7 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
)
)

nav.children match
nav.children.filterNot(_.hidden) match
case Nil => isSelected -> div(cls := s"ni ${if isSelected then "expanded" else ""}")(linkHtml())
case children =>
val nested = children.map(renderNested(_))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ trait Locations(using ctx: DocContext):
cache.get(dri) match
case null =>
val path = dri match
// case `docsRootDRI` => List("docs", "index")
case `apiPageDRI` =>
if ctx.args.apiSubdirectory && ctx.staticSiteContext.nonEmpty
then List("api", "index")
Expand Down
6 changes: 3 additions & 3 deletions scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import java.nio.file.Files
import java.nio.file.FileVisitOption
import java.io.File

case class Page(link: Link, content: Member | ResolvedTemplate | String, children: Seq[Page]):
case class Page(link: Link, content: Member | ResolvedTemplate | String, children: Seq[Page], hidden: Boolean = false):
def withNewChildren(newChildren: Seq[Page]) = copy(children = children ++ newChildren)

def withTitle(newTitle: String) = copy(link = link.copy(name = newTitle))
Expand Down Expand Up @@ -74,12 +74,12 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot
)
updatedTemplates.result()

val newTemplates = updateSettings(Seq(siteContext.staticSiteRoot.rootTemplate), newSettings.to(ListBuffer))
val newTemplates = updateSettings(Seq(rootTemplate), newSettings.to(ListBuffer))
val templatePages = newTemplates.map(templateToPage(_, siteContext))

val newRoot = newTemplates.head

if newRoot.children.size == 0 && newRoot.templateFile.rawCode == ""
if newRoot.children.isEmpty && newRoot.templateFile.rawCode.isEmpty
then rootPckPage.withTitle(args.name)
else {
val newRootPage = templateToPage(newRoot, siteContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ trait SiteRenderer(using DocContext) extends Locations:
def templateToPage(t: LoadedTemplate, staticSiteCtx: StaticSiteContext): Page =
val dri = staticSiteCtx.driFor(t.file.toPath)
val content = ResolvedTemplate(t, staticSiteCtx)
Page(Link(t.templateFile.title.name, dri), content, t.children.map(templateToPage(_, staticSiteCtx)))
Page(Link(t.templateFile.title.name, dri), content, t.children.map(templateToPage(_, staticSiteCtx)), t.hidden)

private val HashRegex = "([^#]+)(#.+)".r

Expand Down
3 changes: 2 additions & 1 deletion scaladoc/src/dotty/tools/scaladoc/site/LoadedTemplate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ case class LazyEntry(getKey: String, value: () => String) extends JMapEntry[Stri
case class LoadedTemplate(
templateFile: TemplateFile,
children: List[LoadedTemplate],
file: File):
file: File,
hidden: Boolean = false):

private def brief(ctx: StaticSiteContext): String =
try
Expand Down
88 changes: 63 additions & 25 deletions scaladoc/src/dotty/tools/scaladoc/site/SidebarParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,86 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.`type`.TypeReference;
import collection.JavaConverters._
import java.util.Optional
import scala.beans._

enum Sidebar:
case Root(index: Option[String], pages: List[Sidebar])
case Category(title: Option[String], indexPath: Option[String], nested: List[Sidebar], directory: Option[String])
case Page(title: Option[String], pagePath: String)
case Root(index: Option[String], pages: List[Sidebar.Child])
case Category(
title: Option[String],
indexPath: Option[String],
nested: List[Sidebar.Child],
directory: Option[String]
)
case Page(title: Option[String], pagePath: String, hidden: Boolean)

object Sidebar:

type Child = Category | Page
case class RawRoot(var rootIndex: String, var pages: JList[RawInput]):
def this() = this("", JList())

def setRootIndex(s: String) = rootIndex = s
def setPages(l: JList[RawInput]) = pages = l

case class RawInput(var title: String, var page: String, var index: String, var subsection: JList[RawInput], var directory: String):
def this() = this("", "", "", JList(), "")

def setTitle(t: String) = this.title = t
def setPage(p: String) = this.page = p
def setIndex(i: String) = this.index = i
def setSubsection(s: JList[RawInput]) = this.subsection = s
def setDirectory(d: String) = this.directory = d
case class RawInput(
@BeanProperty var title: String,
@BeanProperty var page: String,
@BeanProperty var index: String,
@BeanProperty var subsection: JList[RawInput],
@BeanProperty var directory: String,
@BooleanBeanProperty var hidden: Boolean
):
def this() = this("", "", "", JList(), "", false)

private object RootTypeRef extends TypeReference[RawRoot]

private def toSidebar(r: RawInput): Sidebar = r match
case RawInput(title, page, index, subsection, dir) if page.nonEmpty && index.isEmpty && subsection.isEmpty() || title == "Blog" =>
Sidebar.Page(Option.when(title.nonEmpty)(title), page)
case RawInput(title, page, index, subsection, dir) if page.isEmpty && (!subsection.isEmpty() || !index.isEmpty()) =>
private def toSidebar(r: RawInput)(using CompilerContext): Sidebar.Child = r match
case RawInput(title, page, index, subsection, dir, hidden) if page.nonEmpty && index.isEmpty && subsection.isEmpty() =>
Sidebar.Page(Option.when(title.nonEmpty)(title), page, hidden)
case RawInput(title, page, index, subsection, dir, hidden) if page.isEmpty && (!subsection.isEmpty() || !index.isEmpty()) =>
Sidebar.Category(Option.when(title.nonEmpty)(title), Option.when(index.nonEmpty)(index), subsection.asScala.map(toSidebar).toList, Option.when(dir.nonEmpty)(dir))
case RawInput(title, page, index, subsection, dir, hidden) =>
report.error(s"Error parsing YAML configuration file.\n$schemaMessage")
Sidebar.Page(None, page, hidden)

def load(content: String): Sidebar.Root =
val mapper = ObjectMapper(YAMLFactory())
val root: RawRoot = mapper.readValue(content, RootTypeRef)
private def schemaMessage: String =
s"""Static site YAML configuration file should comply to the following description:
|rootIndex: <string> # optional
|pages:
| - <subsection> | <page>
|
|<subsection>:
| title: <string> # optional
| index: <string> # optional
| directory: <string> # optional
| subsection: # optional
| - <subsection> | <page>
| # either index or subsection needs to be present
|<page>:
| title: <string> # optional
| page: <string>
| hidden: <boolean> # optional
|
|For more information visit:
|https://docs.scala-lang.org/scala3/guides/scaladoc/static-site.html
|""".stripMargin

val rootIndex: String = root.rootIndex
val pages: List[Sidebar] = root.pages.asScala.toList.map(toSidebar)
Sidebar.Root(Option.when(rootIndex.nonEmpty)(rootIndex), pages)

def load(file: java.io.File): Sidebar.Root =
def load(content: String | java.io.File)(using CompilerContext): Sidebar.Root =
import scala.util.Try
val mapper = ObjectMapper(YAMLFactory())
val root: RawRoot = mapper.readValue(file, RootTypeRef)
def readValue = content match
case s: String => mapper.readValue(s, RootTypeRef)
case f: java.io.File => mapper.readValue(f, RootTypeRef)

val root: RawRoot = Try(readValue)
.fold(
{ e =>
report.warn(schemaMessage, e)
RawRoot("", java.util.Collections.emptyList())
},
identity
)

val rootIndex: String = root.rootIndex
val pages: List[Sidebar] = root.pages.asScala.toList.map(toSidebar)
val pages: List[Sidebar.Child] = root.pages.asScala.toList.map(toSidebar)
Sidebar.Root(Option.when(rootIndex.nonEmpty)(rootIndex), pages)
34 changes: 20 additions & 14 deletions scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,22 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
}
}

/** Method loading static site structure based on YAML configuration file.
*
* The rendered static site will only contain pages that are present in YAML.
* The following rules are applied:
* - Each subsection will be a separate directory.
* - Nested subsections will result in nested directories.
* - If the subsection object contains location of index and doesn't contain any item,
* items are loaded using file system from the directory of the index file.
* - By default, directory name is a subsection title converted to kebab case.
* However, you can override default name by setting "directory" property of the subsection object.
*
*/
def loadBasedOnYaml(yamlRoot: Sidebar.Root): StaticSiteRoot = {
val rootDest = ctx.docsPath.resolve("index.html").toFile
val rootIndex = yamlRoot.index
.map(Paths.get(root.getPath, _).toFile)
.map(ctx.docsPath.resolve(_).toFile)
.filter(_.exists)
.fold(emptyTemplate(rootDest, "index")) { f =>
val loaded = loadTemplateFile(f)
Expand All @@ -36,13 +48,13 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
loaded
}.copy(title = TemplateName.FilenameDefined(args.name))

def loadChild(pathFromRoot: Path): Sidebar => LoadedTemplate = {
def loadChild(pathFromRoot: Path): Sidebar.Child => LoadedTemplate = {
case Sidebar.Category(optionTitle, optionIndexPath, nested, dir) =>
val indexPageOpt = optionIndexPath
.map(relativizeIfNeeded)
.map(_.toFile)
.filter(_.exists)
.map(loadTemplateFile)
.map(loadTemplateFile(_))
val title = (
optionTitle.map(TemplateName.SidebarDefined(_)) ++
indexPageOpt.map(_.title)
Expand Down Expand Up @@ -70,18 +82,12 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
}

LoadedTemplate(indexPage, children, categoryPath.resolve("index.html").toFile)
case Sidebar.Page(optionTitle, pagePath) =>
case Sidebar.Page(optionTitle, pagePath, hidden) =>
val path = relativizeIfNeeded(pagePath)
val file = path.toFile
val templateFile = loadTemplateFile(file)
val withUpdatedTitle = optionTitle.fold(templateFile) { t => templateFile.title match
case _: TemplateName.FilenameDefined => templateFile.copy(title = TemplateName.SidebarDefined(t))
case _ => templateFile
}
LoadedTemplate(withUpdatedTitle, List.empty, pathFromRoot.resolve(file.getName).toFile)
case Sidebar.Root(_, _) =>
// Cannot happen
???
val title = optionTitle.map(TemplateName.SidebarDefined(_))
val templateFile = loadTemplateFile(file, title)
LoadedTemplate(templateFile, List.empty, pathFromRoot.resolve(file.getName).toFile, hidden)
}
val rootTemplate = LoadedTemplate(rootIndex, yamlRoot.pages.map(c => loadChild(ctx.docsPath)(c)) ++ loadBlog(), rootDest)
val mappings = createMapping(rootTemplate)
Expand Down Expand Up @@ -175,7 +181,7 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite

val children = currRoot.listFiles.toList
.filter(_.toPath != indexPageOpt.getOrElse(null))
Some(LoadedTemplate(indexPage, children.flatMap(loadRecursively(_, destMappingFunc)), destMappingFunc(indexPage.file)))
Some(LoadedTemplate(indexPage, children.flatMap(loadRecursively(_, destMappingFunc)).sortBy(_.templateFile.title.name), destMappingFunc(indexPage.file)))
}
else if (currRoot.exists && ctx.siteExtensions.exists(ext => currRoot.getName.endsWith(ext))) {
val templateFile = loadTemplateFile(currRoot)
Expand Down
4 changes: 2 additions & 2 deletions scaladoc/src/dotty/tools/scaladoc/site/common.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ final val LineSeparator = "\n"

def yamlParser(using ctx: StaticSiteContext): Parser = Parser.builder(defaultMarkdownOptions).build()

def loadTemplateFile(file: File)(using ctx: StaticSiteContext): TemplateFile = {
def loadTemplateFile(file: File, defaultTitle: Option[TemplateName] = None)(using ctx: StaticSiteContext): TemplateFile = {
val lines = Files.readAllLines(file.toPath).asScala.toList

val (config, content) = if (lines.head == ConfigSeparator) {
Expand Down Expand Up @@ -105,7 +105,7 @@ def loadTemplateFile(file: File)(using ctx: StaticSiteContext): TemplateFile = {
rawCode = content.mkString(LineSeparator),
settings = settings,
name = name,
title = stringSetting(allSettings, "title").map(TemplateName.YamlDefined(_)).getOrElse(TemplateName.FilenameDefined(name)),
title = stringSetting(allSettings, "title").map(TemplateName.YamlDefined(_)).orElse(defaultTitle).getOrElse(TemplateName.FilenameDefined(name)),
hasFrame = !stringSetting(allSettings, "hasFrame").contains("false"),
resources = (listSetting(allSettings, "extraCSS") ++ listSetting(allSettings, "extraJS")).flatten.toList,
layout = stringSetting(allSettings, "layout"),
Expand Down
18 changes: 1 addition & 17 deletions scaladoc/src/dotty/tools/scaladoc/site/templates.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,25 +115,9 @@ case class TemplateFile(
// Library requires mutable maps..
val mutableProperties = new JHashMap(ctx.properties.transform((_, v) => asJavaElement(v)).asJava)

val tag = new Tag("highlight"):
override def render(context: TemplateContext, nodes: Array[? <: LNode]): Object =
super.asString(nodes(0).render(context), context) match
case "diff" =>
s"<pre><code class=\"language-diff hljs\" data-lang=\"diff\">${super.asString(nodes(1).render(context), context)}</code></pre>\n\n"
case _ =>
report.warn("Unsupported highlight value. Currenlty supported values are: `diff`", file)(using ssctx.outerCtx)
s"```${super.asString(nodes(1).render(context), context)}```\n\n"

val tag2 = new Tag("link"):
override def render(context: TemplateContext, nodes: Array[? <: LNode]): Object =
super.asString(nodes(0).render(context), context) match
case sth =>
report.warn(s"Unsupported link tag. Link to $sth can't be resolved", file)(using ssctx.outerCtx)
"/"

val parseSettings = ParseSettings.Builder().withFlavor(Flavor.JEKYLL).build()

val rendered = Template.parse(this.rawCode, parseSettings).`with`(tag).`with`(tag2).render(mutableProperties)
val rendered = Template.parse(this.rawCode, parseSettings).render(mutableProperties)

// We want to render markdown only if next template is html
val code = if (isHtml || layoutTemplate.exists(!_.isHtml)) rendered else
Expand Down
21 changes: 10 additions & 11 deletions scaladoc/test/dotty/tools/scaladoc/site/SidebarParserTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import org.junit.Assert._
class SidebarParserTest:

private val sidebar = """pages:
- title: Blog
- title: My title
page: my-page1.md
- page: my-page2.md
- page: my-page3/subsection
- title: Reference
subsection:
- page: my-page3.md
hidden: true
- index: my-page4/index.md
subsection:
- page: my-page4/my-page4.md
Expand All @@ -37,16 +37,15 @@ class SidebarParserTest:
Sidebar.Root(
None,
List(
Sidebar.Page(Some("Blog"), ""),
Sidebar.Page(Some("My title"), "my-page1.md"),
Sidebar.Page(None, "my-page2.md"),
Sidebar.Page(None, "my-page3/subsection"),
Sidebar.Category(Some("Reference"), None, List(Sidebar.Page(None, "my-page3.md")), None),
Sidebar.Category(None, Some("my-page4/index.md"), List(Sidebar.Page(None, "my-page4/my-page4.md")), None),
Sidebar.Category(Some("My subsection"), Some("my-page5/index.md"), List(Sidebar.Page(None, "my-page5/my-page5.md")), None),
Sidebar.Category(None, None, List(Sidebar.Page(None, "my-page7/my-page7.md")), None),
Sidebar.Category(None, Some("my-page6/index.md"), List(Sidebar.Category(None, Some("my-page6/my-page6/index.md"), List(Sidebar.Page(None, "my-page6/my-page6/my-page6.md")), None)), None),
Sidebar.Page(Some("My title"), "my-page1.md", false),
Sidebar.Page(None, "my-page2.md", false),
Sidebar.Page(None, "my-page3/subsection", false),
Sidebar.Category(Some("Reference"), None, List(Sidebar.Page(None, "my-page3.md", true)), None),
Sidebar.Category(None, Some("my-page4/index.md"), List(Sidebar.Page(None, "my-page4/my-page4.md", false)), None),
Sidebar.Category(Some("My subsection"), Some("my-page5/index.md"), List(Sidebar.Page(None, "my-page5/my-page5.md", false)), None),
Sidebar.Category(None, None, List(Sidebar.Page(None, "my-page7/my-page7.md", false)), None),
Sidebar.Category(None, Some("my-page6/index.md"), List(Sidebar.Category(None, Some("my-page6/my-page6/index.md"), List(Sidebar.Page(None, "my-page6/my-page6/my-page6.md", false)), None)), None),
)
),
Sidebar.load(sidebar)
Sidebar.load(sidebar)(using testContext)
)

0 comments on commit 513088c

Please sign in to comment.