package dotty.tools package dottydoc package staticsite import model.references._ import liqp.tags.Tag import liqp.TemplateContext import liqp.nodes.LNode import java.util.{ Map => JMap } object tags { sealed trait ParamConverter { def params: Map[String, AnyRef] val baseurl: String = params.get("site").flatMap { case map: JMap[String, String] @unchecked => Some(map.get("baseurl")) case _ => None } .getOrElse { /*dottydoc.*/println(s"missing `baseurl` in: $params") "" } } /** Renders a `MaterializableLink` into a HTML anchor tag. If the link is * `NoLink` it will just return a string with the link's title. */ final case class RenderLink(params: Map[String, AnyRef]) extends Tag("renderLink") with ParamConverter { override def render(ctx: TemplateContext, nodes: LNode*): AnyRef = nodes(0).render(ctx) match { case map: JMap[String, AnyRef] @unchecked => val link = map.get("scala") if (link.isInstanceOf[MaterializableLink] && (link ne null)) renderLink(baseurl, link.asInstanceOf[MaterializableLink]) else if (link eq null) null // Option[Reference] was None else { /*dottydoc.*/println(s"illegal argument: $link, to `renderLink` function") null } case _ => null } } private[this] def renderLink(baseurl: String, link: MaterializableLink): String = link match { case MaterializedLink(title, target) => s"""$title""" case _ => link.title } final case class RenderReference(params: Map[String, AnyRef]) extends Tag("renderRef") with ParamConverter { private def renderReference(ref: Reference): String = ref match { case TypeReference(_, tpeLink, paramLinks) => { if (paramLinks.nonEmpty) { s"""|${renderLink(baseurl, tpeLink)} |[ |${ paramLinks.map(renderReference).mkString(""", """) } |]""".stripMargin } else renderLink(baseurl, tpeLink) } case AndOrTypeReference(left, sep, right) => s"""${renderReference(left)} $sep ${renderReference(right)}""" case FunctionReference(args, returnValue) => { val params = if (args.isEmpty) "() => " else if (args.tail.isEmpty) renderReference(args.head) + """ => """ else args.map(renderReference).mkString("(", ", ", ") => ") params + renderReference(returnValue) } case TupleReference(args) => s"""|( |${ args.map(renderReference).mkString(", ") } |)""".stripMargin case BoundsReference(low, high) => s"""${ renderReference(low) } <: ${ renderReference(high) }""" case NamedReference(title, _, _, _) => /*dottydoc.*/println(s"received illegal named reference in rendering: $ref") title case ConstantReference(title) => title } override def render(ctx: TemplateContext, nodes: LNode*): AnyRef = nodes(0).render(ctx) match { case map: JMap[String, AnyRef] @unchecked => val ref = map.get("scala") if (ref.isInstanceOf[Reference] && (ref ne null)) renderReference(ref.asInstanceOf[Reference]) else if (ref eq null) null // Option[Reference] was None else { /*dottydoc.*/println(s"illegal argument: $ref, to `renderRef` function") null } case _ => null } } case class ResourceInclude(params: Map[String, AnyRef], includes: Map[String, String]) extends Tag("include") { import scala.collection.JavaConverters._ val DefaultExtension = ".html" override def render(ctx: TemplateContext, nodes: LNode*): AnyRef = { val origInclude = asString(nodes(0).render(ctx)) val incResource = origInclude match { case fileWithExt if fileWithExt.indexOf('.') > 0 => fileWithExt case file => file + DefaultExtension } includes .get(incResource) .map { template => if (nodes.length > 1) ctx.put(origInclude, nodes(1).render(ctx)) LiquidTemplate(template).render(Map.empty ++ ctx.getVariables.asScala, includes) } .getOrElse { /*dottydoc.*/println(s"couldn't find include file '$origInclude'") "" } } } /** Can be used to render the `sidebar.yml` entries, represented here as * `Title`. * * ```html * {% renderTitle title, parent %} * ``` * * The rendering currently works on depths up to 2. This means that each * title can have a subsection with its own titles. */ case class RenderTitle(params: Map[String, AnyRef]) extends Tag("renderTitle") with ParamConverter { private def renderTitle(t: Title, parent: String): String = { if (!t.url.isDefined && t.subsection.nonEmpty) { val onclickFunction = s"""(function(){var child=document.getElementById("${t.title}");child.classList.toggle("show");child.classList.toggle("hide");})();""" s"""|${t.title} |""".stripMargin } else if (t.url.isDefined) { val url = t.url.get s"""${t.title}""" } else /*if (t.subsection.nonEmpty)*/ { /*dottydoc.*/println(s"url was defined for subsection with title: ${t.title}, remove url to get toggleable entries") t.title } } override def render(ctx: TemplateContext, nodes: LNode*): AnyRef = (nodes(0).render(ctx), nodes(1).render(ctx)) match { case (t: Title, parent: String) => renderTitle(t, parent) case _ => null } } }