Skip to content

Commit 2ef7753

Browse files
committed
CRs from review. Add hidden property to hide page configured through sidebar.yaml
1 parent 5a873e0 commit 2ef7753

File tree

10 files changed

+110
-77
lines changed

10 files changed

+110
-77
lines changed

scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
4444
Using(Files.walk(file)) { stream =>
4545
stream.iterator().asScala.toSeq
4646
.map(from => Resource.File(resourceFile.toPath.relativize(from).toString, from))
47-
}.get
47+
}.fold (
48+
{ t =>
49+
report.warn(s"Error occured while processing _assets file.", t)
50+
Seq.empty
51+
},
52+
identity
53+
)
4854
}
4955
}
5056
val resources = staticSiteResources ++ allResources(allPages) ++ onlyRenderedResources
@@ -115,7 +121,7 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
115121
)
116122
)
117123

118-
nav.children match
124+
nav.children.filterNot(_.hidden) match
119125
case Nil => isSelected -> div(cls := s"ni ${if isSelected then "expanded" else ""}")(linkHtml())
120126
case children =>
121127
val nested = children.map(renderNested(_))

scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ trait Locations(using ctx: DocContext):
3434
cache.get(dri) match
3535
case null =>
3636
val path = dri match
37-
// case `docsRootDRI` => List("docs", "index")
3837
case `apiPageDRI` =>
3938
if ctx.args.apiSubdirectory && ctx.staticSiteContext.nonEmpty
4039
then List("api", "index")

scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import java.nio.file.Files
1515
import java.nio.file.FileVisitOption
1616
import java.io.File
1717

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

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

77-
val newTemplates = updateSettings(Seq(siteContext.staticSiteRoot.rootTemplate), newSettings.to(ListBuffer))
77+
val newTemplates = updateSettings(Seq(rootTemplate), newSettings.to(ListBuffer))
7878
val templatePages = newTemplates.map(templateToPage(_, siteContext))
7979

8080
val newRoot = newTemplates.head
8181

