/* NSC -- new Scala compiler * Copyright 2007-2011 LAMP/EPFL * @author David Bernard, Manohar Jonnalagedda */ package scala.tools.nsc package doc package html import model._ import comment._ import xml.{XML, NodeSeq} import xml.dtd.{DocType, PublicID} import scala.collection._ import scala.reflect.NameTransformer import java.nio.channels.Channels import java.io.{FileOutputStream, File} /** An html page that is part of a Scaladoc site. * @author David Bernard * @author Gilles Dubochet */ abstract class HtmlPage { thisPage => /** The path of this page, relative to the API site. `path.tail` is a list of folder names leading to this page (from * closest package to one-above-root package), `path.head` is the file name of this page. Note that `path` has a * length of at least one. */ def path: List[String] /** The title of this page. */ protected def title: String /** Additional header elements (links, scripts, meta tags, etc.) required for this page. */ protected def headers: NodeSeq /** The body of this page. */ protected def body: NodeSeq /** Writes this page as a file. The file's location is relative to the generator's site root, and the encoding is * also defined by the generator. * @param generator The generator that is writing this page. */ def writeFor(site: HtmlFactory): Unit = { val doctype = DocType("html", PublicID("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"), Nil) val html =
{ inlineToHtml(in) }
case Code(data) =>{ xml.Text(data) }case UnorderedList(items) =>
{ xml.Text(text) }
case Text(text) => xml.Text(text)
case Summary(in) => inlineToHtml(in)
case HtmlTag(tag) => xml.Unparsed(tag)
}
def typeToHtml(tpe: model.TypeEntity, hasLinks: Boolean): NodeSeq = {
val string = tpe.name
def toLinksOut(inPos: Int, starts: List[Int]): NodeSeq = {
if (starts.isEmpty && (inPos == string.length))
NodeSeq.Empty
else if (starts.isEmpty)
xml.Text(string.slice(inPos, string.length))
else if (inPos == starts.head)
toLinksIn(inPos, starts)
else {
xml.Text(string.slice(inPos, starts.head)) ++ toLinksIn(starts.head, starts)
}
}
def toLinksIn(inPos: Int, starts: List[Int]): NodeSeq = {
val (tpl, width) = tpe.refEntity(inPos)
(tpl match {
case dtpl:DocTemplateEntity if hasLinks =>
{
string.slice(inPos, inPos + width)
}
case tpl =>
{ string.slice(inPos, inPos + width) }
}) ++ toLinksOut(inPos + width, starts.tail)
}
if (hasLinks)
toLinksOut(0, tpe.refEntity.keySet.toList)
else
xml.Text(string)
}
def typesToHtml(tpess: List[model.TypeEntity], hasLinks: Boolean, sep: NodeSeq): NodeSeq = tpess match {
case Nil => NodeSeq.Empty
case tpe :: Nil => typeToHtml(tpe, hasLinks)
case tpe :: tpes => typeToHtml(tpe, hasLinks) ++ sep ++ typesToHtml(tpes, hasLinks, sep)
}
/** Returns the HTML code that represents the template in `tpl` as a hyperlinked name. */
def templateToHtml(tpl: TemplateEntity) = tpl match {
case dTpl: DocTemplateEntity =>
{ dTpl.name }
case ndTpl: NoDocTemplate =>
xml.Text(ndTpl.name)
}
/** Returns the HTML code that represents the templates in `tpls` as a list of hyperlinked names. */
def templatesToHtml(tplss: List[TemplateEntity], sep: NodeSeq): NodeSeq = tplss match {
case Nil => NodeSeq.Empty
case tpl :: Nil => templateToHtml(tpl)
case tpl :: tpls => templateToHtml(tpl) ++ sep ++ templatesToHtml(tpls, sep)
}
def docEntityKindToString(ety: DocTemplateEntity) =
if (ety.isTrait) "trait"
else if (ety.isCaseClass) "case class"
else if (ety.isClass) "class"
else if (ety.isObject) "object"
else if (ety.isPackage) "package"
else "class" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
/** Returns the _big image name corresponding to the DocTemplate Entity (upper left icon) */
def docEntityKindToBigImage(ety: DocTemplateEntity) =
if (ety.isTrait) "trait_big.png"
else if (ety.isClass) "class_big.png"
else if (ety.isObject) "object_big.png"
else if (ety.isPackage) "package_big.png"
else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
}