Add image rendering

This commit is contained in:
Alexander Nozik 2024-05-01 13:26:19 +03:00
parent 7a2b5c1768
commit 21a85b4501
9 changed files with 60 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -1,6 +1,5 @@
---
type: markdown
order: 2
contentType: markdown
---
## Chapter ${section(1)}

View File

@ -4,11 +4,19 @@ authors:
- name: Alexander Nozik
affiliation: MIPT
fragments:
- name: chapter1
type: data
- name: chapter2
type: data
- name: chapter3
type: data
- type: image
ref: SPC-logo.png
meta:
caption: SPC logo
- type: data
name: chapter1
- type: data
name: chapter2
- type: image
ref: SPC-logo.png
meta:
caption: Another SPC logo
- type: data
name: chapter3
documentMeta:
metaValue: Hello world!

View File

@ -35,7 +35,6 @@ fun Application.renderAllDocuments() = snarkApplication {
fun main() {
embeddedServer(CIO) {
renderAllDocuments()
}.start(true)

View File

@ -6,6 +6,7 @@ import io.ktor.http.ContentType
import kotlinx.coroutines.CoroutineScope
import kotlinx.io.readByteArray
import space.kscience.dataforge.actions.Action
import space.kscience.dataforge.actions.mapping
import space.kscience.dataforge.actions.transform
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory
@ -107,6 +108,10 @@ public class SnarkHtml : WorkspacePlugin() {
public val parseAction: Action<Binary, Any> = ParseAction(this)
public val layoutAction: Action<Any, Any> = Action.mapping {
}
private val allDataNotNull: DataSelector<Any>
get() = DataSelector { workspace, _ -> workspace.data.filterByType() }

View File

@ -7,14 +7,12 @@ import space.kscience.dataforge.context.info
import space.kscience.dataforge.context.logger
import space.kscience.dataforge.context.request
import space.kscience.dataforge.data.*
import space.kscience.dataforge.io.Binary
import space.kscience.dataforge.meta.Laminate
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.cutLast
import space.kscience.dataforge.names.endsWith
import space.kscience.dataforge.names.parseAsName
import space.kscience.dataforge.names.*
import space.kscience.snark.SnarkBuilder
import space.kscience.snark.SnarkContext
import space.kscience.snark.html.*
@ -26,7 +24,7 @@ import kotlin.reflect.typeOf
@SnarkBuilder
public interface DocumentBuilder : SnarkContext {
public val documentName: Name
public val route: Name
public val documentMeta: Meta
@ -51,7 +49,7 @@ private class PageBasedDocumentBuilder(
val page: PageContextWithData,
private val dataRootName: Name,
) : DocumentBuilder {
override val documentName: Name get() = page.pageRoute
override val route: Name get() = page.pageRoute
override val documentMeta: Meta get() = page.pageMeta
override val data: DataTree<*> = page.data.branch(dataRootName) ?: DataTree.EMPTY
@ -63,11 +61,10 @@ private class PageBasedDocumentBuilder(
override suspend fun fragment(fragment: DocumentFragment, overrideMeta: Meta?) {
when (fragment) {
is ImageDocumentFragment -> fragment {
figure("snark-figure") {
img(classes = "snark-image") {
src = fragment.path
src = resolveRef(this@PageBasedDocumentBuilder.route.toWebPath() + "/" + fragment.ref)
alt = fragment.meta["alt"].string ?: ""
}
fragment.meta["caption"].string?.let { caption ->
@ -115,53 +112,41 @@ private class PageBasedDocumentBuilder(
}
public fun SiteContextWithData.document(
documentName: Name,
documentMeta: Meta = Meta.EMPTY,
headers: MetaDataContent.() -> Unit = {},
block: suspend DocumentBuilder.() -> Unit,
): Unit = page(documentName, documentMeta) {
val documentBuilder = runBlocking { PageBasedDocumentBuilder(page, documentName).apply { block() } }
head {
title(documentMeta["title"].string ?: "Snark document")
headers()
}
body {
postprocess(FtlDocumentProcessor(this@document.context, documentBuilder)) {
documentBuilder.fragments.forEach {
fragment(it)
}
}
}
}
public fun SiteContextWithData.document(
route: Name,
dataName: Name,
descriptor: DocumentDescriptor,
descriptor: DocumentDescriptor = DocumentDescriptor.empty(),
route: Name = dataName,
headers: MetaDataContent.() -> Unit = {},
): Unit = page(route, descriptor.documentMeta ?: Meta.EMPTY) {
val documentBuilder = runBlocking {
PageBasedDocumentBuilder(page, dataName).apply {
descriptor.fragments.forEach {
fragment(it)
documentBlock: DocumentBuilder.() -> Unit = {},
): Unit {
siteData.branch(dataName)?.filterByType<Binary>()?.forEach {
static(route + it.name.last(), it.data)
}
page(route, descriptor.documentMeta ?: Meta.EMPTY) {
//TODO think about avoiding blocking
val documentBuilder = runBlocking {
PageBasedDocumentBuilder(page, dataName).apply {
descriptor.fragments.forEach {
fragment(it)
}
documentBlock()
}
}
}
head {
title(descriptor.title ?: "Snark document")
headers()
}
body {
h1("title") { +(descriptor.title ?: dataName.toString()) }
descriptor.authors.forEach {
div("author") {
div("author-name") { +it.name }
it.affiliation?.let { affiliation -> div("author-affiliation") { +affiliation } }
}
head {
title(descriptor.title ?: "Snark document")
headers()
}
postprocess(FtlDocumentProcessor(this@document.context, documentBuilder)) {
documentBuilder.fragments.forEach {
fragment(it)
body {
h1("title") { +(descriptor.title ?: dataName.toString()) }
descriptor.authors.forEach {
div("author") {
div("author-name") { +it.name }
it.affiliation?.let { affiliation -> div("author-affiliation") { +affiliation } }
}
}
postprocess(FtlDocumentProcessor(this@document.context, documentBuilder)) {
documentBuilder.fragments.forEach {
fragment(it)
}
}
}
}
@ -178,9 +163,9 @@ public fun SiteContextWithData.allDocuments(
val route = descriptor.route?.parseAsName(false) ?: directory
context.logger.info { "Loading document $route" }
document(
route = route,
dataName = directory,
descriptor = descriptor,
route = route,
headers = headers
)
}

View File

@ -20,7 +20,7 @@ public class MarkupDocumentFragment(
@Serializable
@SerialName("image")
public class ImageDocumentFragment(
public val path: String,
public val ref: String,
override val meta: Meta = Meta.EMPTY,
) : DocumentFragment

View File

@ -59,7 +59,7 @@ public class FtlDocumentProcessor(
}
private val data = mapOf(
"documentName" to document.documentName.toStringUnescaped(),
"documentName" to document.route.toStringUnescaped(),
"label" to TemplateMethodModelEx { args: List<Any?> ->
val counter = args.getOrNull(0)?.toString() ?: "@default"

View File

@ -42,7 +42,7 @@ public class RegexDocumentProcessor(public val document: DocumentBuilder) : Text
when (match.groups["function"]?.value) {
"documentName" -> {
document.documentName.toStringUnescaped()
document.route.toStringUnescaped()
}
"label" -> {
@ -77,7 +77,7 @@ public class RegexDocumentProcessor(public val document: DocumentBuilder) : Text
}.replace(attributeRegex) { match ->
val uri = URI(match.groups["uri"]!!.value)
val snarkUrl = when (uri.authority) {
"documentName" -> document.documentName.toStringUnescaped()
"documentName" -> document.route.toStringUnescaped()
// "ref" -> page.resolveRef(uri.path)
"meta" -> document.documentMeta[uri.path.parseAsName()].string ?: "@null"
else -> match.value