82-
if newRoot.children.size == 0 && newRoot.templateFile.rawCode == ""
82+
if newRoot.children.isEmpty && newRoot.templateFile.rawCode.isEmpty
8383
then rootPckPage.withTitle(args.name)
8484
else {
8585
val newRootPage = templateToPage(newRoot, siteContext)

scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ trait SiteRenderer(using DocContext) extends Locations:
2222
def templateToPage(t: LoadedTemplate, staticSiteCtx: StaticSiteContext): Page =
2323
val dri = staticSiteCtx.driFor(t.file.toPath)
2424
val content = ResolvedTemplate(t, staticSiteCtx)
25-
Page(Link(t.templateFile.title.name, dri), content, t.children.map(templateToPage(_, staticSiteCtx)))
25+
Page(Link(t.templateFile.title.name, dri), content, t.children.map(templateToPage(_, staticSiteCtx)), t.hidden)
2626

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

scaladoc/src/dotty/tools/scaladoc/site/LoadedTemplate.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ case class LazyEntry(getKey: String, value: () => String) extends JMapEntry[Stri
1616
case class LoadedTemplate(
1717
templateFile: TemplateFile,
1818
children: List[LoadedTemplate],
19-
file: File):
19+
file: File,
20+
hidden: Boolean = false):
2021

2122
private def brief(ctx: StaticSiteContext): String =
2223
try

scaladoc/src/dotty/tools/scaladoc/site/SidebarParser.scala

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,48 +6,86 @@ import com.fasterxml.jackson.databind.ObjectMapper;
66
import com.fasterxml.jackson.core.`type`.TypeReference;
77
import collection.JavaConverters._
88
import java.util.Optional
9+
import scala.beans._
910

1011
enum Sidebar:
11-
case Root(index: Option[String], pages: List[Sidebar])
12-
case Category(title: Option[String], indexPath: Option[String], nested: List[Sidebar], directory: Option[String])
13-
case Page(title: Option[String], pagePath: String)
12+
case Root(index: Option[String], pages: List[Sidebar.Child])
13+
case Category(
14+
title: Option[String],
15+
indexPath: Option[String],
16+
nested: List[Sidebar.Child],
17+
directory: Option[String]
18+
)
19+
case Page(title: Option[String], pagePath: String, hidden: Boolean)
1420

1521
object Sidebar:
22+
23+
type Child = Category | Page
1624
case class RawRoot(var rootIndex: String, var pages: JList[RawInput]):
1725
def this() = this("", JList())
1826

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

22-
case class RawInput(var title: String, var page: String, var index: String, var subsection: JList[RawInput], var directory: String):
23-
def this() = this("", "", "", JList(), "")
24-
25-
def setTitle(t: String) = this.title = t
26-
def setPage(p: String) = this.page = p
27-
def setIndex(i: String) = this.index = i
28-
def setSubsection(s: JList[RawInput]) = this.subsection = s
29-
def setDirectory(d: String) = this.directory = d
30+
case class RawInput(
31+
@BeanProperty var title: String,
32+
@BeanProperty var page: String,
33+
@BeanProperty var index: String,
34+
@BeanProperty var subsection: JList[RawInput],
35+
@BeanProperty var directory: String,
36+
@BooleanBeanProperty var hidden: Boolean
37+
):
38+
def this() = this("", "", "", JList(), "", false)
3039

3140
private object RootTypeRef extends TypeReference[RawRoot]
3241

33-
private def toSidebar(r: RawInput): Sidebar = r match
34-
case RawInput(title, page, index, subsection, dir) if page.nonEmpty && index.isEmpty && subsection.isEmpty() || title == "Blog" =>
35-
Sidebar.Page(Option.when(title.nonEmpty)(title), page)
36-
case RawInput(title, page, index, subsection, dir) if page.isEmpty && (!subsection.isEmpty() || !index.isEmpty()) =>
42+
private def toSidebar(r: RawInput)(using CompilerContext): Sidebar.Child = r match
43+
case RawInput(title, page, index, subsection, dir, hidden) if page.nonEmpty && index.isEmpty && subsection.isEmpty() =>
44+
Sidebar.Page(Option.when(title.nonEmpty)(title), page, hidden)
45+
case RawInput(title, page, index, subsection, dir, hidden) if page.isEmpty && (!subsection.isEmpty() || !index.isEmpty()) =>
3746
Sidebar.Category(Option.when(title.nonEmpty)(title), Option.when(index.nonEmpty)(index), subsection.asScala.map(toSidebar).toList, Option.when(dir.nonEmpty)(dir))
47+
case RawInput(title, page, index, subsection, dir, hidden) =>
48+
report.error(s"Error parsing YAML configuration file.\n$schemaMessage")
49+
Sidebar.Page(None, page, hidden)
3850

39-
def load(content: String): Sidebar.Root =
40-
val mapper = ObjectMapper(YAMLFactory())
41-
val root: RawRoot = mapper.readValue(content, RootTypeRef)
51+
private def schemaMessage: String =
52+
s"""Static site YAML configuration file should comply to the following description:
53+
|rootIndex: <string> # optional
54+
|pages:
55+
| - <subsection> | <page>
56+
|
57+
|<subsection>:
58+
| title: <string> # optional
59+
| index: <string> # optional
60+
| directory: <string> # optional
61+
| subsection: # optional
62+
| - <subsection> | <page>
63+
| # either index or subsection needs to be present
64+
|<page>:
65+
| title: <string> # optional
66+
| page: <string>
67+
| hidden: <boolean> # optional
68+
|
69+
|For more information visit:
70+
|https://docs.scala-lang.org/scala3/guides/scaladoc/static-site.html
71+
|""".stripMargin
4272

43-
val rootIndex: String = root.rootIndex
44-
val pages: List[Sidebar] = root.pages.asScala.toList.map(toSidebar)
45-
Sidebar.Root(Option.when(rootIndex.nonEmpty)(rootIndex), pages)
46-
47-
def load(file: java.io.File): Sidebar.Root =
73+
def load(content: String | java.io.File)(using CompilerContext): Sidebar.Root =
74+
import scala.util.Try
4875
val mapper = ObjectMapper(YAMLFactory())
49-
val root: RawRoot = mapper.readValue(file, RootTypeRef)
76+
def readValue = content match
77+
case s: String => mapper.readValue(s, RootTypeRef)
78+
case f: java.io.File => mapper.readValue(f, RootTypeRef)
79+
80+
val root: RawRoot = Try(readValue)
81+
.fold(
82+
{ e =>
83+
report.warn(schemaMessage, e)
84+
RawRoot("", java.util.Collections.emptyList())
85+
},
86+
identity
87+
)
5088

5189
val rootIndex: String = root.rootIndex
52-
val pages: List[Sidebar] = root.pages.asScala.toList.map(toSidebar)
90+
val pages: List[Sidebar.Child] = root.pages.asScala.toList.map(toSidebar)
5391
Sidebar.Root(Option.when(rootIndex.nonEmpty)(rootIndex), pages)

scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,22 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
2424
}
2525
}
2626

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

