summaryrefslogblamecommitdiff
path: root/docs/pages.sc
blob: bd8a754772897daa3ced4e7105954d6581509f72 (plain) (tree)







































































                                                                                                        
                                                           





















































































































                                                                                                         
 
import $ivy.`com.lihaoyi::scalatags:0.6.5`
import scalatags.Text.all._, scalatags.Text.tags2
import java.time.LocalDate
import $file.pageStyles, pageStyles._

case class PostInfo(name: String,
                    headers: Seq[(String, Int)],
                    rawHtmlContent: String)


def sanitize(s: String): String = {
  s.split(" |-", -1).map(_.filter(_.isLetterOrDigit)).mkString("-").toLowerCase
}
def pageChrome(titleText: Option[String],
               homePage: Boolean,
               contents: Frag,
               contentHeaders: Seq[(String, Int)],
               pageHeaders: Seq[String]): String = {
  val pageTitle = titleText.getOrElse("Mill")
  val sheets = Seq(
    "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css",
    "https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css",
    "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/github-gist.min.css"
  )


  html(
    head(
      meta(charset := "utf-8"),
      for(sheet <- sheets)
        yield link(href := sheet, rel := "stylesheet", `type` := "text/css" ),
      tags2.title(pageTitle),
      tags2.style(s"@media (min-width: 60em) {${WideStyles.styleSheetText}}"),
      tags2.style(s"@media (max-width: 60em) {${NarrowStyles.styleSheetText}}"),
      tags2.style(Styles.styleSheetText),
      script(src:="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"),
      script(src:="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/languages/scala.min.js"),
      script(raw("hljs.initHighlightingOnLoad();")),
      // This makes media queries work on iphone (???)
      // http://stackoverflow.com/questions/13002731/responsive-design-media-query-not-working-on-iphone
      meta(name:="viewport", content:="initial-scale = 1.0,maximum-scale = 1.0")
    ),
    body(margin := 0, backgroundColor := "#f8f8f8")(
      navBar(homePage, contentHeaders, pageHeaders),
      div(
        WideStyles.content,
        NarrowStyles.content,
        maxWidth := 900,
        titleText.map(h1(_)),
        contents
      ),
      if (contentHeaders.nonEmpty) frag()
      else div(
        WideStyles.footer,
        Styles.footerStyle,
        "Last published ", currentTimeText
      )

    )
  ).render
}

def navBar(homePage: Boolean, contentHeaders: Seq[(String, Int)], pageHeaders: Seq[String]) = {
  def navList(navLabel: String, frags: Frag, narrowHide: Boolean) = {
    div(
      WideStyles.tableOfContents,
      if(narrowHide) NarrowStyles.disappear else frag(),
      color := "#f8f8f8"
    )(
      div(paddingLeft := 40, NarrowStyles.disappear)(
        b(navLabel)
      ),
      div(overflowY.auto, flexShrink := 1, minHeight := 0)(
        ul(
          overflow.hidden,
          textAlign.start,
          marginTop := 10,
          whiteSpace.nowrap,
          textOverflow.ellipsis,
          marginRight := 10
        )(
          frags
        )
      )
    )
  }
  val pageList = navList(
    "Pages",
    for((header, i) <- pageHeaders.zipWithIndex) yield li(
      WideStyles.marginLeftZero,
      NarrowStyles.floatLeft
    )(
      a(
        color := "#f8f8f8",
        WideStyles.tableOfContentsItem,
        href := {
          (homePage, i == 0) match {
            case (true, true) => s"index.html"
            case (true, false) => s"page/${sanitize(header)}.html"
            case (false, true) => s"../index.html"
            case (false, false) => s"${sanitize(header)}.html"
          }
        }
      )(
        header
      )
    ),
    narrowHide = false
  )

  val headerBox = div(
    NarrowStyles.headerContent,
    h1(
      textAlign.center,
      a(
        img(
          src := {homePage match{
            case false => s"../logo-white.svg"
            case true => "logo-white.svg"
          }},
          height := 30,
          marginTop := -5
        ),
        color := "#f8f8f8",
        " Mill",
        href := (if (homePage) "" else ".."),
        Styles.subtleLink,
        NarrowStyles.flexFont,
        fontWeight.bold
      ),
      padding := "30px 30px",
      margin := 0
    ),
    div(
      Styles.headerLinkBox,
      pageList
    )
  )


  val tableOfContents = navList(
    "Table of Contents",
    for {
      (header, indent) <- contentHeaders
      offset <- indent match{
        case 2 => Some(0)
        case 3 => Some(20)
        case _ => None
      }
    } yield li(marginLeft := offset)(
      a(
        color := "#f8f8f8",
        WideStyles.tableOfContentsItem,
        href := s"#${sanitize(header)}"
      )(
        header
      )
    ),
    narrowHide = true
  )

  div(
    WideStyles.header,
    NarrowStyles.header,
    Styles.headerStyle,
    headerBox,
    hr(NarrowStyles.disappear, backgroundColor := "#f8f8f8", width := "80%"),
    tableOfContents
  )
}


val currentTimeText = LocalDate.now.toString


def renderAdjacentLink(next: Boolean, name: String, url: String) = {
  a(href := url)(
    if(next) frag(name, " ", i(cls:="fa fa-arrow-right" , aria.hidden:=true))
    else frag(i(cls:="fa fa-arrow-left" , aria.hidden:=true), " ", name)
  )
}
def postContent(homePage: Boolean, post: PostInfo, adjacentLinks: Frag, posts: Seq[String]) = pageChrome(
  Some(post.name),
  homePage,
  Seq[Frag](
    div(adjacentLinks, marginBottom := 10),
    raw(post.rawHtmlContent),
    adjacentLinks
  ),
  post.headers,
  pageHeaders = posts
)