Add image rendering
This commit is contained in:
parent
7a2b5c1768
commit
21a85b4501
BIN
examples/document/data/loremIpsum/SPC-logo.png
Normal file
BIN
examples/document/data/loremIpsum/SPC-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
@ -1,6 +1,5 @@
|
||||
---
|
||||
type: markdown
|
||||
order: 2
|
||||
contentType: markdown
|
||||
---
|
||||
|
||||
## Chapter ${section(1)}
|
||||
|
@ -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!
|
@ -35,7 +35,6 @@ fun Application.renderAllDocuments() = snarkApplication {
|
||||
|
||||
|
||||
fun main() {
|
||||
|
||||
embeddedServer(CIO) {
|
||||
renderAllDocuments()
|
||||
}.start(true)
|
||||
|
@ -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() }
|
||||
|
||||
|
@ -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,36 +112,23 @@ 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) {
|
||||
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 {
|
||||
@ -166,6 +150,7 @@ public fun SiteContextWithData.document(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun SiteContextWithData.allDocuments(
|
||||
headers: MetaDataContent.() -> Unit = {},
|
||||
@ -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
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user