39-
def loadChild(pathFromRoot: Path): Sidebar => LoadedTemplate = {
51+
def loadChild(pathFromRoot: Path): Sidebar.Child => LoadedTemplate = {
4052
case Sidebar.Category(optionTitle, optionIndexPath, nested, dir) =>
4153
val indexPageOpt = optionIndexPath
4254
.map(relativizeIfNeeded)
4355
.map(_.toFile)
4456
.filter(_.exists)
45-
.map(loadTemplateFile)
57+
.map(loadTemplateFile(_))
4658
val title = (
4759
optionTitle.map(TemplateName.SidebarDefined(_)) ++
4860
indexPageOpt.map(_.title)
@@ -70,18 +82,12 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
7082
}
7183

7284
LoadedTemplate(indexPage, children, categoryPath.resolve("index.html").toFile)
73-
case Sidebar.Page(optionTitle, pagePath) =>
85+
case Sidebar.Page(optionTitle, pagePath, hidden) =>
7486
val path = relativizeIfNeeded(pagePath)
7587
val file = path.toFile
76-
val templateFile = loadTemplateFile(file)
77-
val withUpdatedTitle = optionTitle.fold(templateFile) { t => templateFile.title match
78-
case _: TemplateName.FilenameDefined => templateFile.copy(title = TemplateName.SidebarDefined(t))
79-
case _ => templateFile
80-
}
81-
LoadedTemplate(withUpdatedTitle, List.empty, pathFromRoot.resolve(file.getName).toFile)
82-
case Sidebar.Root(_, _) =>
83-
// Cannot happen
84-
???
88+
val title = optionTitle.map(TemplateName.SidebarDefined(_))
89+
val templateFile = loadTemplateFile(file, title)
90+
LoadedTemplate(templateFile, List.empty, pathFromRoot.resolve(file.getName).toFile, hidden)
8591
}
8692
val rootTemplate = LoadedTemplate(rootIndex, yamlRoot.pages.map(c => loadChild(ctx.docsPath)(c)) ++ loadBlog(), rootDest)
8793
val mappings = createMapping(rootTemplate)
@@ -175,7 +181,7 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite
175181

176182
val children = currRoot.listFiles.toList
177183
.filter(_.toPath != indexPageOpt.getOrElse(null))
178-
Some(LoadedTemplate(indexPage, children.flatMap(loadRecursively(_, destMappingFunc)), destMappingFunc(indexPage.file)))
184+
Some(LoadedTemplate(indexPage, children.flatMap(loadRecursively(_, destMappingFunc)).sortBy(_.templateFile.title.name), destMappingFunc(indexPage.file)))
179185
}
180186
else if (currRoot.exists && ctx.siteExtensions.exists(ext => currRoot.getName.endsWith(ext))) {
181187
val templateFile = loadTemplateFile(currRoot)

scaladoc/src/dotty/tools/scaladoc/site/common.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ final val LineSeparator = "\n"
5858

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

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

6464
val (config, content) = if (lines.head == ConfigSeparator) {
@@ -105,7 +105,7 @@ def loadTemplateFile(file: File)(using ctx: StaticSiteContext): TemplateFile = {
105105
rawCode = content.mkString(LineSeparator),
106106
settings = settings,
107107
name = name,
108-
title = stringSetting(allSettings, "title").map(TemplateName.YamlDefined(_)).getOrElse(TemplateName.FilenameDefined(name)),
108+
title = stringSetting(allSettings, "title").map(TemplateName.YamlDefined(_)).orElse(defaultTitle).getOrElse(TemplateName.FilenameDefined(name)),
109109
hasFrame = !stringSetting(allSettings, "hasFrame").contains("false"),
110110
resources = (listSetting(allSettings, "extraCSS") ++ listSetting(allSettings, "extraJS")).flatten.toList,
111111
layout = stringSetting(allSettings, "layout"),

scaladoc/src/dotty/tools/scaladoc/site/templates.scala

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,9 @@ case class TemplateFile(
115115
// Library requires mutable maps..
116116
val mutableProperties = new JHashMap(ctx.properties.transform((_, v) => asJavaElement(v)).asJava)
117117

118-
val tag = new Tag("highlight"):
119-
override def render(context: TemplateContext, nodes: Array[? <: LNode]): Object =
120-
super.asString(nodes(0).render(context), context) match
121-
case "diff" =>
122-
s"<pre><code class=\"language-diff hljs\" data-lang=\"diff\">${super.asString(nodes(1).render(context), context)}</code></pre>\n\n"
123-
case _ =>
124-
report.warn("Unsupported highlight value. Currenlty supported values are: `diff`", file)(using ssctx.outerCtx)
125-
s"```${super.asString(nodes(1).render(context), context)}```\n\n"
126-
127-
val tag2 = new Tag("link"):
128-
override def render(context: TemplateContext, nodes: Array[? <: LNode]): Object =
129-
super.asString(nodes(0).render(context), context) match
130-
case sth =>
131-
report.warn(s"Unsupported link tag. Link to $sth can't be resolved", file)(using ssctx.outerCtx)
132-
"/"
133-
134118
val parseSettings = ParseSettings.Builder().withFlavor(Flavor.JEKYLL).build()
135119

136-
val rendered = Template.parse(this.rawCode, parseSettings).`with`(tag).`with`(tag2).render(mutableProperties)
120+
val rendered = Template.parse(this.rawCode, parseSettings).render(mutableProperties)
137121

138122
// We want to render markdown only if next template is html
139123
val code = if (isHtml || layoutTemplate.exists(!_.isHtml)) rendered else

scaladoc/test/dotty/tools/scaladoc/site/SidebarParserTest.scala

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import org.junit.Assert._
88
class SidebarParserTest:
99

1010
private val sidebar = """pages:
11-
- title: Blog
1211
- title: My title
1312
page: my-page1.md
1413
- page: my-page2.md
1514
- page: my-page3/subsection
1615
- title: Reference
1716
subsection:
1817
- page: my-page3.md
18+
hidden: true
1919
- index: my-page4/index.md
2020
subsection:
2121
- page: my-page4/my-page4.md
@@ -37,16 +37,15 @@ class SidebarParserTest:
3737
Sidebar.Root(
3838
None,
3939
List(
40-
Sidebar.Page(Some("Blog"), ""),
41-
Sidebar.Page(Some("My title"), "my-page1.md"),
42-
Sidebar.Page(None, "my-page2.md"),
43-
Sidebar.Page(None, "my-page3/subsection"),
44-
Sidebar.Category(Some("Reference"), None, List(Sidebar.Page(None, "my-page3.md")), None),
45-
Sidebar.Category(None, Some("my-page4/index.md"), List(Sidebar.Page(None, "my-page4/my-page4.md")), None),
46-
Sidebar.Category(Some("My subsection"), Some("my-page5/index.md"), List(Sidebar.Page(None, "my-page5/my-page5.md")), None),
47-
Sidebar.Category(None, None, List(Sidebar.Page(None, "my-page7/my-page7.md")), None),
48-
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),
40+
Sidebar.Page(Some("My title"), "my-page1.md", false),
41+
Sidebar.Page(None, "my-page2.md", false),
42+
Sidebar.Page(None, "my-page3/subsection", false),
43+
Sidebar.Category(Some("Reference"), None, List(Sidebar.Page(None, "my-page3.md", true)), None),
44+
Sidebar.Category(None, Some("my-page4/index.md"), List(Sidebar.Page(None, "my-page4/my-page4.md", false)), None),
45+
Sidebar.Category(Some("My subsection"), Some("my-page5/index.md"), List(Sidebar.Page(None, "my-page5/my-page5.md", false)), None),
46+
Sidebar.Category(None, None, List(Sidebar.Page(None, "my-page7/my-page7.md", false)), None),
47+
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),
4948
)
5049
),
51-
Sidebar.load(sidebar)
50+
Sidebar.load(sidebar)(using testContext)
5251
)

0 commit comments

Comments
 (0)