diff --git a/build.gradle.kts b/build.gradle.kts index c494eb6..c546e37 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ group = "ru.mipt.npm" version = "0.0.1-SNAPSHOT" application { - mainClass.set("ru.mipt.spc.ApplicationKt") + mainClass.set("io.ktor.server.netty.EngineMain") val isDevelopment: Boolean = project.ext.has("development") applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment", "-Xmx200M") diff --git a/src/main/kotlin/html5up/forty/elements.kt b/src/main/kotlin/html5up/forty/elements.kt new file mode 100644 index 0000000..5d64965 --- /dev/null +++ b/src/main/kotlin/html5up/forty/elements.kt @@ -0,0 +1,792 @@ +package html5up.forty + +import kotlinx.html.* + +internal fun FlowContent.fortyElements() { + section { + id = "one" + div("inner") { + header("major") { + h1 { +"""Elements""" } + } + // Content + h2 { + id = "content" + +"""Sample Content""" + } + p { +"""Praesent ac adipiscing ullamcorper semper ut amet ac risus. Lorem sapien ut odio odio nunc. Ac adipiscing nibh porttitor erat risus justo adipiscing adipiscing amet placerat accumsan. Vis. Faucibus odio magna tempus adipiscing a non. In mi primis arcu ut non accumsan vivamus ac blandit adipiscing adipiscing arcu metus praesent turpis eu ac lacinia nunc ac commodo gravida adipiscing eget accumsan ac nunc adipiscing adipiscing.""" } + div("row") { + div("col-6 col-12-small") { + h3 { +"""Sem turpis amet semper""" } + p { +"""Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat commodo eu sed ante lacinia. Sapien a lorem in integer ornare praesent commodo adipiscing arcu in massa commodo lorem accumsan at odio massa ac ac. Semper adipiscing varius montes viverra nibh in adipiscing blandit tempus accumsan.""" } + } + div("col-6 col-12-small") { + h3 { +"""Magna odio tempus commodo""" } + p { +"""In arcu accumsan arcu adipiscing accumsan orci ac. Felis id enim aliquet. Accumsan ac integer lobortis commodo ornare aliquet accumsan erat tempus amet porttitor. Ante commodo blandit adipiscing integer semper orci eget. Faucibus commodo adipiscing mi eu nullam accumsan morbi arcu ornare odio mi adipiscing nascetur lacus ac interdum morbi accumsan vis mi accumsan ac praesent.""" } + } + // Break + div("col-4 col-12-medium") { + h3 { +"""Interdum sapien gravida""" } + p { +"""Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.""" } + } + div("col-4 col-12-medium") { + h3 { +"""Faucibus consequat lorem""" } + p { +"""Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.""" } + } + div("col-4 col-12-medium") { + h3 { +"""Accumsan montes viverra""" } + p { +"""Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.""" } + } + } + hr("major") { + } + // Elements + h2 { + id = "elements" + +"""Elements""" + } + div("row gtr-200") { + div("col-6 col-12-medium") { + // Text stuff + h3 { +"""Text""" } + p { + +"""This is Text""" + } + hr() + h2 { +"""Heading Level 2""" } + h3 { +"""Heading Level 3""" } + h4 { +"""Heading Level 4""" } + hr() + p { +"""Nunc lacinia ante nunc ac lobortis. Interdum adipiscing gravida odio porttitor sem non mi integer non faucibus ornare mi ut ante amet placerat aliquet. Volutpat eu sed ante lacinia sapien lorem accumsan varius montes viverra nibh in adipiscing blandit tempus accumsan.""" } + // Lists + h3 { +"""Lists""" } + div("row") { + div("col-6 col-12-small") { + h4 { +"""Unordered""" } + ul { + li { +"""Dolor etiam magna etiam.""" } + li { +"""Sagittis lorem eleifend.""" } + li { +"""Felis dolore viverra.""" } + } + h4 { +"""Alternate""" } + ul("alt") { + li { +"""Dolor etiam magna etiam.""" } + li { +"""Sagittis lorem eleifend.""" } + li { +"""Felis feugiat viverra.""" } + } + } + div("col-6 col-12-small") { + h4 { +"""Ordered""" } + ol { + li { +"""Dolor etiam magna etiam.""" } + li { +"""Etiam vel lorem sed viverra.""" } + li { +"""Felis dolore viverra.""" } + li { +"""Dolor etiam magna etiam.""" } + li { +"""Etiam vel lorem sed viverra.""" } + li { +"""Felis dolore viverra.""" } + } + h4 { +"""Icons""" } + ul("icons") { + li { + a(classes = "icon brands fa-twitter") { + href = "#" + span("label") { +"""Twitter""" } + } + } + li { + a(classes = "icon brands fa-facebook-f") { + href = "#" + span("label") { +"""Facebook""" } + } + } + li { + a(classes = "icon brands fa-instagram") { + href = "#" + span("label") { +"""Instagram""" } + } + } + li { + a(classes = "icon brands fa-github") { + href = "#" + span("label") { +"""Github""" } + } + } + li { + a(classes = "icon brands fa-dribbble") { + href = "#" + span("label") { +"""Dribbble""" } + } + } + li { + a(classes = "icon brands fa-tumblr") { + href = "#" + span("label") { +"""Tumblr""" } + } + } + } + ul("icons") { + li { + a(classes = "icon brands alt fa-twitter") { + href = "#" + span("label") { +"""Twitter""" } + } + } + li { + a(classes = "icon brands alt fa-facebook-f") { + href = "#" + span("label") { +"""Facebook""" } + } + } + li { + a(classes = "icon brands alt fa-instagram") { + href = "#" + span("label") { +"""Instagram""" } + } + } + } + } + } + h4 { +"""Definition""" } + dl { + dt { +"""Item1""" } + dd { + p { +"""Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent. Lorem ipsum dolor.""" } + } + dt { +"""Item2""" } + dd { + p { +"""Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent. Lorem ipsum dolor.""" } + } + dt { +"""Item3""" } + dd { + p { +"""Lorem ipsum dolor vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent. Lorem ipsum dolor.""" } + } + } + h4 { +"""Actions""" } + ul("actions") { + li { + a(classes = "button primary") { + href = "#" + +"""Default""" + } + } + li { + a(classes = "button") { + href = "#" + +"""Default""" + } + } + } + ul("actions small") { + li { + a(classes = "button primary small") { + href = "#" + +"""Small""" + } + } + li { + a(classes = "button small") { + href = "#" + +"""Small""" + } + } + } + div("row") { + div("col-6 col-12-small") { + ul("actions stacked") { + li { + a(classes = "button primary") { + href = "#" + +"""Default""" + } + } + li { + a(classes = "button") { + href = "#" + +"""Default""" + } + } + } + } + div("col-6 col-12-small") { + ul("actions stacked") { + li { + a(classes = "button primary small") { + href = "#" + +"""Small""" + } + } + li { + a(classes = "button small") { + href = "#" + +"""Small""" + } + } + } + } + div("col-6 col-12-small") { + ul("actions stacked") { + li { + a(classes = "button primary fit") { + href = "#" + +"""Default""" + } + } + li { + a(classes = "button fit") { + href = "#" + +"""Default""" + } + } + } + } + div("col-6 col-12-small") { + ul("actions stacked") { + li { + a(classes = "button primary small fit") { + href = "#" + +"""Small""" + } + } + li { + a(classes = "button small fit") { + href = "#" + +"""Small""" + } + } + } + } + } + h4 { +"""Pagination""" } + ul("pagination") { + li { + span("button small disabled") { +"""Prev""" } + } + li { + a(classes = "page active") { + href = "#" + +"""1""" + } + } + li { + a(classes = "page") { + href = "#" + +"""2""" + } + } + li { + a(classes = "page") { + href = "#" + +"""3""" + } + } + li { + span { +"""…""" } + } + li { + a(classes = "page") { + href = "#" + +"""8""" + } + } + li { + a(classes = "page") { + href = "#" + +"""9""" + } + } + li { + a(classes = "page") { + href = "#" + +"""10""" + } + } + li { + a(classes = "button small") { + href = "#" + +"""Next""" + } + } + } + // Blockquote + h3 { +"""Blockquote""" } + blockQuote { +"""Fringilla nisl. Donec accumsan interdum nisi, quis tincidunt felis sagittis eget tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan faucibus. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis.""" } + // Table + h3 { +"""Table""" } + h4 { +"""Default""" } + div("table-wrapper") { + table { + thead { + tr { + th { +"""Name""" } + th { +"""Description""" } + th { +"""Price""" } + } + } + tbody { + tr { + td { +"""Item1""" } + td { +"""Ante turpis integer aliquet porttitor.""" } + td { +"""29.99""" } + } + tr { + td { +"""Item2""" } + td { +"""Vis ac commodo adipiscing arcu aliquet.""" } + td { +"""19.99""" } + } + tr { + td { +"""Item3""" } + td { +"""Morbi faucibus arcu accumsan lorem.""" } + td { +"""29.99""" } + } + tr { + td { +"""Item4""" } + td { +"""Vitae integer tempus condimentum.""" } + td { +"""19.99""" } + } + tr { + td { +"""Item5""" } + td { +"""Ante turpis integer aliquet porttitor.""" } + td { +"""29.99""" } + } + } + tfoot { + tr { + td { + colSpan = "2" + } + td { +"""100.00""" } + } + } + } + } + h4 { +"""Alternate""" } + div("table-wrapper") { + table("alt") { + thead { + tr { + th { +"""Name""" } + th { +"""Description""" } + th { +"""Price""" } + } + } + tbody { + tr { + td { +"""Item1""" } + td { +"""Ante turpis integer aliquet porttitor.""" } + td { +"""29.99""" } + } + tr { + td { +"""Item2""" } + td { +"""Vis ac commodo adipiscing arcu aliquet.""" } + td { +"""19.99""" } + } + tr { + td { +"""Item3""" } + td { +"""Morbi faucibus arcu accumsan lorem.""" } + td { +"""29.99""" } + } + tr { + td { +"""Item4""" } + td { +"""Vitae integer tempus condimentum.""" } + td { +"""19.99""" } + } + tr { + td { +"""Item5""" } + td { +"""Ante turpis integer aliquet porttitor.""" } + td { +"""29.99""" } + } + } + tfoot { + tr { + td { + colSpan = "2" + } + td { +"""100.00""" } + } + } + } + } + } + div("col-6 col-12-medium") { + // Buttons + h3 { +"""Buttons""" } + ul("actions") { + li { + a(classes = "button primary") { + href = "#" + +"""Primary""" + } + } + li { + a(classes = "button") { + href = "#" + +"""Default""" + } + } + } + div("row") { + div("col-6 col-12-xsmall") { + ul("actions stacked") { + li { + a(classes = "button large") { + href = "#" + +"""Large""" + } + } + li { + a(classes = "button") { + href = "#" + +"""Default""" + } + } + li { + a(classes = "button small") { + href = "#" + +"""Small""" + } + } + } + } + div("col-6 col-12-xsmall") { + ul("actions stacked") { + li { + a(classes = "button primary large") { + href = "#" + +"""Large""" + } + } + li { + a(classes = "button primary") { + href = "#" + +"""Default""" + } + } + li { + a(classes = "button primary small") { + href = "#" + +"""Small""" + } + } + } + } + } + ul("actions fit") { + li { + a(classes = "button primary fit") { + href = "#" + +"""Fit""" + } + } + li { + a(classes = "button fit") { + href = "#" + +"""Fit""" + } + } + } + ul("actions fit small") { + li { + a(classes = "button primary fit small") { + href = "#" + +"""Fit + Small""" + } + } + li { + a(classes = "button fit small") { + href = "#" + +"""Fit + Small""" + } + } + } + ul("actions") { + li { + a(classes = "button primary icon solid fa-search") { + href = "#" + +"""Icon""" + } + } + li { + a(classes = "button icon solid fa-download") { + href = "#" + +"""Icon""" + } + } + } + ul("actions") { + li { + span("button primary disabled") { +"""Primary""" } + } + li { + span("button disabled") { +"""Default""" } + } + } + // Form + h3 { +"""Form""" } + form { + method = FormMethod.post + action = "#" + div("row gtr-uniform") { + div("col-6 col-12-xsmall") { + input { + type = InputType.text + name = "demo-name" + id = "demo-name" + value = "" + placeholder = "Name" + } + } + div("col-6 col-12-xsmall") { + input { + type = InputType.email + name = "demo-email" + id = "demo-email" + value = "" + placeholder = "Email" + } + } + // Break + div("col-12") { + select { + name = "demo-category" + id = "demo-category" + option { + value = "" + +"""- Category -""" + } + option { + value = "1" + +"""Manufacturing""" + } + option { + value = "1" + +"""Shipping""" + } + option { + value = "1" + +"""Administration""" + } + option { + value = "1" + +"""Human Resources""" + } + } + } + // Break + div("col-4 col-12-small") { + input { + type = InputType.radio + id = "demo-priority-low" + name = "demo-priority" + checked = true + } + label { + htmlFor = "demo-priority-low" + +"""Low""" + } + } + div("col-4 col-12-small") { + input { + type = InputType.radio + id = "demo-priority-normal" + name = "demo-priority" + } + label { + htmlFor = "demo-priority-normal" + +"""Normal""" + } + } + div("col-4 col-12-small") { + input { + type = InputType.radio + id = "demo-priority-high" + name = "demo-priority" + } + label { + htmlFor = "demo-priority-high" + +"""High""" + } + } + // Break + div("col-6 col-12-small") { + input { + type = InputType.checkBox + id = "demo-copy" + name = "demo-copy" + } + label { + htmlFor = "demo-copy" + +"""Email me a copy""" + } + } + div("col-6 col-12-small") { + input { + type = InputType.checkBox + id = "demo-human" + name = "demo-human" + checked = true + } + label { + htmlFor = "demo-human" + +"""I am a human""" + } + } + // Break + div("col-12") { + textArea { + name = "demo-message" + id = "demo-message" + placeholder = "Enter your message" + rows = "6" + } + } + // Break + div("col-12") { + ul("actions") { + li { + input(classes = "primary") { + type = InputType.submit + value = "Send Message" + } + } + li { + input { + type = InputType.reset + value = "Reset" + } + } + } + } + } + } + // Image + h3 { +"""Image""" } + h4 { +"""Fit""" } + span("image fit") { + img { + src = "images/pic03.jpg" + alt = "" + } + } + div("box alt") { + div("row gtr-50 gtr-uniform") { + div("col-4") { + span("image fit") { + img { + src = "images/pic08.jpg" + alt = "" + } + } + } + div("col-4") { + span("image fit") { + img { + src = "images/pic09.jpg" + alt = "" + } + } + } + div("col-4") { + span("image fit") { + img { + src = "images/pic10.jpg" + alt = "" + } + } + } + // Break + div("col-4") { + span("image fit") { + img { + src = "images/pic10.jpg" + alt = "" + } + } + } + div("col-4") { + span("image fit") { + img { + src = "images/pic08.jpg" + alt = "" + } + } + } + div("col-4") { + span("image fit") { + img { + src = "images/pic09.jpg" + alt = "" + } + } + } + // Break + div("col-4") { + span("image fit") { + img { + src = "images/pic09.jpg" + alt = "" + } + } + } + div("col-4") { + span("image fit") { + img { + src = "images/pic10.jpg" + alt = "" + } + } + } + div("col-4") { + span("image fit") { + img { + src = "images/pic08.jpg" + alt = "" + } + } + } + } + } + h4 { +"""Left & Right""" } + p { + span("image left") { + img { + src = "images/pic09.jpg" + alt = "" + } + } + +"""Lorem ipsum dolor sit accumsan interdum nisi, quis tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget tempus vestibulum ante ipsum primis in faucibus magna blandit adipiscing eu felis iaculis.""" + } + p { + span("image right") { + img { + src = "images/pic10.jpg" + alt = "" + } + } + +"""Lorem ipsum dolor sit accumsan interdum nisi, quis tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Vestibulum ante ipsum primis sagittis eget. tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget tempus vestibulum ante ipsum primis in faucibus magna blandit adipiscing eu felis iaculis.""" + } + // Box + h3 { +"""Box""" } + div("box") { + p { +"""Felis sagittis eget tempus primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus. Integer ac pellentesque praesent tincidunt felis sagittis eget. tempus euismod. Magna sed etiam ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan eu faucibus lorem ipsum.""" } + } + // Preformatted Code + h3 { +"""Preformatted""" } + pre { + code { + +""" + i = 0; + while (!deck.isInOrder()) { + print 'Iteration ' + i; + deck.shuffle(); + i++; + } + + print 'It took ' + i + ' iterations to sort the deck.'; + """.trimIndent() + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/spc/Application.kt b/src/main/kotlin/ru/mipt/spc/Application.kt index efc2e5b..4ce98b5 100644 --- a/src/main/kotlin/ru/mipt/spc/Application.kt +++ b/src/main/kotlin/ru/mipt/spc/Application.kt @@ -42,6 +42,7 @@ private fun Application.resolveData(uri: URI, targetPath: Path): Path { return targetPath } +@Suppress("unused") fun Application.spcModule() { val context = Context("spc-site") { plugin(SnarkPlugin) diff --git a/src/main/kotlin/ru/mipt/spc/home.kt b/src/main/kotlin/ru/mipt/spc/home.kt index d1aadd0..e25f60b 100644 --- a/src/main/kotlin/ru/mipt/spc/home.kt +++ b/src/main/kotlin/ru/mipt/spc/home.kt @@ -398,7 +398,7 @@ internal fun Application.spcHome(context: Context, rootPath: Path, prefix: Strin val snark = context.fetch(SnarkPlugin) - val homePageContext = snark.buildPageContext(prefix, rootPath.resolve("content")) + val homePageContext = snark.parse(prefix, rootPath.resolve("content")) routing { route(prefix) { diff --git a/src/main/kotlin/ru/mipt/spc/master.kt b/src/main/kotlin/ru/mipt/spc/master.kt index b667cbf..ec5f9e8 100644 --- a/src/main/kotlin/ru/mipt/spc/master.kt +++ b/src/main/kotlin/ru/mipt/spc/master.kt @@ -268,7 +268,7 @@ internal fun Application.spcMaster(context: Context, dataPath: Path, prefix: Str val snark = context.fetch(SnarkPlugin) - val magProgPageContext = snark.buildPageContext(prefix, dataPath.resolve("content")) + val magProgPageContext = snark.parse(prefix, dataPath.resolve("content")) routing { route(prefix) { diff --git a/src/main/kotlin/space/kscience/snark/HtmlData.kt b/src/main/kotlin/space/kscience/snark/HtmlData.kt index 0294887..a63278d 100644 --- a/src/main/kotlin/space/kscience/snark/HtmlData.kt +++ b/src/main/kotlin/space/kscience/snark/HtmlData.kt @@ -5,12 +5,11 @@ import kotlinx.html.FlowContent import kotlinx.html.TagConsumer import space.kscience.dataforge.data.Data import space.kscience.dataforge.data.await -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.string -enum class Language { - EN, - RU -} //TODO replace by VisionForge type typealias HtmlFragment = TagConsumer<*>.() -> Unit @@ -20,7 +19,7 @@ typealias HtmlData = Data fun HtmlData(meta: Meta, content: TagConsumer<*>.() -> Unit): HtmlData = Data(content, meta) val HtmlData.id: String get() = meta["id"]?.string ?: "block[${hashCode()}]" -val HtmlData.language: Language get() = meta["language"]?.enum() ?: Language.RU +val HtmlData.language: String? get() = meta["language"].string?.lowercase() val HtmlData.order: Int? get() = meta["order"]?.int diff --git a/src/main/kotlin/space/kscience/snark/PageContext.kt b/src/main/kotlin/space/kscience/snark/PageContext.kt index f0bfd1a..15c205e 100644 --- a/src/main/kotlin/space/kscience/snark/PageContext.kt +++ b/src/main/kotlin/space/kscience/snark/PageContext.kt @@ -15,24 +15,30 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import java.nio.file.Path -data class PageContext(val path: String, val pageMeta: Meta, val data: DataSet<*>) +data class PageContext(val path: String, val pageMeta: Meta, val data: DataSet<*>) { + val language: String? by pageMeta.string() +} /** * Resolve a resource full path by its name */ -fun PageContext.resolveRef(name: String): String = "$path/$name" +fun PageContext.resolveRef(name: String): String = "${path.removeSuffix("/")}/$name" /** * Resolve a Html builder by its full name */ -fun PageContext.resolveHtml(name: Name): HtmlData? = data.getByType(name) +fun PageContext.resolveHtml(name: Name): HtmlData? = data.getByType(name)?.takeIf { + it.published //TODO add language confirmation +} /** * Find all Html blocks using given name/meta filter */ fun PageContext.resolveAllHtml(predicate: (name: Name, meta: Meta) -> Boolean): Map = data.filterByType { name, meta -> - predicate(name, meta) && meta["published"].string != "false" + predicate(name, meta) + && meta["published"].string != "false" + //TODO add language confirmation }.asSequence().associate { it.name to it.data } val PageContext.homeRef get() = resolveRef("").removeSuffix("/") @@ -44,14 +50,14 @@ fun PageContext.findByType(contentType: String, baseName: Name = Name.EMPTY) = r internal val Data<*>.published: Boolean get() = meta["published"].string != "false" -fun SnarkPlugin.buildPageContext(rootUrl: String, data: DataSet<*>): PageContext = PageContext(rootUrl, data.meta, data) +fun PageContext(rootUrl: String, data: DataSet<*>): PageContext = PageContext(rootUrl, data.meta, data) -fun SnarkPlugin.buildPageContext(rootUrl: String, path: Path): PageContext { +fun SnarkPlugin.parse(rootUrl: String, path: Path): PageContext { val directoryDataTree = DirectoryDataTree(io, path) val parsedData: DataSet = parseAction(directoryDataTree) - return buildPageContext(rootUrl, parsedData) + return PageContext(rootUrl, parsedData) } context(PageContext) inline fun withRequest(request: ApplicationRequest, block: context(PageContext) () -> Unit) { diff --git a/src/main/kotlin/space/kscience/snark/site.kt b/src/main/kotlin/space/kscience/snark/site.kt index 7b4eb31..eab9280 100644 --- a/src/main/kotlin/space/kscience/snark/site.kt +++ b/src/main/kotlin/space/kscience/snark/site.kt @@ -8,12 +8,12 @@ import space.kscience.dataforge.data.DataSetBuilder import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.copy import space.kscience.dataforge.names.Name -import space.kscience.snark.* +import space.kscience.snark.HtmlData +import space.kscience.snark.HtmlFragment +import space.kscience.snark.PageContext import kotlin.reflect.typeOf -class SiteBuilderAction( - val snark: SnarkPlugin, -) : AbstractAction(typeOf()) { +class SiteBuilderAction : AbstractAction(typeOf()) { private val pageBuilders = HashMap) -> HtmlData>() @@ -21,7 +21,7 @@ class SiteBuilderAction( val prefix = name.tokens.joinToString(separator = "/", prefix = "/") pageBuilders[name] = { dataset -> val fragment: HtmlFragment = { - builder.invoke(snark.buildPageContext(prefix, dataset), this) + builder.invoke(PageContext(prefix, dataset), this) } Data(fragment, meta.copy { "name" put name.toString()