@@ -15,16 +15,17 @@ import com.vladsch.flexmark.parser.{Parser, ParserEmulationProfile}
15
15
import com .vladsch .flexmark .util .options .{DataHolder , MutableDataSet }
16
16
import com .vladsch .flexmark .html .HtmlRenderer
17
17
import liqp .Template
18
+ import java .util .{ Map => JMap , HashMap => HMap , ArrayList , Collection }
18
19
19
20
import scala .collection .JavaConverters ._
20
21
import scala .io .Source
21
22
22
23
case class RenderingContext (
23
- properties : Map [String , Object ],
24
- layouts : Map [String , TemplateFile ] = Map (),
25
- resolving : Set [String ] = Set (),
26
- resources : List [String ] = Nil
27
- ):
24
+ properties : Map [String , Element ],
25
+ layouts : Map [String , TemplateFile ] = Map (),
26
+ resolving : Set [String ] = Set (),
27
+ resources : List [String ] = Nil
28
+ ):
28
29
29
30
def nest (code : String , file : File , resources : List [String ]) =
30
31
copy(
@@ -33,8 +34,8 @@ case class RenderingContext(
33
34
resources = this .resources ++ resources
34
35
)
35
36
36
- case class ResolvedPage (val code : String , val resources : List [String ] = Nil )
37
-
37
+ case class ResolvedPage (code : String , resources : List [String ] = Nil )
38
+ type Element = String | List [ String ] | Object // Object represents Map[String, Element] since it is not possible to get circullar dependency
38
39
/**
39
40
* case class for the template files.
40
41
* Template file is a file `.md` or `.html` handling settings.
@@ -44,53 +45,76 @@ case class ResolvedPage(val code: String, val resources: List[String] = Nil)
44
45
* @param settings The config defined in the begging of the file, between the pair of `---` (e.g. layout: basic).
45
46
*/
46
47
case class TemplateFile (
47
- val file : File ,
48
- val isHtml : Boolean ,
49
- val rawCode : String ,
50
- val settings : Map [String , List [String ]]
51
- ):
52
-
53
- private def stringSetting (name : String ): Option [String ] =
54
- settings.get(name) map {
55
- case List (single) => single.stripPrefix(" \" " ).stripSuffix(" \" " )
56
- case nonSingle =>
57
- throw new RuntimeException (s " Setting $name is a not a singlel-ement list but $nonSingle" )
58
- }
59
-
60
-
61
- private def listSetting (name : String ): List [String ] = settings.getOrElse(name, Nil )
62
-
63
- def name (): String = stringSetting(" name" ).getOrElse(file.getName.stripSuffix(if (isHtml) " .html" else " .md" ))
64
-
65
- def title (): String = stringSetting(" title" ).getOrElse(name())
66
-
67
- def layout (): Option [String ] = stringSetting(" layout" )
68
-
69
- def hasFrame (): Boolean = ! stringSetting(" hasFrame" ).contains(" false" )
70
-
48
+ file : File ,
49
+ isHtml : Boolean ,
50
+ rawCode : String ,
51
+ settings : Map [String , Element ],
52
+ name : String ,
53
+ title : String ,
54
+ hasFrame : Boolean ,
55
+ resources : List [String ],
56
+ layout : Option [String ],
57
+ ):
71
58
def isIndexPage () = file.isFile && (file.getName == " index.md" || file.getName == " index.html" )
72
59
73
- def resolveToHtml (ctx : StaticSiteContext ): ResolvedPage =
74
- val props = Map (" page" -> JMap (" title" -> title()))
75
- resolveInner(RenderingContext (props, ctx.layouts))
60
+ def resolveToHtml (ctx : StaticSiteContext ): ResolvedPage = resolveInner(RenderingContext (settings, ctx.layouts))
76
61
77
62
private [site] def resolveInner (ctx : RenderingContext ): ResolvedPage =
78
63
if (ctx.resolving.contains(file.getAbsolutePath))
79
64
throw new RuntimeException (s " Cycle in templates involving $file: ${ctx.resolving}" )
80
65
81
- val layoutTemplate = layout() .map(name =>
66
+ val layoutTemplate = layout.map(name =>
82
67
ctx.layouts.getOrElse(name, throw new RuntimeException (s " No layouts named $name in ${ctx.layouts}" )))
83
68
69
+ def toJava (m : Any ): Any = m match
70
+ case sm : Map [_, _] => sm.map(kv => (kv._1, toJava(kv._2))).asJava
71
+ case sl : Iterable [_] => new ArrayList (sl.map( toJava ).asJava.asInstanceOf [Collection [_]])
72
+ case _ => m
73
+
84
74
// Library requires mutable maps..
85
- val mutableProperties = new java.util. HashMap [String , Object ](ctx.properties.asJava )
75
+ val mutableProperties = new HMap [String , Object ](toJava( ctx.properties). asInstanceOf [ JMap [ String , Object ]] )
86
76
val rendered = Template .parse(this .rawCode).render(mutableProperties)
87
77
// We want to render markdown only if next template is html
88
78
val code = if (isHtml || layoutTemplate.exists(! _.isHtml)) rendered else
89
79
val parser : Parser = Parser .builder().build()
90
80
HtmlRenderer .builder(defaultMarkdownOptions).build().render(parser.parse(rendered))
91
81
92
- val resources = listSetting(" extraCSS" ) ++ listSetting(" extraJS" )
93
82
layoutTemplate match
94
83
case None => ResolvedPage (code, resources ++ ctx.resources)
95
84
case Some (layoutTemplate) =>
96
85
layoutTemplate.resolveInner(ctx.nest(code, file, resources))
86
+
87
+ object TemplateFile :
88
+ extension (settings : Map [String , Element ]):
89
+ private def stringSetting (name : String ): Option [String ] = settings.getOrElse(name, null ).match {
90
+ case List (elem : String ) => Some (elem)
91
+ case elem : String => Some (elem)
92
+ case _ => None
93
+ }.map(_.stripPrefix(" \" " ).stripSuffix(" \" " ))
94
+
95
+ private def listSetting (name : String ): Option [List [String ]] = settings.getOrElse(name, null ).match {
96
+ case elem : List [_] => Some (elem.asInstanceOf [List [String ]])
97
+ case elem : String => Some (List (elem))
98
+ case _ => None
99
+ }
100
+
101
+ def apply (
102
+ file : File ,
103
+ isHtml : Boolean ,
104
+ rawCode : String ,
105
+ settings : Map [String , Element ],
106
+ ): TemplateFile = {
107
+ val name = settings.stringSetting(" name" ).getOrElse(file.getName.stripSuffix(if (isHtml) " .html" else " .md" ))
108
+
109
+ TemplateFile (
110
+ file = file,
111
+ isHtml,
112
+ rawCode = rawCode,
113
+ settings = settings,
114
+ name = name,
115
+ title = settings.getOrElse(" page" , settings).asInstanceOf [Map [String , Object ]].stringSetting(" title" ).getOrElse(name),
116
+ hasFrame = ! settings.stringSetting(" hasFrame" ).contains(" false" ),
117
+ resources = (settings.listSetting(" extraCSS" ) ++ settings.listSetting(" extraJS" )).flatten.toList,
118
+ layout = settings.stringSetting(" layout" )
119
+ )
120
+ }
0 commit comments