All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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