
com.wbillingsley.veautiful.templates.DeckBuilder.scala Maven / Gradle / Ivy
package com.wbillingsley.veautiful.templates
import com.wbillingsley.veautiful.html.{<, Attacher, Markup, VHtmlContent, VHtmlElement, VHtmlBlueprint, ^}
import org.scalajs.dom
import scala.collection.mutable
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
sealed trait Slide
@JSExportTopLevel("DeckBuilder")
def makeDeckBuilder(parser:(String) => String) = (w:Int, h:Int) => DeckBuilder(w, h)(using Markup { parser })
class DeckBuilder(width:Int = 1920, height:Int = 1080, slides:List[Seq[() => VHtmlContent]] = Nil)(using markup:Markup) {
def stripIndent(s:String):String = {
val lines = s.split('\n')
val indents = for { l <- lines if !l.trim().isEmpty } yield l.indexWhere(!_.isWhitespace)
val minIndent = indents.min
val stripped = (for {
l <- lines
} yield l.drop(minIndent)).mkString("\n")
stripped
}
@JSExport
def markdownSlide(m:String):DeckBuilder = new DeckBuilder(width, height, Seq(() => markup.Fixed(stripIndent(m))) :: slides)
def veautifulSlide(vnode:VHtmlContent):DeckBuilder = new DeckBuilder(width, height, Seq(() => vnode) :: slides)
@JSExport
def markdownSlides(m:String):DeckBuilder = {
val pattern = """(?:^|[\n\r\u0085\u2028\u2029])(---)(?=[\n\r\u0085\u2028\u2029]|$)""".r
val lines = pattern.split(stripIndent(m))
new DeckBuilder(width, height, lines.toSeq.map(l => () => markup.Fixed(l)) :: slides)
}
@JSExport
def withClass(c:String):DeckBuilder = slides match {
case Nil => this
case h :: t => new DeckBuilder(width, height, (for { s <- h } yield () => <.div(^.cls := c, s())) :: t)
}
def renderSlides:VSlides = {
VSlides(width, height, for slide <- slides.reverse.flatten yield slide.apply() match {
case e:VHtmlElement @unchecked => e
case b:VHtmlBlueprint @unchecked => b.build()
})
}
def renderNode(using player:VSlidesPlayer = { (slides, index) => DefaultVSlidesPlayer(slides)(index=index)}) = player.apply(renderSlides, 0)
@JSExport
def render(selector:String) = {
val slides = renderNode(using { (slides, index) => DefaultVSlidesPlayer(slides)(index=index)})
DeckBuilder.publishedDecks(selector) = slides
val a = Attacher.newRoot(dom.document.querySelector(selector))
a.render(slides)
}
}
@JSExportTopLevel("DeckBuilderCompanion")
object DeckBuilder {
val publishedDecks:mutable.Map[String, VHtmlElement] = mutable.Map.empty
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy