Skip to content

Commit dd87223

Browse files
authored
convert public case classes in laika.rewrite.nav (#491)
1 parent df7d35d commit dd87223

File tree

11 files changed

+202
-119
lines changed

11 files changed

+202
-119
lines changed

core/shared/src/main/scala/laika/ast/documents.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ sealed trait TreeContent extends Navigatable {
5858
config.get[Traced[String]](LaikaKeys.title).toOption.flatMap { tracedTitle =>
5959
if (tracedTitle.origin.scope == configScope) {
6060
val title = Seq(Text(tracedTitle.value))
61-
val autonumberConfig = config.get[AutonumberConfig].getOrElse(AutonumberConfig.defaults)
61+
val autonumberConfig = config.get[AutonumberConfig].getOrElse(AutonumberConfig.disabled)
6262
val autonumberEnabled =
6363
autonumberConfig.documents && position.depth < autonumberConfig.maxDepth
6464
if (autonumberEnabled) Some(SpanSequence(position.toSpan +: title))

core/shared/src/main/scala/laika/rewrite/nav/AutonumberConfig.scala

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,39 @@
1616

1717
package laika.rewrite.nav
1818

19-
import laika.config.{
20-
Config,
21-
ConfigBuilder,
22-
ConfigDecoder,
23-
ConfigEncoder,
24-
DefaultKey,
25-
Key,
26-
LaikaKeys,
27-
ValidationError
28-
}
19+
import laika.config.*
2920

3021
/** Configuration for autonumbering of documents and sections.
3122
*/
32-
case class AutonumberConfig(
33-
documents: Boolean = true,
34-
sections: Boolean = true,
35-
maxDepth: Int = Int.MaxValue
36-
)
23+
sealed abstract class AutonumberConfig {
3724

38-
private[nav] sealed trait Scope
25+
/** Applies autonumbering to directories and documents and their titles. */
26+
def documents: Boolean
3927

40-
private[nav] object Scope {
41-
case object Documents extends Scope
42-
case object Sections extends Scope
43-
case object All extends Scope
44-
case object None extends Scope
28+
/** Applies autonumber to section header within documents. */
29+
def sections: Boolean
4530

46-
implicit val decoder: ConfigDecoder[Scope] = ConfigDecoder.string.flatMap {
47-
case "documents" => Right(Documents)
48-
case "sections" => Right(Sections)
49-
case "all" => Right(All)
50-
case "none" => Right(None)
51-
case other => Left(ValidationError(s"Invalid value for autonumbering.scope: $other"))
52-
}
31+
/** Specifies how many levels deep the autonumbering should be applied.
32+
* Any documents or section headers beyond this limit will be ignored.
33+
*
34+
* The default is unlimited depth.
35+
*/
36+
def maxDepth: Int
5337

38+
/** Specifies how many levels deep the autonumbering should be applied.
39+
* Any documents or section headers beyond this limit will be ignored.
40+
*/
41+
def withMaxDepth(value: Int): AutonumberConfig
5442
}
5543

5644
object AutonumberConfig {
5745

46+
private final case class Impl(documents: Boolean, sections: Boolean, maxDepth: Int)
47+
extends AutonumberConfig {
48+
override def productPrefix: String = "AutonumberConfig"
49+
def withMaxDepth(value: Int): AutonumberConfig = copy(maxDepth = value)
50+
}
51+
5852
private val scopeKey = Key("scope")
5953
private val depthKey = Key("depth")
6054

@@ -71,7 +65,7 @@ object AutonumberConfig {
7165
case Scope.All => (true, true)
7266
case Scope.None => (false, false)
7367
}
74-
AutonumberConfig(documents, sections, depth)
68+
Impl(documents, sections, depth)
7569
}
7670
}
7771

@@ -92,7 +86,9 @@ object AutonumberConfig {
9286
/** Disables section numbering for the specified config instance.
9387
* Retains the existing value for auto-numbering of documents.
9488
*/
95-
def withoutSectionNumbering(config: Config)(builder: ConfigBuilder): ConfigBuilder = {
89+
private[laika] def withoutSectionNumbering(
90+
config: Config
91+
)(builder: ConfigBuilder): ConfigBuilder = {
9692
val key = LaikaKeys.autonumbering.child(scopeKey)
9793
config.get[Scope](key).toOption.fold(builder) {
9894
case Scope.Documents => builder
@@ -102,10 +98,43 @@ object AutonumberConfig {
10298
}
10399
}
104100

105-
/** The defaults for autonumbering with section
106-
* and document numbering both switched off.
101+
/** Section numbering within documents switched on, but document and directory numbering switched off.
102+
*/
103+
def sectionsEnabled: AutonumberConfig =
104+
Impl(documents = false, sections = true, maxDepth = Int.MaxValue)
105+
106+
/** Document and directory numbering switched on, but section numbering within documents switched off.
107+
*/
108+
def documentsEnabled: AutonumberConfig =
109+
Impl(documents = true, sections = false, maxDepth = Int.MaxValue)
110+
111+
/** Section and document numbering both switched on.
107112
*/
108-
def defaults: AutonumberConfig =
109-
AutonumberConfig(documents = false, sections = false, maxDepth = 0)
113+
def allEnabled: AutonumberConfig =
114+
Impl(documents = true, sections = true, maxDepth = Int.MaxValue)
115+
116+
/** Section and document numbering both switched off.
117+
*/
118+
def disabled: AutonumberConfig =
119+
Impl(documents = false, sections = false, maxDepth = 0)
120+
121+
}
122+
123+
private[nav] sealed trait Scope
124+
125+
private[nav] object Scope {
126+
127+
case object Documents extends Scope
128+
case object Sections extends Scope
129+
case object All extends Scope
130+
case object None extends Scope
131+
132+
implicit val decoder: ConfigDecoder[Scope] = ConfigDecoder.string.flatMap {
133+
case "documents" => Right(Documents)
134+
case "sections" => Right(Sections)
135+
case "all" => Right(All)
136+
case "none" => Right(None)
137+
case other => Left(ValidationError(s"Invalid value for autonumbering.scope: $other"))
138+
}
110139

111140
}

core/shared/src/main/scala/laika/rewrite/nav/CoverImage.scala

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,27 @@ import laika.config.{ Config, ConfigDecoder, ConfigEncoder, Key, LaikaKeys }
2929
*
3030
* @author Jens Halm
3131
*/
32-
case class CoverImage(path: Path, classifier: Option[String] = None)
32+
sealed abstract class CoverImage {
33+
def path: Path
34+
def classifier: Option[String]
35+
}
3336

3437
object CoverImage {
3538

36-
def apply(path: Path, classifier: String): CoverImage = CoverImage(path, Some(classifier))
39+
private final case class Impl(path: Path, classifier: Option[String] = None) extends CoverImage {
40+
override def productPrefix: String = "CoverImage"
41+
}
42+
43+
def apply(path: Path): CoverImage = Impl(path, None)
44+
45+
def apply(path: Path, classifier: String): CoverImage = Impl(path, Some(classifier))
3746

3847
implicit val decoder: ConfigDecoder[CoverImage] = ConfigDecoder.config.flatMap { config =>
3948
for {
4049
path <- config.get[Path]("path")
4150
classifier <- config.getOpt[String]("classifier")
4251
} yield {
43-
CoverImage(path, classifier)
52+
Impl(path, classifier)
4453
}
4554
}
4655

@@ -80,7 +89,7 @@ private[laika] object CoverImages {
8089
.map(_.orElse(classified.find(_.classifier.isEmpty).map(_.path)))
8190
} yield {
8291
val classifiedMap = classified
83-
.collect { case CoverImage(path, Some(classifier)) => (classifier, path) }
92+
.collect { case c: CoverImage if c.classifier.nonEmpty => (c.classifier.get, c.path) }
8493
.toMap
8594
CoverImages(default, classifiedMap)
8695
}

core/shared/src/main/scala/laika/rewrite/nav/PathTranslator.scala

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ object PathTranslator {
9292
*/
9393
def ignoreVersions(translator: PathTranslator): PathTranslator = translator match {
9494
case cpt: ConfigurablePathTranslator =>
95-
cpt.copy(targetLookup = cpt.targetLookup.andThen(_.map(_.copy(isVersioned = false))))
95+
cpt.copy(targetLookup =
96+
cpt.targetLookup.andThen(_.map(attr => PathAttributes(attr.isStatic, isVersioned = false)))
97+
)
9698
case other => other
9799
}
98100

@@ -186,7 +188,19 @@ private[laika] case class ConfigurablePathTranslator(
186188
def forReferencePath(path: Path): PathTranslator = copy(refPath = path)
187189
}
188190

189-
case class PathAttributes(isStatic: Boolean, isVersioned: Boolean)
191+
sealed abstract class PathAttributes {
192+
def isStatic: Boolean
193+
def isVersioned: Boolean
194+
}
195+
196+
object PathAttributes {
197+
198+
private final case class Impl(isStatic: Boolean, isVersioned: Boolean) extends PathAttributes {
199+
override def productPrefix = "PathAttributes"
200+
}
201+
202+
def apply(isStatic: Boolean, isVersioned: Boolean): PathAttributes = Impl(isStatic, isVersioned)
203+
}
190204

191205
private[laika] case class TranslatorConfig(
192206
versions: Option[Versions],
@@ -243,8 +257,9 @@ private[laika] class TargetLookup(cursor: RootCursor) extends (Path => Option[Pa
243257
(markupDocs ++ staticDocs).toMap
244258
}
245259

246-
val versionedDocuments: Seq[Path] = lookup.collect { case (path, PathAttributes(false, true)) =>
247-
path
260+
val versionedDocuments: Seq[Path] = lookup.collect {
261+
case (path, attr) if attr.isVersioned && !attr.isStatic =>
262+
path
248263
}.toSeq
249264

250265
def apply(path: Path): Option[PathAttributes] =

core/shared/src/main/scala/laika/rewrite/nav/SectionBuilder.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package laika.rewrite.nav
1818

1919
import laika.ast.RewriteRules.RewriteRulesBuilder
20-
import laika.ast._
20+
import laika.ast.*
2121
import laika.collection.Stack
2222
import laika.config.Config.ConfigResult
2323
import laika.config.LaikaKeys
@@ -124,7 +124,7 @@ private[laika] object SectionBuilder extends RewriteRulesBuilder {
124124
*/
125125
def apply(cursor: DocumentCursor): ConfigResult[RewriteRules] = for {
126126
autonumbering <- cursor.config.getOpt[AutonumberConfig].map(
127-
_.getOrElse(AutonumberConfig.defaults)
127+
_.getOrElse(AutonumberConfig.disabled)
128128
)
129129
firstHeaderAsTitle <- cursor.config.get(
130130
LaikaKeys.firstHeaderAsTitle,

0 commit comments

Comments
 (0)